你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32CubeMX2 无法正常添加 CMSIS-DSP?基于 CMake 的手动集成与工程结构优化

[复制链接]
云淼 发布时间:2026-10-9 15:36

STM32CubeMX2 无法正常添加 CMSIS-DSP?基于 CMake 的手动集成与工程结构优化

一、问题背景

最近使用 STM32C542RCT6 开发板进行三角函数性能测试,开发环境如下:

项目 版本或配置
MCU STM32C542RCT6
开发环境 VS Code
工程生成工具 STM32CubeMX2 1.1.1
构建系统 CMake
CMSIS 6.3.0
CMSIS-DSP 1.17.1
工具链 GCC

测试的目标是比较 STM32C5 硬件 CORDIC、CMSIS-DSP 和标准数学库 sinf() 的计算性能。

在 CubeMX2 的 Pack Manager 中安装了 CMSIS 和 CMSIS-DSP 软件包,但生成工程时遇到了问题:CMSIS Core 可以正常集成,CMSIS-DSP 却没有按照预期生成到工程目录中。

即使手动修改 .ioc2 工程配置,让 CMSIS-DSP 组件出现在项目设置中,重新生成后,工程目录下仍然没有得到预期的 arch/cmsis_dsp 目录。

这说明:安装 Pack、在工程配置中声明组件,以及实际把组件源码加入 CMake 构建,是三个不同的环节。

二、分析 CubeMX2 生成的 CMake 工程

CubeMX2 生成的工程主要包含以下结构:

Project09_sine/
├── Application/
│   ├── CMakeLists.txt
│   ├── app/
│   ├── bsp/
│   ├── tool/
│   └── cmake/
├── arch/
├── generated/
├── stm32c5xx_drivers/
├── user_modifiable/
├── cmake/
│   ├── components.cmake
│   ├── files.cmake
│   ├── flags.cmake
│   └── target.cmake
├── CMakeLists.txt
└── Project09_sine.ioc2

其中,顶层 CMakeLists.txt 是工程入口,cmake/components.cmake 负责组件列表、子目录及相关目标的组织。

在 components.cmake 中,可以看到类似以下代码:

set(CMSIS_COMPONENTS_LIST )

if(${CMAKE_BUILD_TYPE} STREQUAL "debug_GCC_STM32C542RCT6")
    list(APPEND CMSIS_COMPONENTS_LIST
        "Cvendor:STMicroelectronics#Cclass:CMSIS#Cgroup:CORE#Cversion:6.2.0"
    )

    # 其他组件配置
endif()

add_subdirectory(arch/cmsis)
add_subdirectory(stm32c5xx_dfp)
add_subdirectory(stm32c5xx_drivers)

# 其他组件目录

target_link_libraries(${CMAKE_PROJECT_NAME}
    # CubeMX2 生成的组件目标
)

这里有两个关键点:

  1. CMSIS_COMPONENTS_LIST 用来描述当前构建启用的 CMSIS 软件组件。
  2. 软件包自身的 CMakeLists.txt 可以根据组件列表决定添加哪些源文件、头文件目录和编译定义。

因此,仅仅在 .ioc2 中添加组件声明,并不意味着对应的 CMake 目标、源码和头文件路径已经全部接入构建。

三、确认 CMSIS-DSP 软件包自身支持 CMake

安装的 CMSIS-DSP 1.17.1 软件包位于:

%LOCALAPPDATA%\stm32cube\packs\STMicroelectronics\CMSIS-DSP\1.17.1

其中存在软件包自己的 CMakeLists.txt。

该文件会创建一个 CMake 目标:

STMicroelectronics_CMSIS_DSP_1_17_1

并根据 CMSIS_COMPONENTS_LIST 中的 DSP 组件标识,配置相应的头文件路径及源文件。

因此,没有必要把整个 CMSIS-DSP 软件包复制到 Application 目录,也不必手动列出所有 DSP 源文件。可以直接复用软件包提供的 CMake 配置。

四、手动集成 CMSIS-DSP

1. 确认软件包路径

首先确认本机已经安装 CMSIS-DSP 1.17.1,并且存在:

%LOCALAPPDATA%\stm32cube\packs\STMicroelectronics\CMSIS-DSP\1.17.1\CMakeLists.txt

