简介ARM Compiler Version 5ARMCC是ARM公司面向ARM架构处理器推出的高效编译工具链适合嵌入式开发工程师、物联网与汽车电子从业者以及需要为Cortex-A/R/M系列编写、编译和优化底层软件的开发者。资源包共650个文件约56.83MB以242个b文件、242个l文件、70个h头文件、24个cc源文件为主并包含exe可执行程序、s汇编文件、map与elmap映射文件以及algorithm、vector、iostream、memory等C标准库头文件覆盖编译器、链接器、汇编器与调试工具链的完整组成。内容涉及ARM指令集支持、O0至O3代码优化、ELF链接、调试信息生成、浮点运算与代码大小优化并集成CMSIS统一硬件访问接口。目前已有4270人学习下载可帮助读者理解ARMCC的编译流程、优化策略与标准库组织方式为嵌入式项目开发与工具链排错提供参考。1. ARMCC 编译器安装为什么老项目总卡在 Version 5 这一关接手一个十年前量产的工业控制板项目打开工程文件第一眼就看到ARMCC的路径指向C:\Keil_v5\ARM\ARMCC\bin而本机装的却是 Keil MDK 5.37 自带的 ARM Compiler 6。编译按钮按下去满屏error: unknown argument那一刻你就明白ARM Compiler Version 5 这个老家伙不是想绕就能绕过去的。ARMCC 是 ARM 公司被收购前推出的编译器套件属于 ARM Compiler 5 工具链的核心组件大量基于标准外设库、老版 RTOS 和遗留启动代码的工程都绑死在它上面。装不上或者装错版本轻则编译报错重则链接出来的镜像跑飞连调试器都连不上。这篇笔记面向的是手里有老工程、需要把 ARMCC 环境重新搭起来的开发者从版本选择、目录规划、环境变量配置一路写到编译验证和常见翻车现场照着走完至少能让你的老工程重新吐出.axf文件。2. 装前准备ARMCC 版本选择与目录规划2.1 先搞清楚 ARMCC 和 ARM Compiler 5 的关系很多人把 ARMCC 和 ARM Compiler 5 混着叫实际上 ARMCC 是 ARM Compiler 5 里的 C/C 编译器可执行文件同套件里还有armasm、armlink、fromelf这几个工具。ARM Compiler 5 的版本号通常以5.06结尾比如5.06 update 6、5.06 update 7这是最后几个被广泛使用的稳定版。再往后的 ARM Compiler 6 换成了基于 LLVM 的armclang命令行参数和 ARMCC 不兼容所以老工程迁移时最省事的做法不是改工程而是把 ARMCC 装回来。我一般会先确认工程里Options for Target的编译器版本要求。如果工程文件里写的是ARMCC而不是armclang那就老老实实装 ARM Compiler 5。版本选择上5.06 update 7是比较稳妥的选择它对 C99 的支持比早期版本完整又不像某些中间版本那样在链接脚本处理上有玄学问题。如果你手头有厂商提供的 BSP 包优先用 BSP 里附带的编译器版本因为厂商的启动文件和链接脚本往往是针对特定版本验证过的。2.2 目录规划别把 ARMCC 塞进系统盘默认路径ARM Compiler 5 的安装包通常是一个自解压的 exe默认会往C:\Keil_v5\ARM\ARMCC或者C:\Program Files\ARM\ARM_Compiler_5.06u7这类路径释放。我的习惯是把它放到一个独立目录比如D:\Tools\ARM_Compiler_5.06u7理由有两个一是避免和 Keil MDK 自带的编译器目录打架二是重装系统或者换机器时整个目录拷走就能用不需要重新跑安装程序。目录结构大概长这样D:\Tools\ARM_Compiler_5.06u7\ ├── bin\ │ ├── armcc.exe │ ├── armasm.exe │ ├── armlink.exe │ └── fromelf.exe ├── include\ │ ├── stdint.h │ └── ... ├── lib\ │ └── armlib\ └── license\bin目录是后面要加进 PATH 的include和lib是编译时自动引用的license目录里放的是授权文件。如果你用的是 Keil MDK 自带的 ARMCC路径通常在C:\Keil_v5\ARM\ARMCC但那个版本可能被 Keil 改过配置独立安装的版本更干净。2.3 环境变量配置PATH 和 ARMCC5 相关变量装完之后最关键的一步是把bin目录加进系统 PATH。Windows 下我一般用命令行改避免图形界面点错# 以管理员身份打开 cmd把 ARMCC 的 bin 目录追加到系统 PATH setx /M PATH %PATH%;D:\Tools\ARM_Compiler_5.06u7\bin这条命令会把路径写进系统环境变量重启终端后生效。注意setx有长度限制如果 PATH 已经很长可能会截断这时候建议用图形界面手动编辑或者用 PowerShell 的[Environment]::SetEnvironmentVariable方法。除了 PATH有些老工程还会引用ARMCC5_INC和ARMCC5_LIB这两个变量用来指定头文件和库文件路径。如果你的工程 Makefile 里有类似-I$(ARMCC5_INC)的写法就需要补上setx /M ARMCC5_INC D:\Tools\ARM_Compiler_5.06u7\include setx /M ARMCC5_LIB D:\Tools\ARM_Compiler_5.06u7\lib配完之后开一个新的 cmd 窗口敲armcc --version如果能看到版本号输出说明 PATH 生效了。如果提示「不是内部或外部命令」先检查路径里有没有空格或者中文ARMCC 对中文路径的支持时好时坏尽量用纯英文路径。3. 安装与授权ARMCC 5.06u7 落地步骤3.1 获取安装包与校验文件完整性ARM Compiler 5 的安装包通常以ARMCompiler5.06u7.exe或者ARM_Compiler_5.06u7_Win.exe命名大小在 200MB 到 400MB 之间。拿到安装包之后先核对一下文件哈希避免下载过程中损坏。我一般用certutil算 SHA256certutil -hashfile ARMCompiler5.06u7.exe SHA256把输出和官方提供的哈希值对比一致再往下走。如果哈希对不上重新下载别抱着侥幸心理硬装编译器文件损坏导致的报错往往很隐蔽可能编译到一半才崩。3.2 静默安装与自定义路径ARM Compiler 5 的安装程序支持静默安装适合批量部署或者写进自动化脚本。命令大概是这样# 静默安装到指定目录不创建桌面快捷方式 ARMCompiler5.06u7.exe --mode silent --install_to D:\Tools\ARM_Compiler_5.06u7 --no_shortcut参数说明--mode silent表示无交互安装--install_to指定目标路径--no_shortcut跳过快捷方式创建。如果你不确定安装程序支持哪些参数可以先跑ARMCompiler5.06u7.exe --help看看。有些版本的安装包参数名不太一样比如用-silent而不是--mode silent这个要按实际安装包的提示来。安装完成后去目标目录下确认bin\armcc.exe存在并且文件大小正常。如果安装程序中途报错先看日志文件通常在%TEMP%目录下文件名类似ARMCompiler_install.log。3.3 授权文件配置License 放哪里、怎么指向ARM Compiler 5 需要授权文件才能正常编译未授权版本会在编译时提示License error或者限制代码大小。授权文件通常是一个.dat文件比如license.dat。配置方式有两种一种是把授权文件放到license目录下另一种是通过环境变量ARMCC5_LICENSE指向授权文件路径。我一般用环境变量方式方便切换不同授权setx /M ARMCC5_LICENSE D:\Tools\ARM_Compiler_5.06u7\license\license.dat配完之后在 cmd 里跑armcc --license或者直接编译一个简单文件看是否还有授权报错。如果提示找不到授权检查文件路径有没有写错以及授权文件是否和编译器版本匹配。不同版本的 ARMCC 对授权文件的格式要求不一样5.06u7 的授权不能直接给 5.06u6 用。提示授权文件属于敏感文件不要放到版本控制仓库里也不要通过公开渠道传输。我一般会在.gitignore里加上*.dat和license/目录。4. 工程集成让 Keil 和 Makefile 都认到 ARMCC4.1 Keil MDK 里切换编译器版本如果你用的是 Keil MDK切换编译器版本在Project - Options for Target - Target标签页里有一个ARM Compiler下拉框。默认可能是Use default compiler version 6改成Use default compiler version 5或者手动指定ARMCC路径。但这里有个坑Keil MDK 5.37 之后的版本默认不再附带 ARM Compiler 5下拉框里可能根本没有 Version 5 选项。这时候需要手动把独立安装的 ARMCC 目录注册到 Keil 里。做法是打开 Keil 的Pack Installer或者直接改 Keil 的配置文件TOOLS.INI在[ARMCC]段里加上路径[ARMCC] PATHD:\Tools\ARM_Compiler_5.06u7\bin改完之后重启 Keil再看编译器下拉框应该就能选到 Version 5 了。如果还是不行检查TOOLS.INI的路径是否正确以及 Keil 是否有权限读取该文件。4.2 Makefile 工程里指定 ARMCC 路径对于用 Makefile 构建的工程需要在 Makefile 里显式指定CC、AS、LD等变量。一个典型的配置片段# 指定 ARMCC 工具链路径 ARMCC_DIR D:/Tools/ARM_Compiler_5.06u7/bin CC $(ARMCC_DIR)/armcc.exe AS $(ARMCC_DIR)/armasm.exe LD $(ARMCC_DIR)/armlink.exe FROMELF $(ARMCC_DIR)/fromelf.exe # 编译选项C99 标准优化等级 -O2输出调试信息 CFLAGS --c99 -O2 -g -I./inc -I$(ARMCC_DIR)/../include这里--c99是启用 C99 标准-O2是优化等级-g生成调试信息。注意 ARMCC 的优化选项和 GCC 不完全一样-O0到-O3都有但-O3在某些老版本上会触发过度优化导致逻辑错误我一般用-O2或者-O1。4.3 链接脚本与启动文件适配ARMCC 使用的链接脚本是.sct格式和 GCC 的.ld不一样。老工程的.sct文件通常长这样LR_IROM1 0x08000000 0x00080000 { ER_IROM1 0x08000000 0x00080000 { *.o (RESET, First) *(InRoot$$Sections) .ANY (RO) } RW_IRAM1 0x20000000 0x00010000 { .ANY (RW ZI) } }这段脚本定义了 Flash 和 RAM 的地址范围以及各个段的放置规则。如果你换了芯片型号需要同步改这里的地址和大小。启动文件一般是startup_xxx.s用armasm汇编和 ARMCC 是配套的。如果启动文件是用 GCC 语法写的需要换成 ARMCC 版本的启动文件否则汇编阶段就会报错。5. 避坑与排查ARMCC 安装配置常见问题5.1 编译报错 “unknown argument –c99”现象在命令行或者 Makefile 里用了--c99但 armcc 提示不识别该参数。原因不同版本的 ARMCC 对 C99 参数的支持不一样早期版本可能用--c99某些版本用-c99或者需要在--c99前面加--strict。解决先跑armcc --help看当前版本支持哪些参数把--c99换成-c99或者--c90试试。如果工程不依赖 C99 特性直接去掉这个参数也能编过。5.2 链接时报 “L6218E: Undefined symbol”现象编译单个文件没问题链接时提示某个符号未定义比如_main或者SystemInit。原因通常是启动文件或者库文件没参与链接或者链接脚本里没有包含对应的段。解决检查 Makefile 里是否把启动文件的.o加进了链接列表以及.sct脚本里是否有*(InRoot$$Sections)这一行。如果是库函数缺失确认lib目录下的armlib是否被正确引用。5.3 Keil 里切换编译器后工程配置丢失现象从 ARM Compiler 6 切回 5 之后之前配的 include 路径、宏定义、优化选项全没了。原因Keil 的工程文件.uvprojx里不同编译器版本的配置是分开存储的切换编译器相当于换了一套配置。解决切换之前先备份.uvprojx文件切换后手动把 include 路径和宏定义重新填一遍。或者用文本编辑器打开.uvprojx把ArmAdsMisc段里的配置复制到Cads段里。5.4 授权报错 “License file does not support this version”现象编译时提示授权文件不支持当前版本但授权文件明明是从正常工作的机器上拷过来的。原因ARMCC 的授权文件通常和版本号绑定5.06u6 的授权不能给 5.06u7 用。解决确认授权文件对应的版本号和当前安装的 ARMCC 版本一致。如果版本不匹配要么换授权文件要么换编译器版本。5.5 命令行能编译但 Keil 里报错现象在 cmd 里跑armcc --version正常但 Keil 里编译提示找不到编译器。原因Keil 使用的是自己的环境变量和路径配置不一定继承系统 PATH。解决在 Keil 的TOOLS.INI里显式指定 ARMCC 路径或者把 ARMCC 的bin目录加到 Keil 的Options for Target - Target - ARM Compiler的自定义路径里。6. 装完怎么验证从编译到烧录的完整检查装完 ARMCC 之后别急着打开老工程就编先跑一个最小验证流程确认工具链本身没问题。我一般会建一个临时目录写一个最简单的main.c和启动文件用命令行编译一遍看能不能生成.axf和.hex。// main.c最小验证程序只做一次空循环 #include stdint.h volatile uint32_t counter 0; int main(void) { while (1) { counter; } return 0; }编译命令# 编译 main.c指定 Cortex-M3 内核输出调试信息 armcc --cpu Cortex-M3 -c -g -O1 main.c -o main.o # 链接生成 axf 文件指定链接脚本 armlink --cpu Cortex-M3 main.o --scatterlink.sct -o demo.axf # 从 axf 生成 hex 文件 fromelf --i32 --outputdemo.hex demo.axf这三条命令跑完如果目录下出现了demo.axf和demo.hex说明 ARMCC 的编译、链接、格式转换三个环节都通了。接下来用fromelf --text -c demo.axf看一下反汇编确认代码段和数据段的地址和链接脚本里写的一致。然后把这个最小工程导入 Keil用 Keil 的编译按钮再编一遍确认 IDE 环境下也能正常构建。最后用调试器烧录到板子上看程序能不能停在main函数入口。如果烧录后跑飞先检查链接脚本里的 Flash 和 RAM 地址是否和芯片手册一致再检查启动文件里的堆栈指针初始化是否正确。注意验证阶段不要直接拿量产工程的完整代码来试先用最小工程确认工具链没问题再逐步把老工程的源文件加进来这样出问题时容易定位是工具链的问题还是工程代码的问题。从那以后我每次装完 ARMCC都会强制走一遍这个最小验证流程哪怕只是换了一台机器或者重装了系统。因为编译器这东西版本号看着一样实际行为可能差很多只有亲手编出一个能烧录的 hex才算真正装好了。希望帮到你。本文还有配套的精品资源点击获取