ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

解决Keil编译报错:安装ARM Compiler 5.06并切换AC5工具链

解决Keil编译报错:安装ARM Compiler 5.06并切换AC5工具链 简介Keil ARM Compiler v5.06 build 960 是一份完整的 ARMCC v5 编译器安装包面向 STM32 等 ARM Cortex-M 嵌入式开发者用于解决新版 Keil MDK 默认 AC6 编译器对旧工程不兼容、导致编译失败或行为改变的问题。压缩包共 4 个文件总大小约 79.63MB内含 MSI 安装程序、EXE 引导程序、HTML 更新说明和 Markdown 使用文档说明文档覆盖从解压、安装到在 Keil MDK 中注册 ARMCC 并切换编译器的完整流程操作指引清晰能有效减少配置摸索时间。目前该资源已有 1219 人学习下载适合需要维护老项目、依赖 ARMCC v5 编译特性如特定优化选项、语法兼容的工程师及在校学生。实际工程中不少第三方库与启动文件仍按 AC5 编写在 AC6 下会频繁告警通过这套包体可快速恢复 ARM Compiler v5 环境统一构建工具链降低因编译器版本差异带来的重复调试成本。 最近群里有好几个做嵌入式的老哥都在问同一个问题手里的 Keil 工程在新电脑上编译不过去一编译就提示Registered ARM Compiler ignored, version needs to be 5 or higher。我一看基本就知道怎么回事——新版 MDK 默认装的是 AC6 编译器而老工程当年是用 ARM Compiler 5.06也就是 armcc写的。对于这些跑了几年、改动都很克制的固件最稳妥的办法就是把 ARM Compiler 5.06 Update 7Build 960装回去。这篇文章就围绕这个版本展开聊聊它到底是什么、怎么装、怎么切以及我在这条路上踩过的坑。1. ARM Compiler 5.06 到底是什么为什么老项目离不开它1.1 版本背景与定位ARM Compiler 5.06 是 ARM 官方在 AC5 时代的最后一个主力版本线Build 960 对应的是 Update 7这个编号在 Keil MDK 的编译器列表里通常会显示为V5.06 update 7 (build 960)。和后面的 AC6armclang相比AC5 的编译器本体是 armcc配套的还有 armasm、armlink、fromelf 这几个工具它们共同构成了一套完整的老牌工具链。为什么说它“老牌”因为从 ARM7/ARM9 时代到 Cortex-M 全面普及很长一段时间里 AC5 都是 Keil MDK 的默认编译器。不少企业级固件、开源 SDK、芯片原厂的标准外设库都是基于 AC5 验证过的。你去看那些老工程的编译日志命令里写的基本都是 armcc链接用的是 armlink。AC5 对旧代码的兼容性好到让人无感代码里写__asm、__forceinline、#pragma O3这类东西都能直接用这在 AC6 里就未必了。1.2 这些场景必须用 AC5 而不是 AC6老工程用的是标准外设库SPL或者老版本 CMSIS。这些库是按 armcc 的语法习惯写的里面大量使用__attribute__、__inline等关键字AC6 虽然可以用兼容模式但编译时常常会出现 “attribute ignored” 之类的警告甚至直接报错。启动文件是 ARM 汇编语法。老工程的startup_xxx.s往往用PRESERVE8、AREA、EXPORT这套 UAL 语法AC5 的 armasm 能正确处理。换到 AC6 后默认的汇编器变成了 armclang 集成的 GNU 汇编器很多写法直接不识别。代码里有内联汇编。比如关中断、开中断老写法是__asm { CPSID i }这种AC5 支持得很好AC6 虽然也支持__asm但具体书写格式和寄存器约束差异很大迁移工作量不小。固化库只有 AC5 版。有些加密库、协议栈原厂只提供 AC5 的.lib切到 AC6 后链接阶段直接找不到符号这种是最无奈的只能保留 AC5 环境。1.3 AC5 与 AC6 的关键差异速览对比项AC5armccAC6armclang编译器本体armccarmclang汇编器armasmarmclang 内置汇编器内联汇编__asm { ... }__asm(...)或过程内汇编关键字__forceinline、__align更贴近 GCC 的__attribute__体系优化策略保守稳定-O2/-O3下代码更小更快但行为可能有差异标准支持C99/C90C11/C17 更好调试信息DWARF 旧版DWARF 4/5这里想多说一句AC6 并不是不能用来编译老工程只是“默认行为”相差太大。AC6 对代码的审查更严格对未定义行为更敏感同样的代码在 AC5 下编译是零警告在 AC6 下可能会被警告刷屏。如果你只是想让老项目继续稳定发货没必要在这个节骨眼上冒险切 AC6先装回 AC5 把问题解决掉才是成本最低的方案。2. 安装与注册让 Build 960 出现在 MDK 里2.1 官方 pack 安装步骤新版 MDK5.37 以后默认不再自动安装 AC5 编译器所以即使你装了最新 MDK也看不到 V5.06。安装方式其实并不复杂直接在 MDK 的 Pack Installer 里操作就行打开 Keil µVision菜单栏选择 Project - Manage - Pack Installer。在 Pack Installer 左侧的 Packs 树里找到 ARM 厂商下的 “ARM Compiler”展开后能看到ARM Compiler 5.06 update 7 (build 960)这个条目。点击 Install等待下载安装完成。如果网络环境不好也可以去官网下载ARM.Compiler.5.06u7.pack文件然后双击安装。装完之后回到工程界面按 AltF7 打开 Options for Target在 Target 标签页里找到 “ARM Compiler” 下拉框正常情况下就能看到V5.06 update 7 (build 960)这个选项了。这一步就搞定了“编译器不存在”的问题。2.2 校验安装结果为了防止装错版本我建议安装后先确认一下 armcc 是否存在。打开命令行进入 MDK 安装目录的ARM\ARMCC\bin执行armcc --vsn注意这里有个细节有些朋友会以为装完 5.06 之后armcc 会出现在ARM\ARMCLANG\bin下其实不是。AC5 的工具链默认安装在ARM\ARMCC目录AC6 才在ARM\ARMCLANG。如果你在 ARMCLANG\bin 里找不到 armcc那是对的不用怀疑。正常的输出大概是Product: ARM Compiler 5.06 update 7 (build 960) Component: ARM Compiler 5.06 update 7 (build 960) Tool: armcc [4d3804]看到 Product 信息里的版本号确实对应 Build 960就说明安装到位了。顺带可以执行armlink --vsn、armasm --vsn确认一下配套工具版本避免出现编译器和一个不匹配的链接器混用的情况。2.3 为什么会出现 “Registered ARM Compiler ignored”这个警告几乎每个从 AC6 切回 AC5 的人都遇到过它翻译过来是“已注册的 ARM 编译器被忽略版本需要是 5 或更高。” 第一次看到这个提示会让人摸不着头脑其实原因很简单MDK 里可能注册了多个编译器但当前工程在 Options for Target 里指定的编译器要么不是 AC5要么 MDK 检测不到。解决办法分两步。第一步在 Options for Target - Target 里把编译器明确选成V5.06 update 7 (build 960)。第二步如果下拉框是灰色不可选的多半是工程从旧版本升级上来的需要在 Project - Manage - Project Items - Folders/Extensions 里把默认编译器版本设置成 “Use default compiler version 5”然后再回到工程设置里切换。还有一种情况比较隐蔽你把 AC5 和 AC6 都装了工程设置里也没问题但 MDK 在命令行里实际调用的还是 AC6 的 armcc。这时候要先清理一次工程删除 Output 和 Listings 目录下的旧文件再重新编译。老项目里编译中间文件目录可能有残留会干扰 MDK 的工具链判定。3. 工程切换与代码适配3.1 工程级编译器选择切编译器本身不是难事但要注意不能光改编译器版本编译选项也要跟着改。比如在 Options for Target - C/C 标签页里AC5 的常见写法是--c99 --gnu -O2 --apcsinterwork --split_sections这些选项在 AC6 里是不认的。如果你从 AC6 切回 AC5建议把 C/C 里填写的选项清空重新按 AC5 的格式写避免一堆 “unknown option” 警告。我通常的习惯是在 AC5 下用--gnu开启 GNU 扩展这样对老代码里常见的宏和语法更友好用--split_sections可以生成更细粒度的节配合链接器的--remove选项能有效减小最终固件体积。编译优化等级一般默认-O2就行如果遇到某些函数行为异常再逐个函数降到-O1排查。3.2 老代码适配 AC5 的兼容处理大部分人从 AC6 切回 AC5 其实不会遇到太多代码改动但有些情况还是要注意头文件路径要检查。老工程里可能用$KEIL$或相对路径引用了 CMSIS、标准外设库这些路径在切换编译器后如果找不到会直接报 “No such file or directory”优先检查 C/C 里的 Include Paths。宏定义清理。AC6 会识别__ARMCC_VERSION、__clang__等宏AC5 的宏体系不一样。如果代码里有“根据编译器选择函数实现”的逻辑比如#if defined(__clang__) (__ARMCC_VERSION 6000000) // AC6 分支 #else // AC5 分支 #endif这种逻辑不用改但要确保用的是正确的宏否则老代码会走进 AC6 分支编译出问题。汇编文件。如果你手头的启动文件是 AC5 时代的切回 AC5 后一般不用改但如果一开始已经被 AC6 覆盖成新语法了要换回旧版启动文件。最简单的方式是从原厂 SDK 里重新拷贝一份匹配的 startup 文件。3.3 编译选项差异与配置建议AC5 和 AC6 在编译选项上有本质区别因为一个是 armcc 语法一个是 Clang 语法。下面这张对比表能帮你快速判断哪里该改目的AC5 写法AC6 写法支持 C99--c99-stdc99支持 GNU 扩展--gnu-stdgnu11生成独立节--split_sections-ffunction-sections -fdata-sections链接移除未用节--remove在 armlink-Wl,--gc-sections优化等级-O0/-O1/-O2/-O3-O0/-O1/-O2/-O3/-Oz编译诊断信息--diag_errorxxx-Werrorxxx从表格里能看到很多功能在 AC5 和 AC6 里都能实现只是参数名不一样。如果你是从 AC6 的例子工程复制过来的编译选项直接切回 AC5 后大概率会报 unknown option。所以我的建议是不要从网上随便抄一份选项贴进去先把你当前这个工程需要什么弄清楚再动手。4. 常见报错与排查实录4.1 高频报错速查表报错信息可能原因解决方案Registered ARM Compiler ignored, version needs to be 5 or higher当前工程指定了 AC5但 MDK 未安装或未注册 AC5用 Pack Installer 安装 ARM Compiler 5.06并在 Options 中切到 V5.06CreateProcess failed, command: ...armclang...armcc.exe编译器路径配置混乱或工程实际调用了 AC6 的 armcc重新指定编译器版本清理编译中间目录后再编译Target uses ARM-Compiler but there is no ARM-Compiler installedMDK 安装了 AC6但没有安装 AC5按第 2 章步骤安装 AC5 编译器Error: L6218E: Undefined symbol链接阶段缺少符号可能是固化库用 AC5工程切到了 AC6确认库里编译工具链把工程编译器切回 AC5Fatal error: C0000: code generation failed编译器异常可能是选项冲突或安装损坏检查编译器版本、清理中间文件必要时重装 AC54.2 一次真实的老工程迁移过程我之前接手过一个蓝牙网关项目固件是 STM32F1 标准外设库写的老同事用的 MDK 5.23 AC5。换到我这边的新电脑后装的是最新 MDK默认编译器是 AC6一编译就是上百条错误绝大多数集中在启动文件和标准外设库里。我没有去逐条改代码而是先切回 V5.06 update 7然后清理了 Output 目录重新编译结果一条错误都没出只花了两分钟。那次经历让我印象很深老代码不是不能在新环境里编译很多时候只是“编译器没选对”。当你接手一个老项目时第一件事永远是确认它原来的工具链版本而不是用新版编译器去硬扛。标准外设库这种老代码在 AC6 下不是不能改但为了一次发货没必要去动那些已经稳定的底层。4.3 避坑心得与工具链管理建议几个我长期用下来的经验分享出来可以省掉不少折腾时间不同 MDK 版本尽量固定编译器版本不要把 AC5、AC6 多个版本全装一起还要来回切换。虽然 MDK 支持多编译器共存但工程设置、路径、宏定义很容易混乱。老项目先在“原始工具链版本”下确认能编译再考虑升级。不要一上来就把编译器升到 AC6至少先跑通再评估迁移。编译选项要跟着编译器走不要从别人的例程里直接复制。AC5 和 AC6 的参数体系完全不同最容易踩的就是这个坑。遇到奇怪的编译错误先删除 Output、Listings 目录再重新 Build有时候中间文件的残留会掩盖真实的问题。5. 写在最后我的个人习惯我在实际维护过程中养成了一个习惯凡是要碰老项目先看 README 或工程文件里记录的 MDK 版本和编译器版本。只要确认是 AC5 工程就直接把 ARM Compiler 5.06 update 7 (build 960) 装好全局默认编译器也设成 V5.06省得每次打开工程都弹警告。AC6 对新项目、新芯片确实是趋势代码密度和优化效果都比 AC5 有优势但对于那些跑得好好的老固件稳定压倒一切。先把这个版本装对再想着迁移才不会让一件十分钟的事变成一整天的事。本文还有配套的精品资源点击获取
返回列表