TI C2000 中断系统

0 阅读16分钟

 TI C2000 的中断系统刚开始看起来容易混乱,主要原因是它并不是“所有中断都进 PIE”,也不是“直连 CPU 的中断一定优先级最高”。

真正理解它,可以抓住一句话:

C2000 的中断分为 CPU 直连中断、PIE 扩展中断和软件陷阱类中断。大多数外设先进 PIE,再通过 INT1~INT12 送入 CPU;但 RESET、NMI、RTOSINT、INT13、INT14、DLOGINT 等并不经过 PIE。

其中,PIE 是 C2000 中断系统里最重要、也最容易混淆的部分。


1. C28x CPU 的中断入口

C28x CPU 固定支持 32 个中断向量入口。无论芯片外设有多少,最终都必须映射到 CPU 能识别的这些入口上。

从路径上看,中断大致可以分成三类:

类型代表中断是否经过 PIE说明
CPU 特殊中断 / 异常RESET、EMUINT、NMI、ILLEGAL、USER TrapCPU 内核直接处理,部分属于异常或软件陷阱
PIE 外设中断INT1 ~ INT12大多数外设中断都走这条路径
CPU 直连可屏蔽中断RTOSINT、INT13、INT14、DLOGINT不经过 PIE,但不代表一定高优先级

这三个路径必须分清。

尤其要注意:
直连 CPU 不等于优先级一定高。

例如:

INT13、INT14、DLOGINT 都是 CPU 直连中断,
但它们的硬件优先级低于 INT1~INT12。


2. C28x 硬件中断优先级

下面这张表只列参与硬件优先级仲裁的主要中断。

优先级数字越小,硬件响应优先级越高。

硬件优先级中断名CPU 向量偏移F2833x PIE 表地址路径可屏蔽说明
1RESET0x00000x0D00CPU 直连系统复位,最高优先级
2EMUINT / Reserved0x00220x0D22CPU 直连调试相关CPU Emulation Interrupt
3NMI0x00240x0D24CPU 直连不可屏蔽中断
4RTOSINT0x00200x0D20CPU 直连实时操作系统中断
5INT10x0002PIE Group 1PIEADC、XINT1/2、Timer0、WAKEINT
6INT20x0004PIE Group 2PIEePWM Trip Zone
7INT30x0006PIE Group 3PIEePWM 周期/比较事件
8INT40x0008PIE Group 4PIEeCAP
9INT50x000APIE Group 5PIEeQEP
10INT60x000CPIE Group 6PIESPI、McBSP
11INT70x000EPIE Group 7PIEDMA
12INT80x0010PIE Group 8PIEI2C、SCI-C
13INT90x0012PIE Group 9PIESCI-A/B、eCAN-A/B
14INT100x0014PIE Group 10PIEF2833x 中保留
15INT110x0016PIE Group 11PIEF2833x 中保留
16INT120x0018PIE Group 12PIEXINT3~7、FPU LVF/LUF
17INT130x001A0x0D1ACPU 直连XINT13 或 CPU Timer1,器件相关
18INT140x001C0x0D1CCPU 直连CPU Timer2
19DLOGINT / DATALOG0x001E0x0D1ECPU 直连Data Logging Interrupt,硬件优先级最低

这里有几个特别容易记错的点:

  1. RTOSINT 不是最低优先级,它的硬件优先级是 4。
  2. DLOGINT 才是硬件优先级最低的 CPU 中断。
  3. NMI 的 CPU 向量偏移是 0x0024,不是 0x0044。
  4. ILLEGAL 不适合混进普通外设中断优先级表,它属于非法操作陷阱。

3. USER1~USER12:软件 Trap,不是普通外设中断

C28x 还有 USER1~USER12 这些用户软件向量。

它们不要和 INT1~INT14、RTOSINT、DLOGINT 这种硬件中断混在一起理解。

