# IAR相关知识点 ## 工程操作 ### **各类型文件含义** | 文件后缀 | 其意义 | | :-------: | :----------------------------------------------------------: | | `.eww` | 工作空间文件,包含多个项目的索引信息 | | `.ewp` | 项目文件,包含项目的设置和配置 | | `.ewd` | 调试配置文件,用于调试设置 | | `.ewt` | (嵌入式工作台模板文件) 用于存储工程或文件的模板配置,方便快速创建具有相同设置的新项目。 | | `.c` | 源代码文件,包含C语言代码 | | `.h` | 头文件,包含函数声明和宏定义 | | `.s/.asm` | 汇编文件 | | `.map` | 单片机地址映射文件 | | `.hex` | 烧录到芯片的十六进制文件 | ### **新建/打开工作区** #### 新建工作区 ![image-20250709093244205](./pictures/image-20250709093244205.png) #### **打开工作区** ![image-20250709093728548](./pictures/image-20250709093728548.png) ### **新建/打开工程** #### 新建工程 ![image-20250709093806148](./pictures/image-20250709093806148.png) #### **打开工程** ![image-20250709093908974](./pictures/image-20250709093908974.png) ### **工作区导入/添加工程** ![image-20250709094027152](./pictures/image-20250709094027152.png) ### **新建分组** ![image-20250709094122539](./pictures/image-20250709094122539.png) ### **新建/打开文件** #### 新建文件 ![image-20250709094340738](./pictures/image-20250709094340738.png) #### 打开文件 ![image-20250709094428732](./pictures/image-20250709094428732.png) ### **工程目录与文件目录的关系** - 工程目录主要负责项目配置和构建控制,而文件目录则是源代码的物理存储位置。两者通过工程文件中的引用关系连接起来,形成完整的开发环境结构。 ## 工程配置 ### **设备配置** #### 选择芯片型号 ![image-20250709095356988](./pictures/image-20250709095356988.png) ![image-20250709095422368](./pictures/image-20250709095422368.png) ### **编译配置** #### 优化等级 ![image-20250709095459265](./pictures/image-20250709095459265.png) **四个优化等级(None、Low、Medium、High)的一般区别:** | 优化等级 | 主要特征 | 适用场景 | | ---------- | ------------------------------------------------------------ | ---------------------------------------------- | | **None** | 不做任何优化,编译器生成的代码基本直译源代码,编译速度最快,代码体积和运行效率都最低。 | 调试阶段,方便调试,代码易读,能快速定位问题。 | | **Low** | 进行少量优化,基本减少明显的低效代码,稍微提升执行速度和代码大小,但编译时间较短。 | 开发早期,性能不是关键时,调试还能较方便。 | | **Medium** | 平衡优化,既关注性能提升,也适度控制代码大小,编译时间较长。 | 一般发布版本,适合大多数应用场景。 | | **High** | 激进优化,最大限度提升执行速度和代码大小的压缩,可能会改变代码行为(比如改变指令顺序、内联函数)。 | 性能要求极高的发布版本,代码难以调试。 | IAR 编译器在 High 优化级别下的下拉框提供了三种优化策略: | 选项 | 含义 | 适用场景 | | ------------ | -------------------------------- | -------------------------------- | | **Size** | 优化代码体积,减小生成二进制大小 | 适合内存受限的嵌入式系统 | | **Speed** | 优化运行速度,提高代码执行效率 | 适合对性能要求较高的应用 | | **Balanced** | 代码大小和执行速度折中 | 兼顾体积和速度,适合一般应用需求 | #### 硬件浮点 ![image-20250709095532506](./pictures/image-20250709095532506.png) #### 预处理 ![image-20250709100328867](./pictures/image-20250709100328867.png) #### 链接文件 (.icf链接脚本控制内存分配(Flash/ROM、RAM 布局)关键硬件相关文件) ![image-20250709095718033](./pictures/image-20250709095718033.png) 在 `IAR` 编译环境下,`__section_start("name")` 是一个 **内置宏**,它返回指定段(section)`name` 的起始地址。通常用于获取某个内存段的起始地址,比如某个代码段、数据段、或者自己定义的特殊段。 **举例** ``` extern unsigned int __section_start("MY_SECTION"); void func() { unsigned int *ptr = (unsigned int *)__section_start("MY_SECTION"); // 现在 ptr 指向 MY_SECTION 段的起始地址,可以用来操作该内存区域 } ``` 这里 `__section_start("MY_SECTION")` 返回的是链接器脚本中 `MY_SECTION` 段的起始地址。 **IAR ICF 文件(.icf)的了解及变量如何分配内存区域** ICF(**IAR Linker Configuration File**)用于定义程序的内存布局,包括代码、数据、堆栈等在内存中的分布。 **变量分配到特定内存区域的方法**: 你可以通过修改 `.icf` 文件中的 `define block` 和 `place in` 语句来控制变量在内存中的分布。 **示例(将某段变量放到特定内存区域):** ``` icf复制编辑define region MY_RAM = mem:[from 0x20010000 to 0x20010FFF]; define block my_section with alignment = 8 { section .mydata }; place in MY_RAM { block my_section }; ``` 然后在代码中定义变量时,使用 `__attribute__((section(".mydata")))` 或 IAR 的 `__section`: ``` c 复制编辑 __no_init uint8_t my_buffer[1024] @ ".mydata"; // IAR语法 ``` ### 文件路径配置 ![image-20250709095759245](./pictures/image-20250709095759245.png) ### 输出文件路径 ![image-20250709100111787](./pictures/image-20250709100111787.png) ### 输出文件配置 ![image-20250709100429885](./pictures/image-20250709100429885.png) ### 调试器配置 ![image-20250709100507410](./pictures/image-20250709100507410.png) ![image-20250715131503129](./pictures/image-20250715131503129.png) | 选项 | 作用 | 建议使用情况 | | ------------------- | ------------------------ | ---------------------- | | Verify Download | 下载后自动校验程序正确性 | 需要确保下载成功时开启 | | Suppress Download | 禁止下载程序 | 只想调试已有程序时开启 | | Use Flash Loader(s) | 使用特定Flash烧录程序 | 编程内部闪存时勾选 | `.board` 文件是IAR Embedded Workbench中用来描述目标硬件板(开发板)配置的文件。 - 它包含调试器接口信息(如JTAG/SWD设置)、时钟配置、芯片类型、连接参数等硬件相关的设定。 - IDE通过 `.board` 文件知道如何与目标板正确通信和调试。 **Mass Erase** 指的是对目标芯片整个闪存区域进行**全部擦除**的操作。 - 该选项开启后,调试器在烧写程序前,会先对芯片内部所有闪存区域执行一次彻底擦除,确保没有残留旧数据。 ### 库相关配置 ![image-20250709100552114](./pictures/image-20250709100552114.png) ### 静态库的封装 1. ![image-20250709185406199](./pictures/image-20250709185406199.png) 2. ![image-20250709185505451](./pictures/image-20250709185505451.png) 3. ![image-20250709185622450](./pictures/image-20250709185622450.png) 4. 屏蔽不用编译的文件 ![image-20250709185744113](./pictures/image-20250709185744113.png) ![image-20250709185833195](./pictures/image-20250709185833195.png) 5. 编译 ### 静态库的调用 1. ![image-20250709185922441](./pictures/image-20250709185922441.png) 2. ![image-20250709190002503](./pictures/image-20250709190002503.png) 3. 将之前的.c文件删除 4. 编译执行 ## 工程调试 ### 断点 #### 设置断点 设置断点(点击代码行左侧,出现红色圆圈) #### 禁用断点 禁用断点(右键红色圆圈,Enable/disable) #### 启用断点 启用断点(右键红色圆圈,Enable/disable) #### 删除断点 删除断点(再次点击代码行左侧,红色圆圈消失) #### 条件断点 条件断点(可以设置一个条件,当条件满足时,断点生效) ![image-20250709104442792](./pictures/image-20250709104442792.png) #### 数据断点 ![image-20250715135308980](./pictures/image-20250715135308980.png) ![image-20250715135342485](./pictures/image-20250715135342485.png) 选择数据断点,可以选择是读触发还是写触发,同时可以结合条件断点使用。 ### 监控信息 ![image-20250709101836850](./pictures/image-20250709101836850.png) #### 寄存器信息 ![image-20250709105019076](./pictures/image-20250709105019076.png) | 寄存器 | 名称 | 类型 | 说明 | | ------------ | ------------------------------------- | ------------ | ------------------------------------------------------------ | | **`R0–R3`** | 通用寄存器 | 通用 | 用于函数参数传递、临时数据处理等。R0 通常作为函数返回值寄存器。 | | **R4–R11** | 通用寄存器 | 被调用者保存 | 用于本地变量、长生命周期数据。函数调用后,值需由被调用函数负责保存。 | | **R12** | Intra-Procedure-call scratch register | 特定用途 | 通常由编译器用于中间值,调用过程临时数据,不保证保存。 | | **R13 (SP)** | Stack Pointer | 特殊 | 栈指针,指向当前栈顶。用于局部变量、函数调用等。可分为 MSP/PSP。 | | **R14 (LR)** | Link Register | 特殊 | 链接寄存器,存储函数返回地址。调用 `BL` 指令时保存返回点。 | | **R15 (PC)** | Program Counter | 特殊 | 程序计数器,存储当前指令地址。控制程序执行流程。 | **R0–R3:参数 / 返回值 / 临时变量** - 函数参数通过 R0~R3 传递(最多 4 个参数); - 函数返回值一般通过 R0(或 R0~R1); - 调用者需要保存这些值(Caller-saved); ``` c复制编辑int add(int a, int b) { return a + b; // a→R0,b→R1,结果→R0 } ``` **R4–R11:局部变量 / 被调用者保存** - 通常用于函数内部的变量或数据; - 调用函数前由被调用者负责保存(Callee-saved); - 在嵌套调用中保持数据完整性。 ``` c复制编辑void foo() { int x = 10; // 可能保存在 R4~R11 中 } ``` **R12:临时 scratch 寄存器** - 用于子程序中临时使用; - 不由任何函数负责保存; - 调用嵌套函数或执行复杂表达式时使用; **R13(SP):栈指针 Stack Pointer** - 指向当前栈顶地址; - 控制函数调用/返回、局部变量压栈; - Cortex-M 支持两种 SP: - MSP(Main Stack Pointer)— 默认上电使用; - PSP(Process Stack Pointer)— RTOS 多线程任务使用; - 使用 `MSR` 和 `MRS` 指令读写切换。 **R14(LR):链接寄存器 Link Register** - 存放函数返回地址; - 执行 `BL`(Branch with Link)时,PC 会跳转到函数地址,当前 PC 会保存到 LR; - 函数返回时使用 `BX LR` 指令返回; **注意**:异常发生时,LR 也可能用于标记返回类型。 **R15(PC):程序计数器 Program Counter** - 保存当前执行指令地址; - 所有分支、跳转指令都会修改 PC; - 可以通过修改 PC 实现跳转(例如 `PC = 0x08001234`)。 #### 内存信息 ![image-20250709105314139](./pictures/image-20250709105314139.png) #### 栈信息 ![image-20250709105420224](./pictures/image-20250709105420224.png) #### 汇编信息 ![image-20250709105851015](./pictures/image-20250709105851015.png) #### 调用堆栈信息 调用堆栈窗口通常在IDE(如Visual Studio)中提供,它展示了函数调用的顺序列表。 ![image-20250709190439295](./pictures/image-20250709190439295.png) ### 单步调试 #### 逐过程 ![image-20250709191214143](./pictures/image-20250709191214143.png) #### 逐语句 ![image-20250709191149273](./pictures/image-20250709191149273.png) #### 复位 ![image-20250709103631255](./pictures/image-20250709103631255.png) #### 跳出 ![image-20250709191239821](./pictures/image-20250709191239821.png) ## IAR 调试常用操作对照表(含英文缩写、快捷键和含义) | 中文名称 | 英文名称 | 缩写/简称 | 快捷键 | 含义说明 | | -------- | --------- | ------------------ | -------------- | ------------------------------------------------------------ | | 逐语句 | Step Into | `StepIn` 或 `SI` | `F11` | 执行当前语句,若为函数调用,则进入函数内部逐句调试。 | | 逐过程 | Step Over | `StepOver` 或 `SO` | `F10` | 执行当前语句,若为函数调用,则跳过函数体,直接执行下一行。 | | 跳出 | Step Out | `StepOut` 或 `SR` | `Shift + F11` | 执行当前函数剩余代码并跳出,返回到调用该函数的位置。 | | 复位 | Reset | `Reset` | *无默认快捷键* | 让 MCU 从复位向量重新启动程序执行(从 `main()` 或初始化开始)。 | ![image-20250715122856333](./pictures/image-20250715122856333.png) | 序号 | 英文 | 作用 | | :--: | :---------------------: | :----------------------------------------------------------: | | 1 | compile | 编译当前页 | | 2 | make | 编译全部文件 | | 3 | toggle Breakpoint | 切换断点 | | 4 | Make & Restart Debugger | 重新启动调试器并从头开始调试程序 | | 5 | Restart Debugger | 重新开始调试,但不做代码更改或重新编译 | | 6 | stop Debugger | 退出调试模式,返回到编辑器状态,释放调试器资源。 | | 7 | step over | 逐过程调试 | | 8 | step into | 逐语句调试 | | 9 | step out | 跳出 | | 10 | Next Statement | **不执行当前行**,将程序的执行位置**强制跳转**到下一条语句。用于控制程序流程,但不会影响变量或硬件状态。 | | 11 | Run to Cursor | 程序从当前停止的位置开始**连续运行**,直到光标所在的那一行,然后**暂停执行**。 | | 12 | Go | 在调试状态下,让程序从当前暂停位置**继续运行**,直到遇到断点、出错或程序结束。 | | 13 | Break | **在程序运行过程中强制暂停执行**,进入调试状态,查看当前执行位置、变量状态等。 | | 14 | Reset | 让 MCU 从复位向量重新启动程序执行(从 `main()` 或初始化开始)。 | | 指令 | 编译 | 下载 | 进入调试 | 从头开始运行 | 是否保留断点 | | ---- | ---- | ---- | -------- | ------------ | ------------ | | **Download and Debug** | ✅ | ✅ | ✅ | ✅ | ✅ | | **Make & Restart Debugger** | ✅ | ❌(默认不下载) | ✅ | ✅ | ✅ | | **Restart Debugger** | ❌ | ❌ | 已在调试中 | ✅ | ✅ | [**参考文献**](https://blog.csdn.net/ideal121/article/details/118675124?fromshare=blogdetail&sharetype=blogdetail&sharerId=118675124&sharerefer=PC&sharesource=2301_81415726&sharefrom=from_link)