Keil 的工程可以通过 uv2csolution 转成 CMSIS 工程, 再用 cbuild 在 Windows 或 Linux 的命令行下编译, 不需要打开 µVision.

这里记录 Arm Compiler 6.24.19, CMSIS-Toolbox 2.14.1 和 MDK-Toolbox 1.1.0 的安装及工程转换过程. 下面以 Linux x86_64 为例, 工具安装到 /opt, 测试工程文件为 project.uvprojx. Windows 下操作流程相同, 换成对应的 Windows 工具包, 并调整安装路径和环境变量的设置方式即可.

安装 Arm Compiler

这里使用 MDK Community(社区版) 的 Arm Compiler 下载链接, 其他下载入口可以查看 Arm 官方下载页面.

1
2
3
4
5
cd /tmp
compiler_url=https://artifacts.keil.arm.com/arm-compiler/6.24/19
wget -O standalone-linux-x86_64-rel_6.24.19.tar.gz "$compiler_url/standalone-linux-x86_64-rel.tar.gz"
sudo mkdir -p /opt/arm-compiler-6.24
sudo tar xzvf standalone-linux-x86_64-rel_6.24.19.tar.gz -C /opt/arm-compiler-6.24

设置编译器路径. 环境变量中的版本号需要与安装版本对应, 路径指向 bin 目录.

1
export AC6_TOOLCHAIN_6_24_19="/opt/arm-compiler-6.24/bin"

激活授权

使用编译器自带的 armlm 激活 MDK Community 授权:

1
/opt/arm-compiler-6.24/bin/armlm activate --product KEMDK-COM0 --server https://mdk-preview.keil.arm.com

MDK Community 是非商业用途授权, 商业项目需要使用相应的商业授权. 参考 Arm 授权激活说明.

激活和后续编译使用同一个普通用户, 不要用 sudo 激活.

安装 CMSIS-Toolbox 和 MDK-Toolbox

cbuild 和 cpackget 在 CMSIS-Toolbox 中, 转换 Keil 工程用的 uv2csolution 在 MDK-Toolbox 中.

1
2
3
4
5
6
7
8
cd /tmp
cmsis_url=https://github.com/Open-CMSIS-Pack/cmsis-toolbox/releases/download
wget "$cmsis_url/2.14.1/cmsis-toolbox-linux-amd64.tar.gz"
tar xzvf cmsis-toolbox-linux-amd64.tar.gz
sudo mv cmsis-toolbox-linux-amd64 /opt/cmsis-toolbox

wget https://artifacts.tools.arm.com/mdk-toolbox/1.1.0/mdk-toolbox-linux-amd64.tar.gz
sudo tar xzvf mdk-toolbox-linux-amd64.tar.gz -C /opt/cmsis-toolbox

把工具加入 PATH, 再执行后面的 cpackget 和 uv2csolution 命令:

1
export PATH="/opt/cmsis-toolbox/bin:/opt/cmsis-toolbox/mdk-toolbox-linux-amd64/bin:$PATH"

cbuild 还依赖 CMake 和 Ninja, 需要提前安装并加入 PATH. 按 CMSIS-Toolbox 当前官方安装说明, 版本要求如下:

工具 当前官方版本要求
CMake 3.31.5 或更新
Ninja 1.12.0 或更新

这里列的是当前官方要求, 不代表已验证 CMSIS-Toolbox 2.14.1 的最低兼容版本. 安装后检查各工具是否可用:

1
2
3
4
cmake --version
ninja --version
cbuild --version
uv2csolution --version

再检查是否已识别到 Arm Compiler:

1
cbuild list toolchains

确认输出中有 AC6 6.24.19. 如果没有, 检查当前 shell 中的 AC6_TOOLCHAIN_6_24_19 是否指向编译器的 bin 目录.

上面的 AC6_TOOLCHAIN_6_24_19 和 PATH 设置只对当前 shell 生效, 需要长期使用可以加入 ~/.bashrc.

初始化软件包

初始化 CMSIS-Pack 索引:

1
cpackget init https://www.keil.com/pack/index.pidx

如果工程依赖本地的 .pack 文件, 可以手动安装. /opt/xx.pack 替换成实际文件路径:

1
cpackget add /opt/xx.pack