2. 在组件列表中启用 DSP

在原先的 cmake/components.cmake 中加入以下组件标识:

list(APPEND CMSIS_COMPONENTS_LIST
    "Cvendor:STMicroelectronics#Cclass:CMSIS#Cgroup:DSP#Cvariant:Source#Cversion:1.17.1"
)

这一步让 CMSIS-DSP 软件包的 CMake 配置能够识别当前启用的 DSP 组件。

3. 加入 CMSIS-DSP 子目录

在 components.cmake 中,add_subdirectory(arch/cmsis) 后加入:

add_subdirectory(
    "$ENV{LOCALAPPDATA}/stm32cube/packs/STMicroelectronics/CMSIS-DSP/1.17.1"
    "${CMAKE_BINARY_DIR}/cmsis_dsp"
)

4. 将 DSP 目标链接到主工程

在 components.cmake 原有的 target_link_libraries() 中加入:

STMicroelectronics_CMSIS_DSP_1_17_1

例如:

target_link_libraries(${CMAKE_PROJECT_NAME}
    # 原有的 CubeMX2 组件目标
    STMicroelectronics_CMSIS_DSP_1_17_1
)

注意: CubeMX2 生成的 target_link_libraries() 使用的是不带 PUBLIC、PRIVATE 等关键字的 plain signature。添加目标时应沿用相同形式,不能在同一目标的不同调用中混用两种签名。

完成以上修改后,重新配置并编译工程。

五、验证是否集成成功

配置命令:

cmake --preset debug_GCC_STM32C542RCT6

编译命令:

cmake --build --preset debug_GCC_STM32C542RCT6

实际编译日志中出现了如下文件:

CMSIS-DSP/1.17.1/Source/BasicMathFunctions/BasicMathFunctions.c.obj
CMSIS-DSP/1.17.1/Source/FastMathFunctions/FastMathFunctions.c.obj
CMSIS-DSP/1.17.1/Source/CommonTables/CommonTables.c.obj
CMSIS-DSP/1.17.1/Source/TransformFunctions/TransformFunctions.c.obj

最后成功链接:

[66/66] Linking C executable Project09_sine.elf

生成已完成,退出代码为 0

这证明 CMSIS-DSP 的源码已经进入实际编译流程,而不只是把软件包显示在项目配置中。

接下来,在应用代码中加入:

#include "arm_math.h"

进行最小功能测试:

float angle = 0.5f;
float result;

result = arm_sin_f32(angle);

printf("CMSIS-DSP sin(%f) = %f\r\n", angle, result);

预期输出接近:

CMSIS-DSP sin(0.500000) = 0.479426

至此,CMSIS-DSP 的基本调用验证完成。

六、进一步优化:避免修改 CubeMX2 自动生成文件

上面的方式已经验证可行,但存在一个工程维护问题:components.cmake 是自动生成文件,重新生成工程时,手动添加的内容可能被覆盖。

因此,进一步把用户维护的构建配置迁移到 Application 目录。

推荐结构:

Project09_sine/
├── Application/
│   ├── CMakeLists.txt
│   ├── cmake/
│   │   └── cmsis_dsp.cmake
│   ├── app/
│   ├── bsp/
│   └── tool/
├── cmake/                 # CubeMX2 生成的构建配置
├── generated/
├── arch/
├── stm32c5xx_drivers/
└── CMakeLists.txt

其中:

  • Application/CMakeLists.txt 管理应用源文件、头文件目录及用户编译配置。
  • Application/cmake/cmsis_dsp.cmake 管理 CMSIS-DSP 接入。
  • 顶层 CMakeLists.txt 保留工程入口及 add_subdirectory(Application)。
  • CubeMX2 自动生成的 cmake/components.cmake 尽量不保留用户手工修改。

1. 用户维护的 CMSIS-DSP 配置

新建 Application/cmake/cmsis_dsp.cmake:

# User-maintained CMSIS-DSP integration

set(CMSIS_DSP_VERSION "1.17.1")

set(CMSIS_DSP_ROOT
    "$ENV{LOCALAPPDATA}/stm32cube/packs/STMicroelectronics/CMSIS-DSP/${CMSIS_DSP_VERSION}"
)

