CLion开发STM32(三)DSP库移植
首先DSP库源码可以从官方github下载,链接如下:
https://github.com/ARM-software/CMSIS-DSP
笔者所用版本为1.17.0,本文以此版本为例。
添加DSP库也是通过配置CMakeLists.txt文件进行,主要有两种方式:
1.直接添加源码(添加方便,但是每次构建都要重新编译一遍DSP库)
2.编译成静态链接库.a文件再添加(需要手动编译才能添加,但是不用重复编译,构建速度快)
一、源码添加
需要用到DSP库下的这三个文件夹
- Source
- Include
- PrivateInclude
在CMakeLists文件中将相关修改参考如下:
# 定义 DSP 根目录地址 set(DSP_ROOT "/home/elysia/Software/Embedded_Libs/CMSIS-DSP/1.17.0") # 收集所有 DSP 源文件 file(GLOB_RECURSE DSP_SOURCES "${DSP_ROOT}/Source/*.c" ) # Add sources to executable target_sources(${CMAKE_PROJECT_NAME} PRIVATE # Add user sources here ${DSP_SOURCES} ) # Add include paths target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined include paths "${DSP_ROOT}/Include" # 头文件路径 "${DSP_ROOT}/PrivateInclude" # 私有头文件路径 ) # Add project symbols (macros) target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined symbols ARM_MATH_CM7 )但是这个时候直接构建会出现问题,主要是两个原因:
1. 添加.c文件的时候包含了名称类似_arm_mat_mult_neon_buffers.c这样以字符 “ _ ” 开头的模板文件。
2. DSP库本身带有聚合文件,就是名称类似 BasicMathFunctions.c 这样的以大写字母开头的文件,会导致重复编译问题。
解决方法就是在target_sources 添加源文件之前添加下面的代码:
# 排除以下划线开头的模板文件 list(FILTER DSP_SOURCES EXCLUDE REGEX ".*/_.*\.c$") # 排除所有大写字母开头的文件(聚合文件) list(FILTER DSP_SOURCES EXCLUDE REGEX ".*/[A-Z][^/]*\\.c$")修复之后就可以正常编译了,相关的完整配置如下:
# 定义 DSP 根目录地址 set(DSP_ROOT "/home/elysia/Software/Embedded_Libs/CMSIS-DSP/1.17.0") # 收集所有 DSP 源文件 file(GLOB_RECURSE DSP_SOURCES "${DSP_ROOT}/Source/*.c" ) # 排除以下划线开头的模板文件 list(FILTER DSP_SOURCES EXCLUDE REGEX ".*/_.*\.c$") # 排除所有大写字母开头的文件(聚合文件) list(FILTER DSP_SOURCES EXCLUDE REGEX ".*/[A-Z][^/]*\\.c$") # Add sources to executable target_sources(${CMAKE_PROJECT_NAME} PRIVATE # Add user sources here ${DSP_SOURCES} ) # Add include paths target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined include paths "${DSP_ROOT}/Include" # 头文件路径 "${DSP_ROOT}/PrivateInclude" # 私有头文件路径 ) # Add project symbols (macros) target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined symbols ARM_MATH_CM7 #__FPU_PRESENT=1 )二、编译成静态链接库添加
手动编译源码需要用到DSP库源码以及CMSIS源码的Core部分,链接分别如下:
https://github.com/ARM-software/CMSIS-DSP
https://github.com/ARM-software/CMSIS_6
此处在Ubuntu系统下,以stm32h7为例,使用 cubeclt 的 arm-none-eabi 编译器进行编译。
如果是在Windows环境下进行编译,可以使用cmake-gui进行。
cd /home/elysia/Software/Embedded_Libs/CMSIS-DSP/1.17.0/ mkdir -p build/stm32h7 cd build/stm32h7在stm32h7目录下创建文件h7_toolchain.cmake,并写入如下内容:
(记得修改 cubeclt 以及 cmsis-core 的路径)
# --- STM32CubeCLT Toolchain File for STM32H743 (Cortex-M7) --- set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR arm) # 1. Set the toolchain prefix for STM32CubeCLT Compiler set(TOOLCHAIN_PREFIX "/home/elysia/Software/CubeCLT/GNU-tools-for-STM32/bin/arm-none-eabi-") set(CMAKE_C_COMPILER "${TOOLCHAIN_PREFIX}gcc") set(CMAKE_CXX_COMPILER "${TOOLCHAIN_PREFIX}g++") set(CMAKE_ASM_COMPILER "${TOOLCHAIN_PREFIX}gcc") # 2. Specify CMSIS-Core Include Path set(CMSIS_CORE_INCLUDE_PATH "/home/elysia/Software/Embedded_Libs/CMSIS/Core/Include") # 3. Set STM32H743 (Cortex-M7) Compilation Flags set(CPU_FLAGS "-mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -fno-strict-aliasing --specs=nosys.specs") # 4. Set DSP-specific Macros (for M7 and DSP support) set(DSP_DEFINES "-DARM_MATH_CM7 -DARM_MATH_DSP -D__FPU_PRESENT=1") # 5. Enable function and data section separation for optimization set(CMAKE_C_FLAGS "${CPU_FLAGS} -Wall -O3 -I${CMSIS_CORE_INCLUDE_PATH} ${DSP_DEFINES} -ffunction-sections -fdata-sections " CACHE INTERNAL "") set(CMAKE_CXX_FLAGS "${CPU_FLAGS} -Wall -O3 -I${CMSIS_CORE_INCLUDE_PATH} ${DSP_DEFINES} -ffunction-sections -fdata-sections " CACHE INTERNAL "") # 6. Set the linker flags to enable garbage collection of unused sections set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections") # 7. FPU settings (ensure proper FPU support) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__FPU_PRESENT=1 -D__FPU_USED=1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FPU_PRESENT=1 -D__FPU_USED=1") # 8. Configure the CMake search behavior set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)然后在stm32h7目录下配置编译,整体目录结构为:
/home/elysia/Software/Embedded_Libs/CMSIS-DSP/1.17.0/build/stm32h7/
# 清理残留 rm -f CMakeCache.txt rm -rf CMakeFiles/ cmake -G Ninja \ -DCMAKE_TOOLCHAIN_FILE=./h7_toolchain.cmake \ -DCMAKE_BUILD_TYPE=Release \ -DNEON=OFF \ -DHELIUM=OFF \ -DAUTOVECTORIZE=OFF \ ../.. # 开始编译 ninja编译结果大致如下:
CMake Warning (dev) in CMakeLists.txt: No project() command is present. The top-level CMakeLists.txt file must contain a literal, direct call to the project() command. Add a line of code such as project(ProjectName) near the top of the file, but after cmake_minimum_required(). CMake is pretending there is a "project(Project)" command on the first line. This warning is for project developers. Use -Wno-dev to suppress it. CMake Warning (dev) in CMakeLists.txt: cmake_minimum_required() should be called prior to this top-level project() call. Please see the cmake-commands(7) manual for usage documentation of both commands. This warning is for project developers. Use -Wno-dev to suppress it. -- The C compiler identification is GNU 13.3.1 -- The CXX compiler identification is GNU 13.3.1 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /home/elysia/Software/CubeCLT/GNU-tools-for-STM32/bin/arm-none-eabi-gcc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /home/elysia/Software/CubeCLT/GNU-tools-for-STM32/bin/arm-none-eabi-g++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done CMake Warning (dev) in CMakeLists.txt: No cmake_minimum_required command is present. A line of code such as cmake_minimum_required(VERSION 3.28) should be added at the top of the file. The version specified may be lower if you wish to support older CMake versions for this project. For more information run "cmake --help-policy CMP0000". This warning is for project developers. Use -Wno-dev to suppress it. -- Configuring done (0.2s) -- Generating done (0.0s) -- Build files have been written to: /home/elysia/Software/Embedded_Libs/CMSIS-DSP/1.17.0/build/stm32h7 [603/603] Linking C static library Source/libCMSISDSP.a没有报错且出现类似 [603/603] Linking C static library Source/libCMSISDSP.a 就没有问题了。
完成之后就可以在.../stm32h7/Source/ 下得到 libCMSISDSP.a
接下来将.a链接库以及头文件添加到工程即可,CMakeLists文件需要修改部分如下:
# 定义 DSP 根目录地址 set(DSP_ROOT "/home/elysia/Software/Embedded_Libs/CMSIS-DSP/1.17.0") # Link directories setup target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined library search paths "${DSP_ROOT}/build/stm32h7/Source" ) # Add include paths target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined include paths "${DSP_ROOT}/Include" # 头文件路径 "${DSP_ROOT}/PrivateInclude" # 私有头文件路径 ) # Add project symbols (macros) target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined symbols ARM_MATH_CM7 #__FPU_PRESENT=1 ) # Add linked libraries target_link_libraries(${CMAKE_PROJECT_NAME} # Add user defined libraries stm32cubemx CMSISDSP # 链接 libCMSISDSP.a m # 链接数学库 libm.m )使用静态链接库的方式就不需要添加一大堆源码每次构建都进行编译,编译速度会快不少。
