背景
我在芯片原厂做BSP开发,公司的项目原本只支持Keil MDK AC6编译器,领导让我增加个GCC编译器支持。当前我先增加了第一个版本的 CMake + GCC 编译支持,并且在 VS Code 中可以调用 J-Link 调试器进行调试,后续再完善 CMake 目录结构。
搭建嵌入式MCU 编译环境
安装软件清单
- GCC 编译器,这里以 2021.10 版本为例;
- CMake 工具,这里以 v3.28.1 为例;
- Ninja 或者 Make 工具,这里安装 ninja 绿色版本;
- 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 工具
它的作用和 make 一样,区别是 make 读取 Makefile 文件调用编译器命令,而 ninja 读取 build.ninja 文件调用编译器命令,而且 ninja 没有隐含规则,编译速度更快。
解压 ninja 到某个磁盘,然后添加到系统 PATH 路径,打开新的命令行输入 “ninja --version” 检查版本。
安装 JLink V752d
从 Segger 官网下载,点击安装一路 NEXT 即可。
编写 CMake
编写 CMake 目录程序,围绕着以下几点:
- 编译器配置:设定编译工具链路径,二进制文件和库文件输出路径;
- 针对处理器的编译选项:即C编译选项,针对处理器的宏定义,调试选项,链接脚本路径;
- 二进制目标文件的规则,库文件的导入导出:一般要指定可执行文件依赖源文件、头文件、库文件的路径;
- 编译后的elf/bin文件处理:即 elf/axf 如何加工生成 bin 文件,如何生成反汇编文件,以及调用外部工具处理 bin 文件;
这里直接列出工程修改后的大致结构:
- cmake 目录,存放 cmake 模块文件;
- test 目录,有一个 CMakeLists.txt 文件,实际上它继续添加下面的 testcase 目录,指导包含可执行文件所在目录;
- 链接脚本,这里有两个链接脚本,区分运行在Flash和 RAM 版本;
- 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 文件
此文件太长了,就不截图了。大致可以分为以下几个部分:
- 导入 cmake/ 目录下的模块;
- 调用 add_executable() 新增一个二进制构建目标,但是还没有增加源文件路径;
- 调用 include_directories() 为工程设置全局的头文件搜索路径;
- 调用 add_subdirectory(test) 把子目录加进来;
- 调用 include(cmake/gcc_custom_build.cmake) 设定编译后的 elf/axf 文件处理规则;
可执行文件指定源文件
前面说了顶层目录的 CMakeLists.txt 文件仅添加了可执行文件目标,但是没有指定源文件。通过调用 add_subdirectory() 层层依赖,最终到了我们的示例工程,文件内容如下:
- 使用 file(GLOB_RECURSE) 命令搜索当前目录下的C源程序添加到 USER_APP_SRCS 变量中;
- 设置 APP_DEP_SRCS 变量,加入GCC 版本的启动文件、system 文件以及标准输入输出重定向文件;
- 调用 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写法,从实战中收获新知识。
本文来自论坛,点击查看完整帖子内容。