资讯动态

IAR中文手册速查:AVR工具链、C-SPY调试与链接排错

发布时间:2026/10/27 14:21:57 来源:尧图企业网站定制
简介《IAR中文用户手册-官方版》面向使用IAR Embedded Workbench IDE进行嵌入式开发的工程师与学习者尤其适合基于Atmel AVR微处理器开展项目、需要系统查阅工具链用法的人群。它以PDF形式交付压缩包共1个文件、约859KB体量轻便便于随查随用。手册内容覆盖产品介绍与教程两大部分前者梳理IDE、C-SPY调试器及其调试系统、C/C编译器、汇编器、XLINK连接器、XAR库创建器与XLIB库管理器等组件后者从新建应用工程、编译连接、C-SPY调试到C与汇编混合编程、C应用及中断模拟逐步展开可帮助读者理解工程组织、调试流程与混合编程要点。目前已有3380人学习适合作为AVR嵌入式开发过程中查阅IDE功能、排查编译调试问题的中文参考。1. 一份 200 多页的 IAR 中文用户手册先别从头读三类人三种翻法手上这份 IAR 中文用户手册官方版 PDF是 AVR 平台上 IAR Embedded Workbench IDE 的随附文档正文从产品介绍、七件套工具链讲起再进教程建工程、编译连接、C-SPY 调试、C 与汇编混合、中断仿真、库模块引用。它的价值不在“读完”而在“查得准”——一个.xcl模板写错、一个断点打不上、一个.map里段地址对不上翻对页三分钟解决翻错页能耗一下午。刚接手 AVR 项目的新人、从别的 IDE 迁过来的熟手、要给团队定工具链规范的人三种人翻法完全不同。下面按我实际用它的顺序拆。2. 工具链七件套与安装目录把手册第一部分压缩成两张对照表第一部分是整份手册里最容易被跳过、但出问题时最常回翻的部分。它不讲语法只讲“这个 IDE 由哪些可执行文件拼起来、它们各自吃什么文件、吐什么文件”。把这一层搞明白后面所有报错你都能立刻定位到是哪一件工具在抱怨。2.1 从 IDE 外壳到 XLINK七件套各自负责哪一段手册 1.1 节把工具链拆成七块集成开发环境外壳、AVR C/C 编译器、AVR 汇编器、XLINK 连接器、XAR 库创建器与 XLIB 库管理器、C-SPY 调试器、编辑器与工程管理器。原文那句“不同架构同一解决方案”说的就是这套外壳可以挂不同芯片的后端工程文件格式和操作习惯不变换芯片只换编译器后端和器件描述文件。按实际编译流程排一遍更清楚源文件.c/.cpp/.s90交给编译器或汇编器各自产出可重定位目标文件.r90XLINK 把若干.r90和库文件.a连起来按.xcl里的段命令摆放代码和数据输出可执行文件.out和下载格式C-SPY 再读.out里的调试信息把源码行、变量、调用栈对回你的编辑器窗口。组件在工程里干什么手册位置出问题先看哪IDE 外壳工作区/工程管理、编辑器、构建系统1.1.1工程选项是否落到组/文件级C/C 编译器优化、扩展关键字、DLIB/CLIB 选择1.1.4优化等级、器件型号、头文件路径汇编器重定位宏汇编内置 C 预处理器1.1.5段声明、PUBLIC/EXTERNXLINK 连接器段定位、库模块抽取、类型检查1.1.6.xcl文件、CSTACK 尺寸XAR / XLIB建库、列模块、增删替换模块1.1.7库顺序、重复符号C-SPY 调试器断点、变量、调用栈、宏1.1.2、1.1.3驱动选错、优化过高编辑器/工程管理语法着色、书签、多文件搜索1.1.1基本不用查选型上有个常被忽略的点手册明确说编译器、汇编器、连接器都能在命令行单独跑。这句话的含义是你完全可以把 IDE 当编辑器用把构建放进批处理或持续集成脚本里iccavr编译、xlink连接、cspybat起调试会话三件事可以分开做。团队里多人协作时我一般会把这套命令行固化成一个build.bat工程文件只作为选项的“可视化编辑器”避免有人手改.ewp造成配置漂移。提示手册里对 C-SPY 的描述分“主要部分”和“驱动部分”两层前者是通用的断点/变量/调用栈逻辑后者负责跟具体目标通信。排查问题时先分清是内核层不工作源码对不上、变量看不到还是驱动层不工作连不上目标板能省掉一半无效操作。2.2 安装目录的分层逻辑avr 与 common 两条分支手册 1.2.1 节写得很细但真正需要记住的只有一句avr目录放芯片相关的东西common目录放所有产品共享的东西。默认根目录形如x:\Program Files\...\Embedded Workbench 4.n4.n是 IDE 版本号安装路径允许自定义所以任何写死路径的脚本迟早会翻车——我一般让脚本从环境变量读根目录。# 典型安装后的目录骨架实际路径以本机为准 $IAR_ROOT/ ├── avr/ │ ├── bin/ # iccavr 编译器、汇编器、C-SPY 驱动等可执行文件 │ ├── config/ # *.xcl 连接模板、*.sfr 寄存器描述、*.ddf 器件描述、*.cfg 着色 │ ├── doc/ # 本手册、编译器参考手册、CHM 在线帮助、readme.htm │ ├── inc/ # 标准库头文件、器件寄存器头文件 │ ├── lib/ # 预编译库与库配置文件 │ ├── src/ # 可配置库源码与示例 │ └── tutor/ # 手册教程对应的示例工程 └── common/ ├── bin/ # xlink、xlib、xar 等共享工具 ├── config/ # IDE 全局设置 ├── doc/ # 连接器与库工具参考手册 ├── plugin/ # 可加载插件 └── src/ # 共享插件源码如自定义输出格式示例这张表比死记目录名有用avr\config是你查“为什么这个器件选不到”“为什么中断向量编号不对”的第一站avr\doc\readme.htm记录的是手册没来得及写进去的版本差异装完先扫一眼能省不少事avr\tutor里放着教程用到的完整工程第 3 章照着做卡住时直接拿它对照选项页最省时间。avr\lib和avr\src的关系也值得说明编译时链的是lib里的预编译库但库的源码在src里。当你想弄清某个库函数为什么占了这么多 flash或者想自己改一版裁剪过的库就去src里找对应模块用 XAR 重新建库再把工程里的库路径指过去。这一步手册提了一句实际项目里做低功耗或小容量芯片时非常常用。2.3 文件扩展名与 config 目录里的四类模板手册 1.2.2 节给了文件类型对照。工程相关的核心是这几个工作区.eww、工程.ewp、调试器设置.ewd、C 源文件.c、C 源文件.cpp、汇编.s90或.asm、头文件.h、可重定位目标.r90、库.a、可执行.out、下载格式.hex/.d90、链接映射.map、列表.lst。avr\config下的四类模板文件更关键它们决定了工程能跑起来的下限扩展名作用什么时候需要动它.xcl连接器命令模板定义段布局、堆栈尺寸、内存区域改 CSTACK/HEAP 大小、自定义段地址、外扩存储.sfr特殊功能寄存器描述器件寄存器定义不全、需要补自定义外设.ddfC-SPY 设备描述仿真器的外设模型软仿真时需要外设行为、中断向量表核对.cfg编辑器语法着色配置自定义关键字高亮纯体验项工程模板.ewp也在config下新建工程时选择模板本质就是复制一份预置选项的工程文件。团队里如果要统一编译选项把自己的.ewp放进这个目录做成模板比每次口头叮嘱“记得开 map 输出”靠谱得多。最后有个容易踩的细节先说在前面手册特别提醒命令行跑 XLINK 时列表映象文件默认扩展名是lst会和编译器生成的.lst列表文件撞名后写的直接覆盖前面的。解决办法很简单在连接选项里把映象文件写成完整名字比如project1.map别偷懒用默认值。这条我吃过一次亏调试时翻了半天“列表文件怎么没有源码行”最后发现是同名覆盖。3. 从空工作区到 C-SPY 跑通建工程、读 map、下断点的完整顺序第二部分是教程从新建工程一路走到中断仿真。它的行文是“点这里、再点那里”的流水账照着做能通但不知道为什么这么点。这一章我按配置的依赖顺序重排一遍把每个选项页里真正影响结果的参数挑出来说。3.1 新建工程与选项配置的先后顺序顺序错了会反复返工。正确的依赖链是器件型号决定可选的中断向量和可用内存内存布局决定.xcl.xcl决定 CSTACK/HEAP 上限优化等级和调试信息决定 C-SPY 能看到什么。所以配置必须自上而下从器件开始。第一步新建工作区Workspace再在其中建工程Project。工作区是容器一个工作区可以挂多个工程做 bootloader 应用的组合时用得上。建工程时选模板空工程、带 main 的 C 工程、汇编工程各一份选错了不要紧删掉源文件重新加就行。第二步打开工程选项在 Target 页选定具体器件型号。这一步不是给你看的是给编译器和 C-SPY 用的编译器据此选正确的寄存器头文件和指令集子集C-SPY 据此加载对应的.ddf。器件选错最典型的表现是编译能过、仿真时寄存器窗口一片空白或者外设名字对不上。第三步General Options 页设置目标核心、数据类型和堆栈。堆栈这里只填“期望值”真正生效的是.xcl里的段定义两边不一致时以.xcl为准。很多人改了这里发现没效果就是没意识到这一层。第四步C/C Compiler 页。优化等级建议开发期用低等级或关闭量产前再切到尺寸优化复测列表文件勾上出问题时能看到生成的汇编预处理器定义里放板级宏别把硬件差异写死在源码里。第五步Assembler 页只有混合编程时才需要细调主要是宏定义和列表输出。第六步Linker 页。勾选覆盖默认.xcl指定实际使用的连接模板勾选生成链接映射文件并显式命名成.map。这一步不做后面排查内存问题会很被动。第七步Debugger 页选驱动。软仿真选 Simulator接硬件仿真器选对应型号。驱动不同可用的断点类型和数量完全不同这个后面细说。第八步把源文件加进工程组按 Make 编译。工程支持组级和文件级选项覆盖做多型号共用一个工作区时把差异放在文件级比维护多份工程省事。; 典型 .xcl 片段示意实际以 avr\config 下对应器件模板为准 -D_CSTACK_SIZE0x100 ; C 栈大小按最深调用链和局部变量估算 -D_HEAP_SIZE0x40 ; 堆大小不用 malloc 就压到最小 -Z(DATA)CSTACK_CSTACK_SIZE ; 把 CSTACK 段定位到内部 RAM 顶端 -Z(DATA)HEAP_HEAP_SIZE.xcl文件里的-D是定义符号-Z是段定位命令。参数怎么改先看.map里 CSTACK 段的实际占用峰值再把_CSTACK_SIZE留出三成余量。压得太狠程序在中断嵌套深的时候跑飞给得太大小容量芯片直接链接报内存不足。这个值没有普适数字只能靠 map 实测。3.2 编译连接产物与 map 文件的读法一次成功构建会产出一堆文件认识它们比背命令有用。.r90是每个源文件对应的可重定位目标.out是最终可执行文件并携带调试信息.hex或.d90是烧录格式.map是链接映射.lst是编译器生成的汇编列表。.map是这里面信息密度最高的。它通常包含模块汇总、段汇总、程序内存汇总和入口列表四块。模块汇总告诉你每个.r90贡献了多少代码和数据段汇总告诉你每个段被放在哪个地址区间、长度多少程序内存汇总给出 flash 和 RAM 的总用量这一行直接决定你能不能换更小容量的芯片。map 里的区块你该关注什么典型异常模块汇总哪个模块代码量异常大某个库函数被整段链入本该被裁剪段汇总CSTACK、HEAP、.data的起止地址栈段被放到 RAM 末尾但没留够余量程序内存汇总flash 与 RAM 用量百分比超过 90% 时后续加功能就会撞墙入口列表复位入口与中断向量地址向量地址与器件手册对不上多半器件选错读 map 有个习惯值得养成每次构建后扫一眼程序内存汇总的 RAM 用量涨得离谱就去段汇总里找是哪个段变胖了。曾经有个工程 RAM 一夜之间多了两百字节最后定位到一个调试用的字符串数组忘了删const也没加直接落在.data里跟着启动代码一起从 flash 拷到 RAM。3.3 用 C-SPY 软仿真跑起来断点、变量窗口、调用栈C-SPY 的驱动决定了你能做什么。手册 1.1.3 节列了几类软仿真驱动完全用软件模拟处理器行为不需要硬件适合逻辑验证和没拿到板子的阶段硬件仿真器驱动面向实时运行不占目标存储器断点能力各有差异——其中一类提供四个硬件断点加不限数量的软件断点另一类支持串口或 USB 连接并内置 flash 下载器。选驱动时别只看“能不能连上”还要看它是否支持代码覆盖几类硬件驱动明确不支持代码和数据覆盖需要做覆盖率统计时只能退回软仿真或换方案。# 命令行启动一次调试会话参数名以本机安装版本为准 cspybat iccavr.exe cspySim.dLL \ --debug_fileproject1.out \ --deviceATmega128 \ --pluginavrEquipment.dLL这段命令的意思是用编译器可执行文件加载 C-SPY 的仿真驱动动态库指定待调试的可执行文件、器件型号和仿真外设插件。参数说明上--debug_file必须指向带调试信息的.out指向.hex是没有源码级调试的--device要与工程选项里选的器件一致不一致时寄存器窗口会错位插件参数决定仿真器是否加载外设模型不做外设仿真可以去掉。断点分三类代码断点停在某条语句可以附加条件比如i 100才停避免在循环里反复中断数据断点监视某个变量或内存地址被读写宏断点则挂一段 C-SPY 宏在命中时执行打印、改变量、甚至注入中断。第三类在中断仿真里是主力手册 2.5 节专门讲了中断和断点中宏的用法。变量窗口的坑主要在优化上。开了高等级优化局部变量可能被完全放进寄存器窗口里显示“不在作用域”单步也会在源码行之间跳跃。开发期把优化关掉或者把关键变量加volatile并在观察窗口里用表达式固定住比反复怀疑调试器有用。调用栈窗口依赖编译器生成的扩展调用信息手册说即使程序计数器停在任何位置也能显示完整调用栈。实际用的时候注意栈回溯在中断上下文里可能断掉这时候看反汇编窗口更实在。混合显示模式可以同时看到 C 源码和对应汇编定位“这行 C 到底编译成了什么”时非常高效。4. 混合编程、中断仿真与库裁剪手册里最容易被跳过的三节教程的后半段2.3 到 2.6讲的是三件在真实项目里天天遇到、但很少有人系统学过的事C 调汇编、中断怎么在没硬件时验证、库该链多少。这三节文字不多信息密度却最高。4.1 调用规则与汇编模块接入C 和汇编混编的第一个门槛不是语法是调用约定参数放哪、返回值放哪、谁负责清栈、哪些寄存器必须保护。手册 2.3.1 节的建议是先检查调用规则再动手写这话不是客套。规则没弄清就写汇编最容易出现“C 里传进去的值在汇编里读出来是垃圾”。常见做法是先用 C 写一个空函数编译后看.lst里的汇编列表观察参数是怎么搬进寄存器的、返回值放在哪、函数序言和尾声长什么样。照着自己编译器实际生成的代码去写汇编模块比照搬任何文档都准。; 汇编模块示例两字节无符号加法演示段声明与符号导出 NAME ADD16 RSEG CODE:CODE:NOROOT(0) ; 放入代码段NOROOT 表示无引用时可被裁剪 PUBLIC add16 ; 导出符号C 端才能链接到 add16: ADD R16, R18 ; 低字节相加寄存器分配以调用规则为准 ADC R17, R19 ; 高字节带进位相加 RET ; 返回值在 R16:R17 END这段代码的关键在三个地方RSEG声明段名和属性段名和属性写错会导致连接时找不到或放错存储区PUBLIC导出符号没有它链接阶段一定报未定义外部引用寄存器编号必须和调用规则一致上面只是示意真实项目要按编译器实际约定填。C 端的声明写法也要对上/* 汇编模块的 C 端声明告诉编译器别做名字修饰 */ extern unsigned int add16(unsigned int a, unsigned int b);参数和返回值的类型要与汇编里实际操作的数据宽度匹配。用unsigned int而汇编只处理了单字节高字节就是脏数据。加汇编模块到工程的步骤是把.s90文件加入工程组检查该文件的 Assembler 选项是否继承了工程级设置然后重新构建用.map确认模块确实被链进去了。4.2 中断句柄与仿真环境搭建中断这块手册 2.5 节的思路很值得学先加中断句柄再建仿真环境最后触发中断验证。它默认你已经知道向量表怎么排实际上多数人卡在第一步——句柄写了中断就是不进。句柄的写法有两种用编译器扩展关键字声明函数为中断类型或者用#pragma指定向量。两种方式的区别在于向量编号是显式写死还是由器件头文件里的宏给出。我一般用后者器件换了向量号自动跟着变不容易错。句柄函数里不要做耗时操作不要调用不可重入函数不要忘了清中断标志——这三条是中断跑飞的经典原因。仿真环境搭建的核心是把中断源“造”出来。软仿真驱动提供中断模拟能力配合 C-SPY 宏系统可以在指定时刻手工触发某个向量。步骤大概是在仿真器配置里启用中断模拟在需要触发的断点处挂一个宏宏里写入触发向量的动作然后全速运行。手册 2.5.4 节讲的“中断和断点中宏的使用”就是这套流程。宏的写法要注意两点一是宏里改动的变量和寄存器在中断上下文里的可见性二是宏执行失败时不会给你明显报错只是“什么都没发生”。调试时可以在宏里加一条打印确认宏真的被执行了再去看中断有没有进。4.3 库模块DLIB 与 CLIB 的取舍手册 1.1.4 节提到两套运行库这是选型时最实际的一个决策点维度DLIBCLIB标准符合性支持 ISO/ANSI C 与 C不完全兼容 ISO/ANSI C浮点支持 IEEE 754 格式不支持C支持不支持代码体积较大较小适用场景需要标准库完整性、浮点、Cflash 紧张、纯 C、无浮点选型逻辑很直接用 C、用浮点、用标准库里的重函数就选 DLIB芯片 flash 只有几 KB、纯 C、定点运算选 CLIB 能省下可观空间。切换在编译器选项里改一行但改完必须全量重编译混着链会出类型不匹配的报错。XAR 和 XLIB 的用法手册 1.1.7 节讲得比较简略实际流程是把若干.r90用 XAR 打包成.a用 XLIB 列出、添加、替换、移除模块需要时把模块在程序和库类型间转换。链接时 XLINK 只抽取被实际引用的模块这就是为什么库大了不一定占 flash——但前提是每个模块粒度够细。如果你的库把十个函数塞进一个模块用一个就全链进来.map里立刻能看出来。遇到这种情况重新按功能拆分源文件再建库比事后优化代码有效得多。5. 排查清单编译连接与调试仿真两个阶段的高频翻车这份手册的价值有一半在排错但它按功能组织不按症状组织。下面这些是我和同事实际撞过的按“现象 → 原因 → 解决”记下来对照着查比逐页翻快。5.1 编译与连接阶段现象编译全过链接报未定义外部引用符号名还带着奇怪的前后缀。原因C 端调用汇编模块或 C 调用 C 函数时名字修饰没对上汇编里也没写PUBLIC。 解决先在.map或链接报错里看清它找的符号全名回头核对 C 端声明和汇编导出是否一致C 调 C 要加外部 C 声明块汇编模块确认PUBLIC拼写和大小写。这类问题九成是名字问题不是逻辑问题。现象明明开了列表文件输出打开.lst里却没有源码行只有一堆二进制。原因连接器生成的映象文件默认扩展名也是lst把编译器产物覆盖了。 解决连接选项里把映象文件显式命名成project1.map之类的独立名字别用默认值。养成构建后先看文件时间戳的习惯能第一时间发现覆盖。现象链接报内存区域溢出但代码量看着不大。原因常量数组没加const落在.data段启动时要从 flash 拷到 RAM双份占用或者某个库模块整段被链入。 解决打开.map的段汇总看.data和.bss谁在膨胀把只读数据加const放进 flash再看模块汇总找那个异常大的模块拆库或换精简实现。现象换了个器件型号工程能编译但中断完全没反应。原因器件选项没改编译器用的还是旧头文件向量号对不上。 解决Target 页重新选器件清理后全量重编译。器件相关的宏和向量表都在头文件里增量编译不会重读必须清理。5.2 调试与仿真阶段现象单步调试时执行行在源码里乱跳变量窗口显示变量不在作用域。原因优化等级开太高局部变量被放进寄存器或直接被消除语句被重排。 解决调试配置单独建一套优化关掉需要长期观察的变量加volatile或者改用表达式窗口按地址观察。发布配置保持优化两套配置分开维护别来回改同一个工程。现象软仿真里中断句柄永远不执行硬件上却是好的。原因仿真环境没启用中断模拟或者触发宏没真正执行。 解决确认仿真器配置里中断模拟已开启在宏里加打印验证宏被执行再核对向量号和句柄声明是否匹配。手册里“中断和断点中宏的使用”那一节就是为这个场景写的。现象程序跑一段时间就复位或行为异常仿真器里看不出错。原因CSTACK 给小了深层调用或中断嵌套把栈写穿踩到了其他变量。 解决.xcl里加大 CSTACK把大数组从局部变量改成静态或放到堆构建后固定看一眼.map里栈段余量别等出事才查。现象换到硬件仿真器后代码覆盖率报告出不来。原因所选驱动不支持代码覆盖手册在产品介绍里对几类硬件驱动明确标注了这一点。 解决需要覆盖率时退回软仿真跑用例或者改用支持该功能的调试方案。选驱动前先想清楚这一轮调试要什么能力别等做完才发现拿不到数据。6. 把 PDF 变成随手可查的私人索引标签、摘录与一条检索习惯手册是 PDF目录页码和阅读器物理页码之间有一段偏移直接输页码经常差几页。我的做法是先花十分钟把一级、二级标题在阅读器里全部建成书签命名规则统一成“症状关键词 章节号”比如“栈溢出 1.2.1”“未定义外部引用 2.3.1”。建完之后这份文档就从“要读的书”变成了“能查的手册”。第二步是把文字层抽出来做全文检索。PDF 有文字层时命令行工具比阅读器搜索快得多尤其是要跨多个文档找同一个词# 抽取文字层保留分页信息便于回查页码 pdftotext -layout iar_avr_ug_zh.pdf iar_avr_ug_zh.txt # 按现象检索一次命中多个候选段落 grep -n -E 未定义|溢出|向量|断点 iar_avr_ug_zh.txt | head -40 # 需要看上下文时按行号取前后若干行 sed -n 1200,1260p iar_avr_ug_zh.txt-layout参数尽量保留原始排版表格和代码片段不会糊成一行grep -n输出行号配合sed取上下文比在阅读器里翻页快。抽出来的文本还可以丢进本地检索工具建索引几个月后再遇到同一个报错一条命令就能定位到当初记的页码。第三步是维护一张自己的“现象—页码”对照表只记自己撞过的坑不抄目录。我遇到的现象手册里的位置关键结论列表文件没有源码行文件类型一节映象文件默认扩展名与列表冲突改名变量窗口看不到值C-SPY 调试器一节优化等级过高调试配置单独一套中断仿真不触发中断仿真一节需启用中断模拟并用宏注入RAM 莫名其妙变少目录结构与文件一节查.map段汇总只读数据加const最后说个习惯。早年我遇到链接报错第一反应是改代码试改到第三次才想起来翻手册结果那一条在 1.2.2 节的注意事项里写得清清楚楚。从那以后凡是报错里带工具名——连接器、库管理器、调试器——我都会先花两分钟在这份 IAR 中文用户手册里搜一遍工具名加报错关键词确认不是自己的用法问题再动代码。这份手册不会教你写出更好的嵌入式程序但它能保证你不把时间浪费在工具的脾气上。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