向量CPU 向量偏移F2833x PIE 表地址触发方式说明
USER10x00280x0D28TRAP用户自定义软件陷阱
USER20x002A0x0D2ATRAP用户自定义软件陷阱
USER30x002C0x0D2CTRAP用户自定义软件陷阱
USER40x002E0x0D2ETRAP用户自定义软件陷阱
USER50x00300x0D30TRAP用户自定义软件陷阱
USER60x00320x0D32TRAP用户自定义软件陷阱
USER70x00340x0D34TRAP用户自定义软件陷阱
USER80x00360x0D36TRAP用户自定义软件陷阱
USER90x00380x0D38TRAP用户自定义软件陷阱
USER100x003A0x0D3ATRAP用户自定义软件陷阱
USER110x003C0x0D3CTRAP用户自定义软件陷阱
USER120x003E0x0D3ETRAP用户自定义软件陷阱

注意两个地址:

0x001E 是 DLOGINT
0x0020 是 RTOSINT

它们不是 USER1 / USER2。

USER1~USER12 是从:

0x0028 ~ 0x003E

这一段开始的。


4. PIE 的作用:把 12 条 CPU 中断线扩展成 96 个外设槽位

PIE 的全称是:

Peripheral Interrupt Expansion

也就是外设中断扩展模块。

C28x CPU 只有 INT1~INT12 这 12 条主要外设中断入口,但片上外设数量远远超过 12 个,所以 TI 设计了 PIE。

PIE 的结构是:

12 个 PIE 组 × 每组 8 个中断槽位 = 96 个 PIE 中断入口

也就是说:

外设中断
→ PIE 某一组某一槽位
→ CPU INT1~INT12
→ CPU 响应中断

PIE 的优先级分两层:

组间优先级:
INT1 > INT2 > INT3 > ... > INT12

组内优先级:
INTx.1 > INTx.2 > INTx.3 > ... > INTx.8

例如:

INT1.1 和 INT8.1 同时发生,先响应 INT1.1
INT1.1 和 INT1.8 同时发生,先响应 INT1.1


5. F2833x PIE 中断向量表

下面以 F2833x 为例整理 PIE 表。

表格按 INTx.1 → INTx.8 排列,也就是从高优先级到低优先级。

CPU 中断INTx.1 最高INTx.2INTx.3INTx.4INTx.5INTx.6INTx.7INTx.8 最低
INT1SEQ1INTSEQ2INTReservedXINT1XINT2ADCINTTINT0WAKEINT
INT2EPWM1_TZINTEPWM2_TZINTEPWM3_TZINTEPWM4_TZINTEPWM5_TZINTEPWM6_TZINTReservedReserved
INT3EPWM1_INTEPWM2_INTEPWM3_INTEPWM4_INTEPWM5_INTEPWM6_INTReservedReserved
INT4ECAP1_INTECAP2_INTECAP3_INTECAP4_INTECAP5_INTECAP6_INTReservedReserved
INT5EQEP1_INTEQEP2_INTReservedReservedReservedReservedReservedReserved
INT6SPIRXINTASPITXINTAMRINTBMXINTBMRINTAMXINTAReservedReserved
INT7DINTCH1DINTCH2DINTCH3DINTCH4DINTCH5DINTCH6ReservedReserved
INT8I2CINT1AI2CINT2AReservedReservedSCIRXINTCSCITXINTCReservedReserved
INT9SCIRXINTASCITXINTASCIRXINTBSCITXINTBECAN0INTAECAN1INTAECAN0INTBECAN1INTB
INT10ReservedReservedReservedReservedReservedReservedReservedReserved
INT11ReservedReservedReservedReservedReservedReservedReservedReserved
INT12XINT3XINT4XINT5XINT6XINT7ReservedLVFLUF

如果看到有些资料把表头写成:

INTx.8 → INTx.1

那就要注意方向。

INTx.1 才是组内最高优先级,INTx.8 是组内最低优先级。


