
简介面向ARM架构嵌入式开发者提供的ARM Compiler 5.06(960) Windows安装包需配合Keil MDK使用核心作用是把C源码高效编译为32位ARM处理器机器码解决本地工具链搭建与老旧工程兼容问题。压缩包共3个文件约80.52MB含msi安装主程序、exe引导启动文件和一份html版发布说明安装程序负责在Windows x86平台完成部署html文档记录版本960的更新内容、改进与已知问题便于读者判断兼容性、提前规避踩坑。armcc通过Plum Hall C Validation Suite验证对ANSI C支持严格并提供代码大小与运行速度优化选项支持ARM、Thumb、Thumb-2多种指令子集适合资源受限的MCU项目。借助Keil图形化工程管理与调试环境可完成编辑、编译、链接到JTAG/SWD下载调试的完整流程。已有3607人学习下载适合从入门到进阶的嵌入式开发者搭建稳定可用的编译环境。1. 装完 Keil 才发现没有 AC5先把这个 MSI 备好前段时间接手一个 Cortex-M3 的老工程接手的环境里装的是较新的 MDK打开工程点开 Options for TargetTarget 页的 ARM Compiler 下拉框里只有 version 6 一条。编译一下启动文件、厂商外设库、链接脚本全线报错改了半天才发现问题不在代码——这颗芯片的 SDK 和几个第三方静态库全是当年用 armcc 5.06 编出来的。ARMCC 5.06 这套编译器就是 ARM Compiler 5.06 update 6构建号 b960MDK 5.37 之后不再随安装包分发必须单独拿ARMCompiler_506_Windows_x86_b960.msi装。AC6 换了 LLVM 后端源码级不兼容的地方一大片老工程直接迁过去往往比装回 AC5 更费时间。这篇记录的就是这套装法装哪、怎么装、怎么挂进 Keil、装坏了怎么救。2. 版本对不清就别动手AC5、MDK 与 b960 的对应关系动手前先要把“我要的到底是哪个东西”确定下来。这里涉及三个层面编译器版本、构建号、宿主 IDE 版本。只要在这个问题上判断错一次后面所有步骤都会白做装完发现进不了 Keil、或者进了 Keil 但版本不对这种情况很常见。2.1 拆开文件名5.06 是主版本960 是构建号ARMCompiler_506_Windows_x86_b960.msi这个名字里塞了三条信息。506是 ARM Compiler 5.06 的主版本号x86表示这是一个 32 位安装包在 64 位系统上照样能装只是默认落在Program Files (x86)下b960是构建号对应 update 6。所以口头说的“AC5”“ARMCC 5.06”“ARM Compiler 5.06 update 6 (build 960)”指的都是同一套东西。麻烦的地方在于Keil 的 Target 下拉框里只显示version 5这种大版本不显示构建号。也就是说你没法从界面上判断当前挂的是不是 960。要确认是不是 960只有两条路一条是在命令行敲armcc --vsn看它打印的 Component 行另一条是打开编译产物里的 map 文件看链接器版本行。这两条后面都会用到。另一个容易混淆的点是 MDK 自带与独立安装的关系。MDK 5.36 及更早的版本安装包里自带一份 AC5位置在C:\Keil_v5\ARM\ARMCC从 5.37 开始这份被拿掉了Target 页只剩 AC6。所以如果你的机器是新装的 MDK别在Keil_v5\ARM下面找那里不会有。MDK 版本是否自带 AC5你需要做的5.36 及更早自带通常在Keil_v5\ARM\ARMCC先跑armcc --vsnbuild 不是 960 再考虑补装5.37 及以后不带只有 AC6必须装这个 MSI并在 uVision 里手动注册路径只做命令行构建与 MDK 无关只装 MSI把bin加进 PATH 即可AC5、AC6 工程并存视情况两套编译器分目录存放靠工程里的编译器选择区分2.2 装前检查旧 ARMCC 目录、TOOLS.INI 和权限装之前有三件事要先做都是出过一次问题之后才养成习惯的。第一是看机器上有没有旧的 AC5 目录有的话先记下版本避免装完两个版本混着用第二是备份TOOLS.INIuVision 把编译器路径记在这个文件里改坏了要么启动报错、要么所有工程都找不到编译器第三是确认自己有管理员权限MSI 默认往Program Files (x86)写并登记注册表权限不够会直接以 1603 之类的错误码退出。# 1) 看 Keil 安装目录下现有的编译器目录有哪些 Get-ChildItem C:\Keil_v5\ARM -Directory -ErrorAction SilentlyContinue # 2) 如果自带 AC5 存在先记下它当前是哪个 build C:\Keil_v5\ARM\ARMCC\bin\armcc.exe --vsn # 3) 备份 TOOLS.INI改坏了能原样还原 Copy-Item C:\Keil_v5\TOOLS.INI C:\Keil_v5\TOOLS.INI.bak -Force第一行的作用是确认有没有“自带的那份”输出里出现ARMCC就说明是老版本 MDK第二行只有在前一步找到了目录时才有意义--vsn是 armcc 查版本的固定参数选项卡里看不到的构建号全靠它。第三行的备份是应急措施TOOLS.INI是个纯文本文件uVision 会在你添加自定义编译器时往里写路径手改或者写错一个引号整个 IDE 的编译器列表就乱了。备份文件放同目录、加.bak后缀就行还原时直接覆盖回去。2.3 安装路径怎么定别带空格更别带中文MSI 默认装到C:\Program Files (x86)\ARM\ARM_Compiler_5.06u6这个路径本身带空格和括号。大多数情况下它能正常工作因为 Keil 内部调用时会自己加引号但一旦你把工程放进带空格或中文的目录再配合命令行脚本构建就会开始出现一些难以理解的报错。我一般会把工具链装到一个短路径下比如D:\Toolchain\ARMCC506工程目录也保持全英文、无空格。这不是过度谨慎。AC5 的构建链路里armcc 负责编译armlink 负责链接fromelf 负责把 axf 转 bin三个进程之间靠命令行参数传递文件路径中间任何一层对空格的处理不一致报出来的错误都不是“路径有问题”而是cannot open source input file这类看起来像头文件缺失的提示。第一次遇到这种提示时我花了很久去查 include 路径最后发现是输出路径里的空格导致的。这也是“后悔药”要提前备好的原因。3. 安装 ARMCC 5.06(960)图形安装、静默安装与便携解包真正点安装只要几分钟麻烦的是安装前后的准备和检查。这一章把三种装法都写清楚图形界面装一台机器、静默参数批量装多台、管理安装解包成绿色工具链。你可以根据手上是单机还是机房环境选择。3.1 图形化安装一路下一步但两处要看清楚双击 MSI前面几步都是常规的许可协议和组件确认中间会有一个安装路径页默认就是C:\Program Files (x86)\ARM\ARM_Compiler_5.06u6。如果按 2.3 的建议改路径就在这一页改改完记下来后面挂进 Keil 要用。最后一页点 Install等进度条走完。装完之后先看目录结构确认文件齐全。AC5 的安装目录是固定布局缺了任何一个子目录都说明安装不完整路径内容bin\armcc.exeC/C 编译器驱动也是最常用来查版本的可执行文件bin\armasm.exe汇编器启动文件.s走它bin\armlink.exe链接器输出 axf 和 mapbin\fromelf.exe镜像转换axf 转 bin、hex、反汇编bin\armar.exe静态库打包include\C 库头文件stdio.h、string.h这些lib\运行时库--cpu不同会挑不同的.abin目录是整个工具链的关键入口后面无论是 Keil 里注册路径还是命令行加 PATH指的都是它不是它的上一层也不是某个 exe 文件。3.2 静默安装与解包msiexec 的几种用法要给多台机器装或者写进部署脚本就得用 msiexec 的静默参数。最常用的一条是/qn全程无界面配合/norestart防止安装完自动重启打断别的任务再加/l*v把详细日志写出来出问题时日志是唯一的线索。MSI 的报错界面经常只给一个错误码真正的失败原因都在日志里。# 静默安装无界面、不重启、输出详细日志 msiexec /i D:\pkg\ARMCompiler_506_Windows_x86_b960.msi /qn /norestart /l*v D:\pkg\ac5_install.log # 安装完成后立刻回看日志末尾有 1603 之类的错误码就在这里 Get-Content D:\pkg\ac5_install.log -Tail 40/i表示安装后面跟 MSI 的完整路径路径有空格时引号不能省。/qn是完全没有用户界面适合脚本如果这是你第一次装、想看着它走完/qb会显示一个基本的进度条比/qn好排查。/l*v是日志级别v表示最详细日志会包含每个组件、每个目录的写入动作。想改安装目录就在/qn后面加属性赋值比如INSTALLDIRD:\Toolchain\ARMCC506。但不同厂商的 MSI 用的目录属性名不一样常见的有INSTALLDIR、APPDIR、TARGETDIR写错了不会报错、只会被忽略然后照默认路径装。稳妥的做法是用 Orca 这类工具打开 MSI看 Property 表和 Directory 表里到底是哪个属性名再照着写。还有一种做法是管理安装也叫解包。它不执行真正的安装流程只是把 MSI 里的文件铺到一个目录下# 管理安装只解包不写注册表得到一份可直接拷贝的工具链 msiexec /a D:\pkg\ARMCompiler_506_Windows_x86_b960.msi /qb TARGETDIRD:\Toolchain\ARMCC506/a就是管理安装开关TARGETDIR指定解包落点。解出来的目录结构和正常安装完全一致bin、include、lib都在。这种做法的好处是便携拷到没有安装权限的机器上Keil 里照样能把编译器路径指过去坏处是注册表没写某些依赖注册表查询的工具认不到它。做 CI 构建机或者临时验证环境时我更倾向用解包不污染系统。3.3 装完第一件事用 armcc --vsn 对版本不管用哪种方式装的装完都别急着开 Keil。先直接在命令行敲一次版本查询确认落地的确实是 b960 这个构建。# 直接调绝对路径避免 PATH 里还有别的 armcc 干扰 C:\Program Files (x86)\ARM\ARM_Compiler_5.06u6\bin\armcc.exe --vsn期望看到的输出大致是这么三行Product: ARM Compiler 5.06 Component: ARM Compiler 5.06 update 6 (build 960) Tool: armcc看的就是第二行的update 6 (build 960)。如果这里显示的是update 5或者更早的构建号说明你调用的是机器上另一个 armcc而不是刚装的这个——这在之前装过 MDK 自带 AC5 的机器上很常见因为 PATH 里可能已经有旧路径。用绝对路径调用就是为了排除这种干扰。这一步看起来多余但它能把后面两类问题提前挡掉一类是安装包本身没装完整另一类是系统里存在多个 armcc 互相抢占。如果在这一步就发现版本不对后面的 Keil 配置全都不用做了。3.4 PATH 怎么加先临时验证再持久化命令行构建、脚本构建都要求armcc能被直接找到所以要把它加进 PATH。但加 PATH 这件事本身也有风险setx在旧版本 Windows 上对超过 1024 字符的 PATH 会截断一旦截断系统里其他工具的命令就全找不到了。# 第一步只在当前会话里临时加先确认能用 $env:Path D:\Toolchain\ARMCC506\bin; $env:Path armcc --vsn # 第二步确认没问题后先把当前用户 PATH 导出备份一份 [Environment]::GetEnvironmentVariable(Path, User) | Out-File D:\pkg\path_user_bak.txt # 第三步追加而不是覆盖注意保留原有内容 $old [Environment]::GetEnvironmentVariable(Path, User) [Environment]::SetEnvironmentVariable(Path, D:\Toolchain\ARMCC506\bin; $old, User)第一步改的是进程级环境变量关掉窗口就失效适合做验证。第二步导出的是用户级 PATH出事能照着文本还原。第三步用User作用域而不是Machine避免影响整机其他账户也避开了管理员权限要求。提示不要用setx PATH %PATH%;新路径这种写法。它会把系统 PATH 和用户 PATH 合并后写回用户变量长期下来 PATH 越来越长迟早撞上长度限制。4. 把 AC5 接进 Keil编译器路径、Target 参数与命令行三件套MSI 装完只是把文件放到了磁盘上Keil 并不知道它的存在。这一章做两件事让 uVision 认识这份编译器以及让工程和命令行都用对参数。前者是界面操作后者是参数取舍两边都要对构建结果才可控。4.1 在 Folders/Extensions 里注册自定义编译器路径新版 uVision 允许注册多个编译器版本入口在项目管理对话框里。步骤是固定的打开 uVision菜单Project → Manage → Project Items切到Folders/Extensions页签下半部分有一个 ARM Compiler 区域下拉里除了已有的版本还有一条类似Add another ARM Compiler Version to List...的选项。选中它弹出目录选择框把路径指到bin目录。这里的路径精度是关键要指到...\ARM_Compiler_5.06u6\bin不能指到上一层...\ARM_Compiler_5.06u6也不能指到bin\armcc.exe这个文件本身。指错了不会立刻报错只是 Target 页的下拉里仍然看不到 version 5很容易让人以为安装失败了。注册成功后uVision 会把这条路径写进安装根目录的TOOLS.INI。文件里大致是这样一段结构示意实际内容以工具自己写入的为准[UV2] ORGANIZATION... NAME... EMAIL... [ARM] PATHD:\Toolchain\ARMCC506\bin[ARM]段的PATH就是编译器入口。这个文件不要手改尤其是不要手动往里塞多条路径去“试试看”写乱了 uVision 可能直接找不到任何编译器。真要改先按 2.2 备份。4.2 Target 选项与 C/C 参数从 AC6 切回 AC5 要清干净路径注册好之后回到Options for Target → Target页ARM Compiler 下拉里应该能看到 version 5 了选它。然后重点检查 C/C 页这里是从 AC6 工程切回 AC5 时最容易出错的地方。AC6 是 armclang走的是一套 GNU 风格的选项AC5 是 armcc只认自己那套。如果你把 AC6 工程的 Misc Controls 原样留着里面会有-fno-common、-Wno-...、-stdgnu11这类参数AC5 一个都不认编译第一步就报Error: C3900U: Unrecognized option。正确做法是把 Misc Controls 清空再按需一条条加回去。参数作用常用写法注意--cpu指定目标内核--cpuCortex-M3编译、汇编、链接三处必须一致--c99打开 C99 支持--c99AC5 默认偏 C90老代码不开会报变量声明位置错-O0/-O2优化等级调试-O0发布-O2-O3在部分老库上会触发内联问题-g生成调试信息配合-O0只开-g不开-O0单步会跳--apcsinterworkARM/Thumb 互调一般默认就带手工改链接脚本时留意--split_sections每个函数单独成段配合链接期--remove明显减小 Flash 占用--diag_suppress屏蔽指定编号告警如--diag_suppress1295按编号屏蔽别一把全关除参数之外还有两处常见设置Output 页勾上Create HEX File方便烧录Linker 页如果用的是 Target 对话框里的内存布局就保持Use Memory Layout from Target Dialog如果工程自带.sct分发文件就切到手动指定并填对路径。4.3 命令行三件套armcc、armlink、fromelfKeil 图形界面背后调的就是这三条命令把它们的参数搞明白出问题时才能自己复现和定位。顺序也是固定的先编译成.o再链接成.axf最后转成.bin或者.hex。# 编译只编译不链接输出目标文件 armcc --cpuCortex-M3 -c --c99 -O2 -g -I ./inc -D BOARD_V1 -o build/main.o src/main.c # 链接指定分散加载文件打印尺寸信息并生成 map armlink --cpuCortex-M3 build/main.o build/startup.o --scatterapp.sct --infosizes --map --outputbuild/app.axf # 转换从 axf 里导出纯二进制镜像 fromelf --bin --outputbuild/app.bin build/app.axf-c是只编译不链接缺了它 armcc 会尝试自己完成链接。-I后面跟头文件搜索目录可以写多次-D是宏定义等价于源码里#define BOARD_V1。-o指定输出文件目录不存在时不会自动创建所以build目录要先建好。armlink 这一条里--scatter指定分散加载文件决定代码和数据放在哪块 Flash、哪块 RAM--infosizes会在链接结束时打印各段大小这是判断镜像有没有超容量最直接的方式--map生成 map 文件后面验证版本要靠它。--cpu必须和编译时写的一致不一致会出现“同一份代码编出来的东西链接不上”这种非常难查的问题。fromelf 是镜像转换工具--bin表示输出裸二进制--output指定落点。如果是要给烧录工具用的 hex就把--bin换成--i32或对应格式。4.4 AC5 与 AC6 参数对照迁移时对着这张表改手上如果有两套工程一套 AC5 一套 AC6来回切的时候对照这张表改比照着报错一条条试要快得多。功能AC5armccAC6armclang编译器驱动armccarmclang指定内核--cpuCortex-M4--targetarm-arm-none-eabi -mcpucortex-m4C 标准--c99-stdc99优化-O2-O2宏定义-D-D头文件路径-I-I弱符号__weak__attribute__((weak))字节对齐打包__packed、__align(n)__attribute__((packed))、__attribute__((aligned(n)))链接器armlinkarmlink参数大体通用镜像转换fromelffromelf参数大体通用表里最需要注意的是关键字那一栏。AC5 提供了一批以双下划线开头的扩展关键字__weak、__packed、__align、__irq这些写起来干净但只有 armcc 认。AC6 走 GNU 的__attribute__语法同一份源码在两边切换时必须改。这也是老工程不能顺手迁到 AC6的核心原因之一不是编不过是要改的源码位置太分散。5. 排查AC5 装完之后最常翻车的五件事下面五条是这套环境里出现频率最高的问题按“看到什么现象、为什么、怎么解”的顺序记。有些问题看着像安装失败实际是配置差一层有些看着像代码问题实际是版本问题。5.1 Target 下拉里始终没有 version 5现象Options for Target → Target页的 ARM Compiler 下拉里只有 version 6或者只有一条 default反复重装 MSI 也没变化。原因MDK 5.37 之后本来就不带 AC5下拉框里的条目来自两个地方——安装包自带以及用户在Folders/Extensions里手动注册的路径。如果注册时把路径指到了bin的上一层或者armcc.exe文件本身uVision 校验时找不到编译器入口就不会把这条加进下拉。解决重新走一遍Project → Manage → Project Items → Folders/Extensions路径精确到bin目录。添加完把 uVision 完全关闭再打开让它重新读一次TOOLS.INI。如果还不行打开TOOLS.INI看[ARM]段的PATH有没有被正确写入没有就还原 2.2 的备份重来。5.2 链接报 L6050U 代码超限现象编译都正常到链接这一步报Error: L6050U: The code size of this image exceeds the maximum allowed for this version of the linker.原因这是评估版 32KB 代码限制的提示跟 AC5 本身没关系。编译器装得对不对是一回事能不能产出超过 32KB 的镜像由 Keil 那边的授权状态决定。AC5 单独安装不会改变这个限制。解决先确认授权状态是否正常检查是不是在换机器、重装系统之后授权没跟上。临时验证代码是否真的超标可以打开-O2并加上--split_sections链接时配合--remove裁掉未引用段看尺寸是否刚好卡在边界附近。如果裁完仍然超那就是工程本身规模问题不是配置问题。5.3 cannot open source input file现象编译报Error: #5: cannot open source input file xxx.h: No such file or directory但你确认过这个文件就在工程目录里。原因三种可能——头文件目录没加到Include Paths加了但路径里带空格没有正确引用工程从别的机器拷过来路径是绝对路径指向了原机器的目录。解决在 C/C 页的Include Paths里逐条补齐尽量用相对工程根目录的写法。命令行构建时对应的是-I参数路径带空格要加引号。另外养成一个习惯路径里不要出现中文和空格这一条能挡掉后面一大半难以理解的报错。5.4 一堆 C3900U 和语法错误现象从 AC6 工程切回 AC5 之后编译一开始就滚出一串Error: C3900U: Unrecognized option或者源码里报__attribute__相关的语法错误。原因AC5 不认 armclang 的选项也不认 GNU 的__attribute__扩展写法。工程里的 Misc Controls 和源码关键字都是按 AC6 写的切回 AC5 就全部失效。解决把 Misc Controls 清空再一条条按需要加回 AC5 认的参数源码里的__attribute__((packed))、__attribute__((weak))、__attribute__((aligned(n)))分别替换成__packed、__weak、__align(n)。替换时注意这类关键字往往出现在启动文件、外设寄存器定义和中断处理函数里改完要重新编译全部文件不能只做增量编译。5.5 装完 Keil 打不开或者所有工程都找不到编译器现象打开 uVision 弹窗提示找不到工具链或者干脆启动即退出已存在的工程全部报编译器缺失。原因TOOLS.INI被写入了一条无效路径或者安装目录被手动移动过、文件不全。uVision 启动时会读这个文件路径指向一个不存在的目录就会把整条编译器记录判为失效。解决先用 2.2 备份的TOOLS.INI.bak覆盖回去确认 IDE 能正常启动然后把 MSI 重新装一遍到确认无误的路径进目录看bin下armcc.exe、armasm.exe、armlink.exe、fromelf.exe四个文件是否齐全缺任何一个就重装不要试图手工补文件。6. 装完怎么验证三条命令确认 b960 真的在干活到这一步文件装了、路径注册了、参数也配了但“配了”和“生效了”是两件事。我见过不止一次Keil 里下拉框显示 version 5实际调用的却是另一个目录里的旧版 armcc编出来的东西和预期不一样查了半天才发现是路径问题。所以每次装完我都会强制走完下面三条验证全通过才动真实工程。第一条命令行直接查版本armcc --vsn期望输出里Component那一行是ARM Compiler 5.06 update 6 (build 960)。如果 PATH 里还有别的 armcc就先去掉 PATH 再查一次或者用绝对路径调用确认版本来源唯一。第二条命令行完整走一遍编译和链接# 最小验证文件内容只有一行空的 main echo int main(void){return 0;} hello.c armcc --cpuCortex-M3 -c --c99 -O0 -g -o hello.o hello.c armlink --cpuCortex-M3 hello.o --infosizes --map --outputhello.axf第一步验证 armcc 能正常启动并产出目标文件第二步验证 armlink 能正常链接并打印尺寸。因为没有启动文件和入口链接期会提示没有入口点的警告这条在验证阶段可以忽略重点看它有没有跑完、有没有生成hello.axf和hello.map。第三条在 Keil 里本文还有配套的精品资源点击获取