3. 中断系统深度优化
RX 系列 MCU 的中断控制器(ICUA/ICU)是实时性能的关键路径。中断响应延迟由硬件入栈、向量取址、跳转执行三部分构成,而中断嵌套与优先级配置直接决定高优先级事件能否抢占低优先级服务。本节围绕优先级寄存器配置、嵌套规则、FIQ 快速响应通道以及延迟测量方法展开,目标是让读者能够独立完成一套可验证的中断优化配置。
一、优先级配置:IPR 寄存器与分组策略
RX 的中断优先级由 IPR 寄存器组控制,每个中断源对应一个 4 位优先级字段,取值 0~15,数值越大优先级越高。RX 将 16 级优先级划分为 8 组(组 0~7),组内再分高低两级,这一分组机制决定了嵌套时的抢占粒度。配置时需注意三点:
- 同一组内的中断不能相互抢占,只有组号更高的中断才能打断当前服务;
- IPR 写入必须在中断使能前完成,否则可能产生一次错误优先级的响应;
- 系统保留最高优先级(15)给 NMI 与看门狗等不可屏蔽事件,用户中断建议使用 1~14。
以下是一段典型的 IPR 配置示例,将 SCI 接收中断设为优先级 12(组 6),定时器中断设为优先级 8(组 4),确保串口接收能抢占定时器服务:
/* 假设 IPR 基址已由 iodefine.h 定义 */
IPR(SCI0, RXI0) = 12; /* 串口接收:高优先级 */
IPR(CMT0, CMI0) = 8; /* 定时器:低优先级 */
IEN(SCI0, RXI0) = 1; /* 使能中断 */
IEN(CMT0, CMI0) = 1;
配置完成后,可通过读取 IPR 寄存器回读值确认写入生效。若使用 Smart Configurator,需在中断标签页中核对优先级数值与生成代码一致,避免图形界面与手写代码冲突。
二、中断嵌套管理:PSW 与栈帧保护
RX 在响应中断时自动将 PC、PSW 等压入栈,并清除 PSW 中的 I 位(中断禁止位)。若希望在中断服务程序(ISR)中允许更高优先级中断嵌套,需在 ISR 入口手动置位 I 位。典型做法是在 ISR 开头执行 setpsw i,使能嵌套;若该 ISR 涉及不可重入的共享资源,则应保持 I 位为 0,禁止嵌套。
嵌套深度受栈空间限制。每次中断嵌套至少消耗 8 字节栈帧(PC 4 字节 + PSW 4 字节),若 ISR 内部还有函数调用与局部变量,实际消耗更大。建议在链接脚本中为中断栈预留至少 512 字节,并在调试阶段通过填充魔数(如 0xDEADBEEF)观察栈使用峰值。若发现栈溢出,优先检查是否存在过深嵌套或 ISR 内大数组分配。
三、FIQ 快速中断:绕过向量表的直达通道
RX 提供 FIQ(Fast Interrupt)通道,其响应不经过普通向量表跳转,而是直接跳转到固定地址,省去向量取址周期。FIQ 通常用于对延迟极度敏感的事件,如电机控制中的过流保护、编码器零脉冲捕获。启用 FIQ 需完成三步:
- 将目标中断源映射到 FIQ 通道(通过 ICU 的 FIQ 控制寄存器选择);
- 在固定地址处放置 FIQ 处理函数,或通过 FIQ 向量寄存器指向自定义入口;
- 将 FIQ 优先级设为最高,并确保其不被普通中断屏蔽。
FIQ 的代价是灵活性降低:同一时刻只能有一个 FIQ 源,且调试时断点行为与普通中断不同。因此建议仅在普通中断延迟无法满足时序要求时启用,并在启用后重新测量最坏响应时间。
四、中断延迟测量:GPIO 翻转法与示波器判读
中断延迟指从中断事件发生到 ISR 第一条指令执行的时间。最实用的测量方法是 GPIO 翻转法:在 ISR 入口立即翻转一个空闲 GPIO,用示波器同时观察中断触发信号与 GPIO 翻转沿,两者时间差即为响应延迟。
void sci0_rxi_isr(void) {
PORT1.PODR.BIT.B0 = 1; /* 入口拉高,标记进入 ISR */
/* ... 实际处理 ... */
PORT1.PODR.BIT.B0 = 0; /* 退出拉低 */
}
测量时需注意:GPIO 翻转本身有 1~2 个时钟周期延迟,应在结果中扣除;示波器探头地线要短,避免振铃误判。建议分别测量空 ISR 与满载 ISR 的延迟,前者反映硬件响应下限,后者反映实际工程余量。若实测延迟超过预期,优先检查是否因优先级配置不当导致等待、是否因 Flash 等待周期拖慢取指、以及是否因嵌套过深造成栈访问冲突。
五、优化检查清单
完成上述配置后,建议按以下顺序复核:IPR 回读值是否与设计一致;ISR 入口是否按需置位 I 位;FIQ 是否确实映射到目标源且固定地址入口正确;栈魔数是否未被覆盖;GPIO 翻转法测得的延迟是否在预算内。若任一环节不通过,优先回到优先级仲裁与嵌套决策环节排查,因为这两处最容易因配置顺序或组划分错误导致响应异常。