6. 各 PIE 组功能速查

PIE 组主要功能典型用途
INT1ADC、XINT1/2、Timer0、WAKEINTADC 采样完成、外部 GPIO 中断、系统节拍
INT2ePWM Trip Zone过流、过压、硬件保护关断
INT3ePWM 周期/比较中断电机控制、电源控制、PWM 更新节拍
INT4eCAP输入捕获、测速、测脉宽
INT5eQEP编码器位置、速度、方向反馈
INT6SPI、McBSP串行通信、音频/同步接口
INT7DMA数据搬运完成通知
INT8I2C、SCI-C板级通信、扩展串口
INT9SCI-A/B、eCAN-A/B上位机通信、CAN 总线
INT10ReservedF2833x 中保留
INT11ReservedF2833x 中保留
INT12XINT3~7、FPU 异常外部 GPIO 中断、浮点异常

7. 中断源的分流路径

7.1 CPU Timer

三个 CPU Timer 的路径并不一样。

中断源去向是否经过 PIE说明
CPU Timer0PIE Group 1,INT1.7普通系统节拍中断
CPU Timer1INT13CPU 直连,常用于系统或 RTOS
CPU Timer2INT14CPU 直连,常用于系统或 RTOS

所以,不能说“三个 CPU Timer 都进 PIE”。

准确说是:

Timer0 进 PIE
Timer1 / Timer2 直连 CPU


7.2 普通片内外设

大多数片内外设都走 PIE。

例如:

ADC      → PIE Group 1
ePWM TZ  → PIE Group 2
ePWM INT → PIE Group 3
eCAP     → PIE Group 4
eQEP     → PIE Group 5
SPI      → PIE Group 6
DMA      → PIE Group 7
I2C/SCI  → PIE Group 8/9
XINT3~7  → PIE Group 12


7.3 外部引脚中断

外部信号去向说明
XRS / ResetRESET系统复位入口,最高优先级
XNMINMI不可屏蔽中断
XINT1PIE Group 1,INT1.4外部 GPIO 中断
XINT2PIE Group 1,INT1.5外部 GPIO 中断
XINT3~XINT7PIE Group 12,INT12.1~INT12.5更多外部 GPIO 中断
XINT13INT13与 Timer1 相关,具体看器件配置

8. PIE 中断响应流程

一个典型的 PIE 外设中断,从产生到进入 ISR,大致经历下面这些步骤:

1. 外设事件发生

2. 外设自己的中断标志位置位

3. 外设自己的中断使能打开

4. PIEIFRx.y 置位

5. PIEIERx.y 允许该槽位

6. PIEACKx 当前允许该组送中断

7. CPU IFRx 置位

8. CPU IERx 允许该 CPU 中断级

9. INTM = 0,全局中断允许

10. CPU 完成当前指令,清流水线,保存上下文

11. CPU 从 PIE 向量表取 ISR 地址

12. 进入 ISR

13. ISR 中清外设中断标志

14. ISR 末尾写 PIEACK,释放该 PIE 组

15. IRET 返回

可以把它理解为三层开关:

外设层:外设自己的中断使能
PIE 层:PIEIERx.y
CPU 层:IER + INTM

三层都打开,中断才真正能进 CPU。


9. PIEACK 是什么

PIEACK 是很多人写 C2000 中断时最容易漏掉的东西。

它不是某一个外设的中断标志,而是 PIE 组级应答锁

PIEACK 状态含义
PIEACKx = 0该组可以继续向 CPU 送中断
PIEACKx = 1该组已经有中断送入 CPU,同组其他中断暂时被挡住
写 1 到 PIEACKx清除该组 ACK,允许该组后续中断进入

所以在 ISR 里,除了清外设自己的中断标志,还要清 PIEACK。

否则会出现这种现象:

第一次中断能进来,
后面同组中断再也进不来。

本质上不是外设坏了,而是 PIE 组被 ACK 锁住了。