转换 Keil 工程

切换到测试工程文件 project.uvprojx 所在的目录, 执行:

1
uv2csolution project.uvprojx

测试工程转换后生成了下面几个文件, 实际名称随工程和 target 名称变化:

生成文件 用途
project.cproject.yml 工程配置, 定义源文件, 头文件搜索路径, 宏以及编译和链接参数等.
project.csolution.yml 解决方案配置, 组织工程并定义构建类型, 目标类型和工具链等.
project_Project.sct Arm 链接器的分散加载文件, 定义 Flash/RAM 的内存布局及代码和数据的放置位置.
vcpkg-configuration.json vcpkg 工具环境配置, 声明所需工具及版本要求, 用于配置开发环境.

下面以测试工程生成的 project.csolution.yml 和 project.cproject.yml 为例说明参数调整, 其他工程按实际配置修改.

调整优化等级

测试工程使用 balanced 优化等级, 在 project.csolution.yml 中将对应配置的 optimize 项设置为:

1
optimize: balanced

这是 CMSIS 工程的通用优化等级, 不直接填写 -O2 之类的编译器参数. uv2csolution 从 µVision 转换时的对应关系如下:

µVision 优化选项 CMSIS 工程配置
-O0, <default> optimize: none
-O1 optimize: none
-O2 optimize: speed
-O3 optimize: speed
-Ofast optimize: speed
-Os (balanced) optimize: balanced
-Oz (image size) optimize: size
-Omax optimize: balanced

如果 µVision 中勾选了 Options for Target -> Output -> Debug Information, 转换时会设置为 optimize: debug, 优先于上表的映射. 要按原来的优化选项转换, 需要先取消勾选.

以上是工程转换时的映射, 不是编译参数的一一对应关系. 参考 uv2csolution 说明.

拆分编译参数

测试工程的 project.cproject.yml 中有多个参数被放在同一项里的情况:

1
- -Wno-invalid-source-encoding -fshort-enums

需要拆成两项, 保持原来所在位置的缩进:

1
2
- -Wno-invalid-source-encoding
- -fshort-enums

调整汇编参数

测试工程转换后, 需要删除下面这项强制语言设置:

1
- -x assembler

-x assembler 会强制把输入文件作为不经过 C 预处理的汇编源文件处理. 例如 .S 文件中的 #include 和 #define 需要预处理, 强制使用这个参数就会跳过这一步. 删除它是为了避免覆盖工具链原有的汇编模式, 让文件扩展名和工具链配置决定处理方式. 如果源文件需要预处理, 最终命令应使用支持预处理的模式, 如 -x assembler-with-cpp.

并在相应的汇编参数列表中加入:

1
- -Wno-unused-command-line-argument

-Wno-unused-command-line-argument 用于关闭 argument unused during compilation 警告. 汇编命令如果沿用了仅对 C/C++ 编译生效的参数, 如 -fshort-enums, armclang 会提示这些参数没有被使用. 添加这个选项只关闭此类警告, 不会让这些参数对汇编生效, 也不会修复汇编语法或预处理错误.

上述调整针对测试工程, 其他工程需结合源文件类型和实际汇编命令判断.

设置 map 文件

map 文件路径配置在 Link 参数列表中, 测试工程将其输出到链接时的当前目录.

下面汇总前面的参数调整, 展示 project.cproject.yml 中的配置层级. 示例只列出相关字段, 合并到现有的 project -> misc 配置中, 保留其他参数和字段:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
project:
  misc:
    - for-compiler: AC6
      C:
        - -Wno-invalid-source-encoding
        - -fshort-enums
      ASM:
        - -Wno-unused-command-line-argument
      Link:
        - --list=./project.map

C 是 C 编译参数, ASM 是汇编参数, Link 是链接参数. 如果原参数位于 C-CPP 或 group/file 级配置中, 在原位置修改, 不要为了套用示例改变参数的作用范围.

编译工程

仍然在测试工程文件所在的目录执行:

1
cbuild project.csolution.yml -p

-p 是 --packs 的缩写, 用于下载缺少的软件包, 不是指定工程路径. 私有或本地的软件包仍需要提前安装.

cbuild 的其他选项可以查看 CMSIS-Toolbox 命令说明.