ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

KEIL MDK手动安装ARM Compiler 5 (AC5)解决编译报错完整指南

KEIL MDK手动安装ARM Compiler 5 (AC5)解决编译报错完整指南 1. 从一次AC5缺失报错说起问题到底出在哪1.1 报错现场全景复盘大概每隔一两个月我所在的嵌入式交流群里就会出现一次“求帮忙看看编译错误”的求助截图往往是这样的*** Target Target 1 uses ARM-Compiler and there is no ARM compiler installed ***或者直接来一句error: C9555E: Failed to check out license第一次遇到的人基本都会懵明明工程文件都在器件包也装好了头文件路径也没问题怎么突然跟编译器较上劲了更奇怪的是同一个工程在同事电脑上编译得好好的换到自己刚装好的MDK上就报错。如果你也是这种情况基本可以断定你的KEIL MDK里缺了ARM Compiler 5也就是我们常说的AC5。这里先帮大家把问题定位清楚AC5缺失不是代码问题不是仿真器问题也不是许可证问题纯粹是安装阶段少了一个组件。只要你用的是5.36之后的新版MDK并且安装时没有特意去勾选旧编译器支持那么MDK只带ARM Compiler 6AC6AC5并不会自动出现。而很多时间比较久的工程尤其是用了STM32标准库、老版CMSIS或者一些第三方SDK的工程编译链默认还是AC5于是就有了上面那一幕。1.2 新版本MDK的编译器“分家”逻辑要弄明白为什么AC5会被“抛弃”得先理解KEIL MDK从5.36版本开始的一个大变化官方把默认编译器从ARM Compiler 5换成了ARM Compiler 6。AC6是基于LLVM的armclang编译速度快、对C11/C11支持好代码体积和优化都有优势Arm官方也一直在推动生态迁移。但问题是老工程并不买账。AC6和AC5在语法层面有不少差异比如AC5允许使用__irq、__asm这类关键字AC6需要用__attribute__((interrupt(IRQ)))或__asm volatile替代。AC5的GNU风格内联汇编和AC6的armclang内联汇编规则不同。某些老版本库内部用的编译器特殊选项在AC6下面根本编不过去。所以Arm官方也意识到不能一刀切。于是从MDK 5.36开始安装包里默认只装AC6但官方依然保留了AC5的独立下载通道。也就是说AC5并不是“没了”只是不再默认安装。你完全可以在MDK 5.36、5.37、5.38甚至5.39上手动把AC5补回去新旧编译器共存互不干扰。1.3 为什么很多老工程离不开AC5我知道有人会说早晚都要迁移到AC6何必抱着AC5不放现实是很多商业项目、科研代码、杂牌芯片SDK并没有跟上新编译器的节奏。我见过一个量产产品的工程用了好几年的STM32标准库里面有不少__asm内联汇编和__irq中断函数拿到AC6下面一编译就是几十个error。客户不可能为了换个编译器去重写整个底层所以最保守的做法就是在新版MDK上继续用AC5。另外AC5和AC6生成的代码行为在某些细节上有差异。比如浮点ABI、结构体对齐规则、volatile访问的优化策略可能导致老程序在新编译器下出现诡异的时序问题。对于稳定运行的产品升级工具链的收益远远小于风险。这也是我在自己的电脑上始终保留AC5的原因——不是守旧而是实用主义。2. 手工添加AC5之前先弄清楚版本来源2.1 AC5的官方获取路径既然要手动添加第一步当然是拿到AC5的安装文件。这里严肃提醒一句千万别去网上搜什么“5.36网盘版”“AC5绿色版”之类的东西。一方面安全性无法保证编译器被植入恶意代码你的固件、源码、甚至电脑都会有风险另一方面MDK本身是商业软件官方提供了正版许可和评估模式没必要冒这个险。官方获取AC5的路径并不难找我走一遍下来是这样的打开Arm Keil官网developer.arm.com/downloads。找到“MDK-ARM”或者“MDK”产品下载页面。在下载列表里寻找一个叫ARM Compiler 5.06 Update 7或Legacy ARM Compiler 5的独立包完整文件名类似ARMCompiler_5.06u7_Windows.zip。这个包的大小一般在一百多兆里面就是AC5完整的编译工具链。需要注意我的经验是官网偶尔会调整下载页面结构如果你一时找不到可以直接在站内搜索“ARM Compiler 5.06”或者在MDK的Pack Installer里看看有没有“Legacy Support”包可以勾选。但最直接的方法还是下载独立包自己手动放置。2.2 如何确认你需要的AC5版本号AC5的最后一个正式版本就是5.06 Update 7发布于多年前。所以对于绝大多数用户来说不用纠结到底下载5.05还是5.06直接用5.06u7就是最稳的选择。它修复了旧版本的一些已知问题支持绝大多数ARM Cortex-M/R/A内核是我推荐的首选。不过也要注意少数芯片厂商的老SDK文档里会特别指定要使用某个具体版本比如“ARM Compiler 5.04”或“5.05”。这种情况多见于非常古老的ST/ NXP早期代码包。你可以先按厂商要求下载对应版本如果找不到历史版本再退回5.06u7试试。从我的实际经验看5.06u7向下兼容性很好绝大多数标称老版本编译器的工程都能正常编过顶多有一些语法警告。2.3 下载后文件结构长什么样解压下载好的ARMCompiler_5.06u7_Windows.zip你会看到一个名为ARMCC的文件夹。这个文件夹里面的结构大概是这样ARMCC/ ├── bin/ ├── data/ ├── doc/ ├── examples/ ├── include/ ├── lib/ └── sw/bin目录下能看到armcc.exe、armlink.exe、fromelf.exe等一系列可执行文件这就是AC5的核心。include和lib分别是头文件和运行库data里则有芯片相关的描述文件。搞清楚结构很重要因为后面你要把这个文件夹放到MDK的特定位置MDK才能识别。如果放错层级MDK在扫描编译器时就会找不到ARMCC/bin/armcc.exe结果还是提示AC5缺失。3. 手动安装AC5的完整操作流程3.1 把编译器文件放到指定目录这一步的核心就是让MDK能按约定路径找到AC5。MDK安装完成后根目录下会有一个ARM文件夹例如C:\Keil_v5\ARM。正常情况下这个ARM目录下会存在ARMCC、ARMCLANG、CMSIS、Packs等子目录。其中ARMCLANG就是AC6的安装位置ARMCC则是在你手动添加AC5后才会出现。操作方法非常简单把解压出来的ARMCC文件夹整个复制到C:\Keil_v5\ARM\目录下。最终路径应该是这样C:\Keil_v5\ARM\ARMCC\bin\armcc.exe复制完成后建议顺手验证一下路径里不要有中文、不要带空格。如果你的MDK装在D:\Program Files\Keil_v5这种带空格的路径可能会引发后面Make工具找不到编译器的问题。最省心的方案是安装MDK时就直接使用C:\Keil_v5或D:\Keil_v5这样简洁的路径。3.2 在MDK里注册编译器让软件“看到”AC5放好ARMCC文件夹后打开你的MDK工程接下来有两个地方可以验证或添加编译器我的习惯是先去“项目管理器”里处理。点击菜单栏的Project-Manage-Project Items在弹出的窗口底部会有一个Folders/Extensions按钮点进去你会发现一个编译器列表。这里通常会显示MDK自动扫描到的已安装编译器例如ARM Compiler 6.16。如果你把ARMCC文件夹放对了路径MDK启动时会自动扫描到新增的AC5并显示在列表里。如果列表里仍然只有AC6不用慌可以手动添加。回到Project Items窗口看Folders/Extensions里的内容在编译器选择区域有类似Add another ARM Compiler Version的按钮点击后浏览到C:\Keil_v5\ARM\ARMCC目录确认即可。添加后列表里会出现ARM Compiler 5.06 Update 7这样的选项。这里有个小细节有些MDK版本在添加编译器时会要求你选择到包含armcc.exe的bin目录而有些版本选择到ARMCC根目录就行。你可以先选根目录如果MDK提示找不到再尝试选择到bin目录。我实际测试过的MDK 5.36和5.37都是选择ARMCC根目录就能识别。3.3 工程配置里切换为AC5并处理兼容项编译器注册完成后还需要在具体工程里把编译器切换到AC5。选中工程目标按AltF7打开Options for Target切换到Target选项卡在Code Generation区域能看到ARM Compiler下拉框。点开下拉框正常情况下会列出可用的编译器选项比如“Use default compiler version 6”和“ARM Compiler 5.06 Update 7”。直接选择AC5的版本即可。这里我建议同时检查一下C/C选项卡里的“Language / Code Generation”设置。因为老工程可能用了一些旧编译器特有的选项比如AC5时代习惯于在“C/C”的Misc Controls里写--cpuCortex-M4或者使用--gnu、--c99等标志。切换到AC5后这些选项通常能继续生效。但如果开了太高优化等级可以先用-O2甚至-O0跑通编译再逐步优化避免一开始被混淆。全部设置好后点击OK然后Rebuild。编译日志里如果出现类似armcc.exe的调用并且一长串路径指向C:\Keil_v5\ARM\ARMCC\bin就说明AC5已经成功接管了编译。4. 编译过程中最常踩的五个坑4.1 AC5路径识别不了、仍提示缺失第一种情况是明明把ARMCC放好了MDK的编译器列表里也显示了AC5但编译时还是报“there is no ARM compiler installed”。这种事我见过不少很大概率是工程配置里选错了编译器。注意Options for Target里的ARM Compiler下拉框有时候你选的是“Use default compiler version 5”但系统实际没有找到默认AC5。尝试直接选中具体的“ARM Compiler 5.06 Update 7”选项而不是用default。还有一种情况是MDK的TOOLS.INI文件残留了旧的编译器路径信息。如果你曾经装过老版本MDK后来又换到了新目录TOOLS.INI里可能错误地指向了旧的ARMCC路径。可以打开MDK安装目录下的TOOLS.INI在[ARM]段中检查是否存在ARMCC相关路径确保它指向你当前实际的ARMCC目录。如果你不确定怎么改最稳妥的办法是卸载重装MDK或者把整个MDK和ARMCC统一放到同一个根目录。4.2 老工程里编译选项失效用AC5编译老工程最常见的是优化等级、C标准、字节序等选项不兼容。例如有的老工程在“Misc Controls”里写了--split_section或--reduce_paths这些开关在AC5下确实有效但如果之前你尝试过AC6并在这些配置里写了-fno-short-enums之类的armclang选项再切回AC5时就会报“unknown option”错误。解决办法是在切换编译器后把C/C选项卡里的“Misc Controls”内容清空然后再逐步根据编译提示加回必要的选项。不要贪图省事从AC6的配置里直接复制选项过来两个编译器的参数体系完全不同。我给一个参考方案先清空所有额外编译选项只保留优化等级-O2和调试信息--debug能编过之后再一点点加东西。4.3 头文件路径兼容问题AC5的头文件搜索规则和AC6并没有本质区别但老工程的相对路径在手动移动编译器后容易出问题。我遇到过一种情况工程里引用了#include stm32f10x.h而标准库的头文件路径原本是相对于C:\Keil_v5\ARM\INC\ST\STM32F10x之类的目录但新版MDK的INC目录结构已经变了导致找不到头文件。这种问题很好排查看编译日志里第一个Error: #5: cannot open source input file的错误再去工程设置里的Include Paths检查对应目录是否存在。正常情况下只要你的工程路径是完整的头文件路径都存放在工程本身的配置里和MDK安装目录关系不大。但如果你之前引入了一些“绝对路径”的头文件目录挪动编译器后就要同步更新。4.4 多版本MDK共存时的选择器问题有时候一台机器上装了多个版本的MDK比如5.36做主力5.34做老项目备份。这种情况下AC5放在哪个MDK的AR目录下就只会被哪个MDK识别。我见过有人把AC5放到了旧版MDK的目录里然后打开新版MDK编译却发现找不到AC5急得一头汗。建议是多版本共存的场景下只在主力MDK里放AC5或者每个MDK都单独放一份ARMCC。反正是绿色文件夹复制一份不占多少空间但能避免很多路径混乱。另外双击.uvprojx文件默认打开的MDK版本要和你预期的工程一致右键工程文件选择“Open with”可以指定MDK版本免得打开错了编译器环境。4.5 License验证偶发失败添加AC5后还有一个可能出现的幺蛾子error: C9555E: Failed to check out license。这通常不是AC5文件本身的问题而是MDK的许可证里没有包含AC5的使用权限。如果你使用的是在线浮点许可证需要确保你的Keil账号已经登记了AC5的license部分评估版不包含AC5需要获取合适的license。如果是单机锁试着重新激活一次许可证。这种时候可以先退出MDK打开License Management检查许可支持的特性里有没有“ARM Compiler 5”的字样。如果没有可以联系代理商或Arm官方申请添加。如果你借用的是公司团队license也要确认服务器端是否放开了AC5的授权。总之这属于许可证配置问题不是AC5安装问题。5. 我自己长期维护多版本工程的几个心得5.1 为什么我建议保留AC5但不要过度依赖说句实在话AC5终究是个“过气”编译器。我把AC5留在电脑里是因为手头有历史项目要维护客户并不会因为编译器不流行就允许我贸然改代码。但如果你是刚开始接触嵌入式的新人或者准备启动全新的项目我真心建议直接用AC6。理由很简单AC6才是未来Linaro、GCC、LLVM的新特性都会往AC6靠拢而且现在新出的芯片官方SDK很多已经默认只支持AC6了。我之前有个项目因为要用一颗新的传感器芯片SDK是用armclang写的里面用了一些AC6特有的关键字和内置函数。老工程如果强行用AC5去编译那个SDK反而会出现大量误差。所以正确姿势是老代码用AC5新模块用AC6通过分目录、分库的方式混编。MDK支持在同一个工程里按汇编、C/C源文件分别指定编译器实际上MDK工程粒度是Target级别的不能直接每个文件独立选AC5/AC6。所以更实际的做法是把新模块编译成静态库丢给AC5的老工程链接。5.2 如何把现有工程平滑迁移到AC6如果你终于决定摆脱AC5我给一个风险较小的迁移路径先在MDK里复制一个Target把编译器切换到AC6修改编译选项然后逐个解决错误。常见的迁移点包括内联汇编改写AC5的__asm{}变成AC6的__asm volatile(...)尽量用C语言替代。中断关键字__irq改成__attribute__((interrupt))。$Sub$$和$Super$$补丁机制AC6改用__attribute__((patchable))或使用函数指针进行挂钩老办法不再适用。结构体对齐、位域的默认行为差异编译后可能产生不同的内存布局需要逐个结构体确认。迁移过程中建议先开-Wall把可见警告清理一遍。不要试图一次搞定可以先让代码编译出来再烧到板子上验证功能重点检查时序中断、DMA配置这类对编译器敏感的部分。5.3 备份、记录与团队协作中的注意事项最后分享一点干活的时候踩过的坑。如果你和我一样需要维护大量老工程建议把AC5的安装包单独存到一个内部共享盘上而不是只放在本机。因为新来的同事安装MDK后大概率也会面对AC5缺失的问题如果没有离线包他们还要到处找下载链接。把ARMCompiler_5.06u7_Windows.zip放在团队公共资源目录里可以省去很多沟通成本。另一个关键是编译器和工程版本的“约定”。团队里最好有一份文档明确写清楚哪个工程必须用哪个版本的MDK、AC5还是AC6、Pack版本是多少。我见过最惨的事故是有人用MDK 5.38打开了一个MDK 5.36创建的工程MDK自动升级了工程文件格式导致其他同事用老版本MDK打不开只能回滚到SVN上一个版本重改。从那以后我对所有工程都要求在提交代码时明确标注“请使用MDK 5.36 AC5.06u7”这样的标签避免版本混乱。还有一个小技巧在工程文件夹里放一个README.md或build_env.txt写清楚编译环境和依赖。虽然看起来麻烦但在半年后你重新拾起一个项目时会发现这份小小的记录能救你的命。我自己现在就习惯在每个项目根目录放一个文本文件内容就是一句话“编译器: AC5.06u7, MDK目录: C:\Keil_v5, 注意不要用AC6打开此工程”。说实话给MDK手动加AC5这件事本身并不复杂整个过程下来也就几分钟。真正让人头疼的不是“不会装”而是装完之后工程依然编译不过的挫败感。希望通过这篇文章你能把AC5缺失这个根因解决掉同时绕过我在实操中踩过的那些坑。下次再有人问“为什么我装了新版MDK还是编译失败”你可以直接把这篇分享转给他帮他少走点弯路。
返回列表