10. 推荐的 ISR 写法

以 ePWM1 中断为例:

interrupt void epwm1_isr(void)
{
    /*
     * 1. 执行用户中断处理逻辑
     *    ISR 里尽量不要做耗时任务。
     */
    // control_loop();

    /*
     * 2. 清外设中断标志
     */
    EPwm1Regs.ETCLR.bit.INT = 1;

    /*
     * 3. 最后清 PIEACK
     *    EPWM1_INT 属于 PIE Group 3
     */
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}

比较稳的习惯是:

先处理业务
再清外设标志
最后清 PIEACK

不建议一进 ISR 就清 PIEACK。
尤其是在 ISR 里可能重新打开全局中断的情况下,过早清 PIEACK 可能让同组中断过早参与嵌套,调试会更麻烦。


11. PIE 中断初始化流程

典型初始化流程如下:

/*
 * 1. 关闭全局中断
 */
DINT;

/*
 * 2. 初始化 PIE 控制器和 PIE 向量表
 */
InitPieCtrl();
InitPieVectTable();

/*
 * 3. 修改 PIE 向量表,绑定 ISR 函数
 */
EALLOW;
PieVectTable.EPWM1_INT = &epwm1_isr;
PieVectTable.ADCINT    = &adc_isr;
EDIS;

/*
 * 4. 使能 PIE 组内中断
 */
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;    // EPWM1_INT,Group 3,INTx.1
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;    // ADCINT,Group 1,INTx.6

/*
 * 5. 使能 CPU 层中断
 */
IER |= M_INT3;
IER |= M_INT1;

/*
 * 6. 开全局中断和实时调试中断
 */
EINT;
ERTM;

这里要注意两点:

第一,PIE 向量表在 RAM 中,需要用户初始化。
第二,只开 PIEIER 不够,还必须开 CPU IER 和全局中断 INTM。


12. 中断嵌套

C28x 默认进入一个可屏蔽中断后,会自动置位 INTM,阻止新的普通可屏蔽中断打断当前 ISR。

也就是说,默认情况下:

ISR 不会被其他普通中断自动抢占

如果需要中断嵌套,需要在 ISR 中手动处理:

1. 配置好 IER / PIEIER,确保只允许希望嵌套的高优先级中断
2. 根据需要处理 PIEACK
3. 在 ISR 中重新开全局中断,例如 EINT 或 CLRC INTM

中断嵌套虽然能降低高优先级中断延迟,但也会带来几个问题:

风险说明
栈空间增加嵌套越深,保存上下文越多
同组中断复杂PIEACK 处理不当容易乱
共享变量冲突ISR 之间可能同时访问同一资源
调试困难时序不再线性

所以在控制类应用中,常见做法是:

高频 ISR 尽量短
低频任务放后台
非必要不做复杂嵌套


13. 中断延迟

C28x 的中断入口开销常用 8 cycles 来估算,但实际延迟不应该只看这个数字。

真实延迟还会受到这些因素影响:

影响因素说明
当前正在执行的指令CPU 通常要完成当前指令后才响应
流水线状态进入中断前需要清流水线
PIE 仲裁PIE 中断还要经过组间/组内仲裁
Flash wait-stateISR 或向量表在 Flash 中会增加等待
编译器保存寄存器C 语言 ISR 会有额外现场保护
是否从 IDLE 唤醒唤醒路径可能增加延迟

所以更准确的写法是:

8 cycles 是基础入口开销,实际 ISR 响应延迟要结合代码位置、编译器、外设同步和系统状态一起估算。


14. PIEIFR 不要随便清

还有一个很实战的坑:

不要随便用软件读-改-写方式清 PIEIFR。

PIEIFR 是 PIE 层的中断标志寄存器。很多情况下,PIEIFR 会在中断被正确响应时由硬件处理。

如果软件随便清 PIEIFR,尤其是读-改-写操作,很可能出现:

刚来的中断被误清掉

