注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
CoderX9527的个人空间 https://home.eeworld.com.cn/space-uid-1479210.html [收藏] [复制] [分享] [RSS]
日志

《CMake 构建实战-项目开发卷》实战分享3—从零开始给MCU项目增加CMake支持

已有 194 次阅读2024-10-29 15:41 |个人分类:评测

 

背景

我在芯片原厂做BSP开发,公司的项目原本只支持Keil MDK AC6编译器,领导让我增加个GCC编译器支持。当前我先增加了第一个版本的 CMake + GCC 编译支持,并且在 VS Code 中可以调用 J-Link 调试器进行调试,后续再完善 CMake 目录结构。

搭建嵌入式MCU 编译环境

安装软件清单
  1. GCC 编译器,这里以 2021.10 版本为例;
  2. CMake 工具,这里以 v3.28.1 为例;
  3. Ninja 或者 Make 工具,这里安装 ninja 绿色版本;
  4. JLink V752d,烧写程序、调试程序

安装 GCC 编译器

文件 gcc-arm-none-eabi-10.3-2021.10-win32.exe 可以从 ARM Developer 官网下载,地址如下:
下载后双击安装,一路 NEXT,安装到 “C:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2021.10\bin” 目录下。安装结束打开一个新的命令行窗口输入 “arm-none-eabi-gcc.exe --version” 检查是否看到正确的版本信息。
如果没有,就把此目录添加到系统环境变量 PATH 中。(后续各个软件也需要把安装路径添加到 PATH 变量中)

安装 CMake 工具

从 CMake 官网下载最新的版本,我这里以 3.28.1 版本为例。
点击安装,一路 NEXT 即可。

安装 Ninja 工具

ninja 是一个绿色软件,github 官方释放地址为:javascript:;
它的作用和 make 一样,区别是 make 读取 Makefile 文件调用编译器命令,而 ninja 读取 build.ninja 文件调用编译器命令,而且 ninja 没有隐含规则,编译速度更快。
解压 ninja 到某个磁盘,然后添加到系统 PATH 路径,打开新的命令行输入 “ninja --version” 检查版本。

安装 JLink V752d

从 Segger 官网下载,点击安装一路 NEXT 即可。

编写 CMake

编写 CMake 目录程序,围绕着以下几点:
  1. 编译器配置:设定编译工具链路径,二进制文件和库文件输出路径;
  2. 针对处理器的编译选项:即C编译选项,针对处理器的宏定义,调试选项,链接脚本路径;
  3. 二进制目标文件的规则,库文件的导入导出:一般要指定可执行文件依赖源文件、头文件、库文件的路径;
  4. 编译后的elf/bin文件处理:即 elf/axf 如何加工生成 bin 文件,如何生成反汇编文件,以及调用外部工具处理 bin 文件;
这里直接列出工程修改后的大致结构:
  1. cmake 目录,存放 cmake 模块文件;
  2. test 目录,有一个 CMakeLists.txt 文件,实际上它继续添加下面的 testcase 目录,指导包含可执行文件所在目录;
  3. 链接脚本,这里有两个链接脚本,区分运行在Flash和 RAM 版本;
  4. CMakeLists.txt 主目录文件,工程入口

cmake 目录中的模块文件

简单介绍此目录中的4个文件。

functions.cmake

定义了一些 cmake 通用函数,例如:

gcc_compiler_flags.cmake

定义了编译选项,包括针对处理器的选项,通用选项、调试选项以及链接器选项。下图仅截取一部分:

gcc_custom_build.cmake

定义了一些自定义目标,用来处理 axf/elf 文件到 bin 文件的转换。
这个文件用到了生成器语法和 CMAKE 命令(跨平台),比写 Makefile 方便多了。

gcc_toolchain_setup.cmake

此文件定义了编译工具链路径。

主目录 CMakeLists.txt 文件

此文件太长了,就不截图了。大致可以分为以下几个部分:
  1. 导入 cmake/ 目录下的模块;
  2. 调用 add_executable() 新增一个二进制构建目标,但是还没有增加源文件路径;
  3. 调用 include_directories() 为工程设置全局的头文件搜索路径;
  4. 调用 add_subdirectory(test) 把子目录加进来;
  5. 调用 include(cmake/gcc_custom_build.cmake) 设定编译后的 elf/axf 文件处理规则;

可执行文件指定源文件

前面说了顶层目录的 CMakeLists.txt 文件仅添加了可执行文件目标,但是没有指定源文件。通过调用 add_subdirectory() 层层依赖,最终到了我们的示例工程,文件内容如下:
  1. 使用 file(GLOB_RECURSE) 命令搜索当前目录下的C源程序添加到 USER_APP_SRCS 变量中;
  2. 设置 APP_DEP_SRCS 变量,加入GCC 版本的启动文件、system 文件以及标准输入输出重定向文件;
  3. 调用 target_sources() 命令为最终的可执行目标设置源文件路径。

编译后的动作

见上面的 gcc_custom_build.cmake 文件,调用编译工具链中的命令把 elf/axf 文件转换为 hex/bin 文件,并生成反汇编文件。

调试支持

VS Code 安装 Cortex-Debug 插件。
然后先点击(1)处的 Run and Debug 按钮,在点击(2)处的齿轮,配置调试选项。
在打开的 launch.json 文件输入以下内容,配置调试文件为 RADAR_CHIPX.elf 文件,调试器类型为 jlink,调试器接口为 swd,并配置进入调试时要执行的 JLink 命令。

运行

JLink 链接电脑和开发板之后,按 F5 键开始调试。
刚进入调试模式会弹出 TERMINAL 窗口,打印 JLink 调试器加载信息
然后 DEBUG CONSOLE 窗口会打印 JLink 调试器执行命令的信息
最后成功进入 main() 函数并打印信息

总结

编写 CMake 程序,主要是指定源文件、头文件、库文件路径,设置编译器选项、链接器参数等。当然还需要注意链接脚本设置的启动文件。
这个项目是为了赶时间所以CMake程序写的潦草,后期可以参考我的第一个分享 QCC74x SDK 的写法虽然复杂,但是每个example 都可以独立进入编译,而我这个项目需要修改顶层目录中的 CMakeLists.txt 文件,修改一个全局变量,有点麻烦。
多学习其他SDK的CMake写法,从实战中收获新知识。
 
 

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章