先是前几天看了稚晖君在CLion中开发STM32,于是学习了一下告别了Keil。这里概述一下使用CLion开发标准库的过程。留下一些记录,也希望可以为其他想尝试在CLion上进行库函数开发的朋友参考参考。在一些步骤中我也是按他人的教程做的,我会直接给出教程地址。本文解决了如下几个问题
在CLion中搭建STM32标准库开发环境。
解决printf无法使用的问题
解决math.h无法使用的问题并引入CMSIS-DSP库
稚晖君的原文是《配置CLion用于STM32开发【优雅の嵌入式开发】》(原文链接https://zhuanlan.zhihu.com/p/145801160),文中稚晖君使用的库是HAL库,和我们要使用的标准库还有些差异,之后参考了up主陈伟国AE的《Clion实现Stm32标准库开发》,按照文中步骤做完后基本的功能都可以实现了。补充说明一点,创建工程时,在一些版本的STM32CubeMX的Toolchain/IDE中可能找不到SW4STM32,直接选择STM32CubeIDE即可。
在usart.c中自定义如下函数即可。
int _isatty(int fd) {
if (fd >= STDIN_FILE_NO && fd <= STDERR_FILE_NO)
return 1;
return 0;
}
int _write(int fd, char *ptr, int len) {
if (fd == STDOUT_FILE_NO || fd == STDERR_FILE_NO) {
uint32_t i;
for (i = 0; i < len; i++) {
USART_SendData(USART1, ptr[i]);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return len;
}
return -1;
}
int _close(int fd) {
if (fd >= STDIN_FILE_NO && fd <= STDERR_FILE_NO)
return 0;
return -1;
}
int _lseek(int fd, int ptr, int dir) {
(void) fd;
(void) ptr;
(void) dir;
return -1;
}
int _read(int fd, char *ptr, int len) {
if (fd == STDIN_FILE_NO) {
while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET) {
}
*ptr = USART_ReceiveData(USART1);
return 1;
}
return -1;
} 1. math.h
要使用math.h需要在CMakeLists中的add_executable命令前加入LINK_LIBRARIES(m)即可。
2. CMSIS-DSP(arm_math.h)
当然在嵌入式环境下直接使用math.h会慢一些,所以我们也可以使用CMSIS的DSP库(下文简称DSP库)。
2.1 获取DSP库
(1) 首先获取DSP库的方式可以是从Keil的文件夹或是STM32CubeMX的文件夹中复制,但是不推荐这么做,这么做的话获得的DSP库版本不统一,可能会增加后续查阅说明文档的难度(当然也可以看他们文件夹中有Documentation文件夹,其中有对应版本的离线说明文档)。我是选择了去官网下载了目前的最新版1.14.2,链接如下:
https://github.com/ARM-software/CMSIS-DSP/releases
下载zip格式的包,解压之后如图4-1

(2)获取CMSIS-Core文件夹,这个一般STM32CubeMX在一开始生成的时候就会生成一个,删了也可以去文件夹C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_F1_V1.8.4\Drivers\CMSIS\Core\Include
中找到,包含内容如图4-2。

图4-2 CMSIS-Core
2.2 将DSP库文件移动到工程目录中
在工程目录中新建CMSIS文件夹,在CMSIS文件夹下再新建两个文件夹,在CMSIS中按照图4-3结构新建文件夹。

图4-3 新建的文件夹结构,分别是Core和DSP,Core中包含一个Inc文件夹,DSP中包含三个文件夹分别是Inc,PrivateInclude和Src。
新建完成后,将DSP库移动过来。
(1)PrivateInclude文件夹内的内容直接复制到这边的PrivateInclude文件夹即可,如图4-4。

图4-4 DSP\PrivateInclude
(2)将CMSIS-DSP-1.14.2\Include中所有内容复制到DSP\Inc中,如图4-5。

图4-5 DSP\Inc
(3)将CMSIS-DSP-1.14.2\Source中的所有文件夹复制到DSP\Src中,如图4-6。

图4-6 DSP\Src
(4)将CMSIS-Core中的文件移动到Core\Inc中,如图4-7。

图4-7 移动后的CMSIS-Core
2.3配置CMakeLists
将CMSIS/Core/Inc,CMSIS/DSP/Inc,CMSIS/DSP/PrivateInclude添加到引用路径中,即把上述三项添加到include_directories命令中即可,代码如下。
include_directories(
CMSIS/Core/Inc
CMSIS/DSP/Inc
CMSIS/DSP/PrivateInclude
STM32F10x_FWLib/Inc
Core/Inc
SYSTEM/Inc
HARDWARE/Inc
USER/Inc
) 同样将源文件添加到项目中,需要注意只能添加与每个库文件夹同名的那个.c文件,因为那个文件中include了他所在文件夹的其他文件,如果我们这里直接将所有文件夹添加到项目中会导致multiple definition的问题。当然CMSIS-DSP按照不同功能的库进行了区分,分为多个文件夹,也可以直添加需要的库,这里以只添加DistanceFunction库为例,如果想要全部添加的话去掉注释即可。
file(
GLOB_RECURSE SOURCES
#"CMSIS/DSP/Src/BasicMathFunctions/BasicMathFunctions.c"
#"CMSIS/DSP/Src/CommonTables/CommonTables.c"
#"CMSIS/DSP/Src/ComplexMathFunctions/ComplexMathFunctions.c"
#"CMSIS/DSP/Src/ControllerFunctions/ControllerFunctions.c"
#"CMSIS/DSP/Src/FastMathFunctions/FastMathFunctions.c"
#"CMSIS/DSP/Src/FilteringFunctions/FilteringFunctions.c"
#"CMSIS/DSP/Src/MatrixFunctions/MatrixFunctions.c"
#"CMSIS/DSP/Src/StatisticsFunctions/StatisticsFunctions.c"
#"CMSIS/DSP/Src/SupportFunctions/SupportFunctions.c"
"CMSIS/DSP/Src/DistanceFunctions/DistanceFunctions.c"
#"CMSIS/DSP/Src/QuaternionMathFunctions/QuaternionMathFunctions.c"
#"CMSIS/DSP/Src/SVMFunctions/SVMFunctions.c"
#"CMSIS/DSP/Src/TransformFunctions/TransformFunctions.c"
#"CMSIS/DSP/Src/InterpolationFunctions/InterpolationFunctions.c"
#"CMSIS/DSP/Src/BayesFunctions/BayesFunctions.c"
"CMSIS/Core/*.*"
"startup/*.*"
"STM32F10x_FWLib/*.*"
"Core/*.*"
"HARDWARE/*.*"
"SYSTEM/*.*"
"USER/*.*"
) 之后需要取消CMaleList中的一些宏定义的注释来启用浮点数运算,这里使用的是STM32F1,没有FPU,故选择使用软件浮点运算(取消第二段注释),M4核心的话也可以使用硬件浮点运算(取消第一段注释)。
#Uncomment for hardware floating point
#SET(FPU_FLAGS "-mfloat-abi=hard -mfpu=fpv4-sp-d16")
#add_definitions(-DARM_MATH_CM4 -DARM_MATH_MATRIX_CHECK -DARM_MATH_ROUNDING -D__FPU_PRESENT=1)
##Uncomment for software floating point
SET(FPU_FLAGS "-mfloat-abi=soft")
SET(COMMON_FLAGS
"-mcpu=cortex-m3 ${FPU_FLAGS} -mthumb -mthumb-interwork -ffunction-sections -fdata-sections \
-g -fno-common -fmessage-length=0 -specs=nosys.specs -specs=nano.specs -u _printf_float") 2.4 修改arm_math.h
在arm_math.h开头加入
#include "stm32f10x.h" 即可,同理如果使用hal库的话就引用stm32f1xx.h。
2.5完工
之后就可以用了,可以选择只引用需要的功能,如
#include "dsp/distance_functions.h" 也可以引入整个库
#include "arm_math.h" 之后正常用就行了,至于有哪些功能可以参考官方文档
https://arm-software.github.io/CMSIS-DSP/latest/
总结一下,添加CMSIS-DSP库需要以下步骤
获取CMSIS-DSP和CMSIS-Core
将上述文件添加到工程目录中
修改CMakeList
修改arm_math.h