结果就是偶发性丢中断,调试起来非常痛苦。

一般 ISR 里更应该关注:

清外设自己的中断标志
清 PIEACK

而不是随便操作 PIEIFR。


15. PIE 中断和 CPU 直连中断的区别

对比项PIE 中断CPU 直连中断
典型对象ADC、ePWM、SCI、SPI、CAN、DMA 等RESET、NMI、RTOSINT、INT13、INT14、DLOGINT
路径外设 → PIE → CPU INT1~INT12中断源 → CPU
数量最多 96 个外设槽位固定少量 CPU 入口
使能层级外设使能 + PIEIER + CPU IER + INTM通常 CPU IER + INTM;RESET/NMI 例外
清标志外设标志 + PIEACK一般清对应外设/CPU 标志
优先级INT1INT12,组内 INTx.1INTx.8按 CPU 固定硬件优先级

16. F281x、F2833x 和其他 C2000 器件的区别

C2000 系列很多,不同器件的外设和 PIE 分配并不完全一样。

可以这样理解:

内容是否通用
C28x CPU 有 32 个中断向量大体通用
PIE 是 12 组 × 8 槽的结构经典 C2000 器件中常见
INT1~INT12 的 CPU 优先级顺序通用
PIE 组内 INTx.1 高于 INTx.8通用
某个外设具体在哪个 PIE 槽位不通用,必须查具体芯片手册
F281x 和 F2833x 的外设命名/分配不完全一样
带 CLA 的器件 PIE 分配要看具体型号

例如,F2833x / F2823x 的官方 PIE 表中,INT10 和 INT11 都是 Reserved。
但一些更新的 C2000 器件可能会把 CLA、更多 ADC、CMPSS 等中断映射到不同 PIE 组。

所以笔记里最好写成:

CPU 中断机制可以通用理解,但 PIE 外设映射必须以具体芯片 TRM 为准。


17. 常见误区总结

误区正确理解
三个 CPU Timer 都走 PIE错。Timer0 走 PIE,Timer1/2 直连 CPU
直连 CPU 一定高优先级错。INT13、INT14、DLOGINT 直连 CPU,但优先级低于 INT1~INT12
DLOGINT / RTOSINT 是不可屏蔽仿真中断错。它们在 IER 中有使能位,是可屏蔽中断
USER1 / USER2 在 0x001E / 0x0020错。0x001E 是 DLOGINT,0x0020 是 RTOSINT
USER 中断由 INTR 触发错。USER1~USER12 由 TRAP 指令触发
PIEACK 不清也没事错。不清 PIEACK,同组后续中断会被挡住
PIEIFR 可以随便软件清错。可能造成丢中断
PIE 优先级可以随便改错。组间和组内硬件优先级固定
F281x / F2833x PIE 表可以混用错。CPU 机制相似,但 PIE 映射必须查具体芯片
ISR 越长越好处理错。ISR 应尽量短,把耗时任务放到后台

18. 最后总结

C2000 的中断系统可以按照下面这张逻辑图理解:

特殊 CPU 中断:
RESET / EMUINT / NMI / RTOSINT
→ CPU 直接响应,优先级较高

普通外设中断:
ADC / ePWM / SCI / SPI / CAN / DMA / XINT 等
→ PIE
→ INT1~INT12
→ CPU

CPU 直连低优先级中断:
INT13 / INT14 / DLOGINT
→ 不经过 PIE
→ 但优先级低于 INT1~INT12

软件陷阱:
ILLEGAL / USER1~USER12
→ CPU Trap 类向量

真正写代码时,最关键的是三件事:

1. 使能外设中断、PIEIER、CPU IER 和全局中断
2. 在 ISR 中清外设中断标志
3. 在 ISR 末尾清 PIEACK

只要这三层逻辑理清,C2000 的中断系统就不再是“很多表格堆在一起”,而是一套非常明确的分流、仲裁和应答机制。