3、中断系统详解:中断请求系统(IR)、服务请求节点(SRN)、中断优先级仲裁、中断路由配置、多核中断分发机制
各位同学,咱们今天聊聊AURIX的中断系统。说实话,我刚开始接触AURIX的时候,最头疼的就是这个中断。它跟ARM、Cortex-M那套完全不一样,第一次看参考手册,差点把我绕晕。但后来我明白了,AURIX这套设计其实非常巧妙,尤其适合多核运动控制这种实时性要求极高的场景。
3.1 中断请求系统(IR)—— 中断的“源头”
先说说中断请求系统,也就是IR。你可以把它理解成所有中断事件的“汇集点”。
在AURIX里,外设(比如GPT12、CCU6、VADC)产生中断事件后,并不会直接去找CPU。它们先把信号发给IR模块。IR模块负责把这些原始的脉冲信号,整理成标准的“服务请求”。
我打个比方:IR就像公司前台。各个部门(外设)有急事(中断事件),先打电话给前台。前台登记一下,再转给对应的负责人(CPU)。
IR模块的核心工作就两件:
- 边沿检测:判断是上升沿触发还是下降沿触发。我在做电机编码器接口时,就遇到过边沿抖动导致误触发的问题,后来在IR配置里加了硬件滤波才搞定。
- 电平同步:把异步的外设时钟域信号,同步到系统时钟域来。
3.2 服务请求节点(SRN)—— 中断的“路由器”
IR把中断事件整理好之后,接下来就交给SRN了。SRN的全称是Service Request Node,服务请求节点。
每个外设中断源,都对应一个SRN。比如GPT12的定时器溢出中断,就绑定在SRN[0]上。CCU6的捕获中断,绑定在SRN[1]上。AURIX TC3xx系列有超过200个SRN,数量相当可观。
SRN本质上是一个寄存器,里面存着两样东西:
- 中断优先级(8级,0最低,7最高)
- 目标CPU(CPU0、CPU1、CPU2,或者广播到所有核)
说白了,SRN就是给每个中断源贴了个标签,告诉硬件:“这个中断有多紧急,该由哪个核来处理。”
我个人习惯,在项目初期就把所有SRN的配置表画出来。哪个中断给CPU0,哪个给CPU1,优先级怎么分配,一目了然。否则后期调试多核中断路由问题,会非常痛苦。
3.3 中断优先级仲裁 —— 谁先谁后?
多个中断同时来了怎么办?这就涉及到优先级仲裁了。
AURIX的中断仲裁是硬件完成的,不需要软件干预。仲裁规则很简单:
- 比较所有挂起中断的优先级
- 优先级最高的先响应
- 如果优先级相同,比较SRN编号,编号小的优先
这里有个坑,我必须要提醒大家。我曾经在一个伺服驱动项目里,把电流环中断和速度环中断设成了相同优先级。结果发现电流环偶尔会被速度环打断,导致电流波形出现毛刺。后来我把电流环优先级设为7(最高),速度环设为6,问题就解决了。
3.4 中断路由配置 —— 怎么把中断送到指定核?
配置中断路由,其实就是写SRN寄存器。以TC3xx为例,每个SRN对应一个32位寄存器,地址是连续的。
配置代码大概长这样:
// 假设我们要配置SRN[5](比如是GPT12的定时器中断)
// 目标:CPU1,优先级5
uint32 srn_addr = 0xF003E000 + (5 * 4); // SRN基地址 + 偏移
uint32 config = (1 << 8) | (5 << 0); // bit8=1表示CPU1,bit[2:0]=5表示优先级
*(volatile uint32*)srn_addr = config;
嗯,这里要注意:配置完SRN之后,还要使能CPU核的中断控制器。否则中断信号到了CPU门口,门是关着的,进不去。
使能CPU中断的代码:
// 使能CPU1的中断控制器
IfxCpu_enableInterrupts(&g_cpu1_interrupt);
我刚开始做多核开发时,经常忘记使能CPU中断。结果中断配置了半天,就是不触发。后来我养成了一个习惯:配置完SRN后,立刻检查对应CPU的中断使能位。
3.5 多核中断分发机制 —— 中断怎么“跑”到不同核?
这是AURIX最精彩的部分。多核中断分发,说白了就是让中断信号能准确到达指定的CPU核。
分发路径是这样的:
- 外设产生中断事件 → IR模块
- IR模块输出脉冲 → SRN模块
- SRN根据配置,把中断请求发送到指定CPU的ICU(中断控制单元)
- ICU进行优先级仲裁,然后触发CPU的异常处理
我画了一张图,帮你理解这个流程:
你看,SRN就像个交通枢纽,根据配置把中断请求“分发”到不同的CPU。这种设计的好处是:
- 负载均衡:可以把不同外设的中断分配到不同核,避免单个核过载
- 实时性保障:关键中断(比如电流环)可以独占一个核,不受其他任务干扰
- 灵活性:运行时可以动态修改SRN配置,改变中断路由
3.6 实战经验:中断配置的常见陷阱
最后,分享几个我踩过的坑:
- 中断优先级反转:低优先级中断长时间占用CPU,导致高优先级中断无法及时响应。解决办法是确保高优先级中断的服务程序尽量短小精悍。
- 多核中断竞争:两个核同时访问同一个外设的中断状态寄存器,可能导致数据不一致。我一般会为每个外设分配专属的CPU核,避免竞争。
- 中断嵌套过深:AURIX支持中断嵌套,但嵌套层数太多会导致栈溢出。我建议嵌套不超过3层。
嗯,中断系统就讲到这里。内容不少,但都是干货。你想想看,掌握了这些,AURIX的中断对你来说就不再是黑盒了。