if(NOT EXISTS "${CMSIS_DSP_ROOT}/CMakeLists.txt")
    message(FATAL_ERROR
        "CMSIS-DSP not found: ${CMSIS_DSP_ROOT}"
    )
endif()

list(APPEND CMSIS_COMPONENTS_LIST
    "Cvendor:STMicroelectronics#Cclass:CMSIS#Cgroup:DSP#Cvariant:Source#Cversion:${CMSIS_DSP_VERSION}"
)

add_subdirectory(
    "${CMSIS_DSP_ROOT}"
    "${CMAKE_BINARY_DIR}/cmsis_dsp"
)

target_link_libraries(${CMAKE_PROJECT_NAME}
    STMicroelectronics_CMSIS_DSP_1_17_1
)

2. 应用层 CMake 管理

在 Application/CMakeLists.txt 中加入:

include(
    "${CMAKE_CURRENT_LIST_DIR}/cmake/cmsis_dsp.cmake"
)

应用代码和编译配置也统一放在这个文件中,例如:

target_sources(${CMAKE_PROJECT_NAME} PRIVATE
    app/callbacks.c
    app/app.c
    bsp/bsp_BTN.c
    bsp/bsp_MT6701.c
    bsp/bsp_uart.c
    tool/sys_DWT.c
)

target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
    ${CMAKE_CURRENT_LIST_DIR}/bsp
    ${CMAKE_CURRENT_LIST_DIR}/app
    ${CMAKE_CURRENT_LIST_DIR}/tool
)

target_compile_definitions(${CMAKE_PROJECT_NAME} PUBLIC
    _PRINTF_FLOAT_ENABLE=1
)

target_link_options(${CMAKE_PROJECT_NAME} PUBLIC
    -u _printf_float
)

这样可以把应用代码、编译宏、链接选项以及第三方库接入配置集中管理,减少对自动生成文件的依赖。

3. 需要特别注意 CMake 执行顺序

上述迁移方案有一个重要前提:CMSIS_COMPONENTS_LIST 必须在 CMSIS-DSP 软件包的 add_subdirectory() 执行前准备好。

CubeMX2 当前工程的顶层执行顺序中,add_subdirectory(Application) 原本位于 include(cmake/components.cmake) 之前。若不调整顺序,Application 内的 DSP 配置可能在组件列表初始化前执行。

因此,应先保证组件列表已经建立,再调用用户的 CMSIS-DSP 配置。若要严格做到顶层只保留 add_subdirectory(Application) 这一句用户扩展,就需要确认 CubeMX2 的生成机制允许调整执行顺序,或采用单独的用户扩展入口。

此外,CubeMX2 重新生成后应重新检查构建顺序、组件列表及 DSP 目标,不能**用户 CMake 文件仍然存在就认定集成一定成功。

七、总结

这次问题的核心并不是 CMSIS-DSP 缺少 CMake 支持,而是 CubeMX2 图形界面的组件配置能力、软件包自身的 CMake 机制,以及生成工程的执行顺序之间存在衔接问题。

排查后确认:

  1. CMSIS-DSP 1.17.1 软件包本身提供 CMake 配置。
  2. 通过正确的 CMSIS_COMPONENTS_LIST 标识、add_subdirectory() 和目标链接,可以将 DSP 源码加入 STM32C542 工程。
  3. 实际编译日志确认了 DSP 源文件参与编译,最终 ELF 成功链接。
  4. 为了提高工程可维护性,应把应用代码及自定义构建逻辑放入 Application,尽量减少对 CubeMX2 自动生成文件的修改。
  5. 将配置迁移到用户目录后,仍需通过重新生成、重新配置、重新编译三步验证,确认不会因为执行顺序或组件列表被重置而失效。

对于正在使用 STM32C5、CubeMX2、VS Code 和 CMake 的开发者,希望这次实践能够提供一个可复现的排查思路。

最后说明: 本文验证的是 CMSIS-DSP 1.17.1 在上述 STM32C542 工程中的编译与基本函数调用。不同 CubeMX2 版本、不同芯片系列及不同软件包版本的组件标识和 CMake 机制可能有所不同,实际使用时应以对应软件包的 CMakeLists.txt 为准。

赞 1 收藏 评论0 发布时间:2026-10-9 15:36

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版