TMS320F280025 中断机制interrupt
文章目录
外设中断
中断的概念
中断是一个信号,它导致CPU暂停当前的执行,并分支到称为中断服务例程(ISR)的另一段代码。这是处理外设事件的有用机制,并且比寄存器轮询涉及更少的CPU开销或程序复杂性。但是,由于中断对程序流是异步的,因此必须小心避免在中断和主程序代码中访问的资源上发生冲突。
中断通过一系列标志寄存器和使能寄存器传播到CPU。标志寄存器存储中断,直到它被处理。启用寄存器阻止中断的传播。当中断信号到达CPU时,CPU从一个称为向量表的列表中获取适当的ISR地址。
中断架构
C28x CPU有14条外设中断线。其中两个(INT13和INT14)分别直接连接到CPU定时器1和2。其余12个通过增强型外设中断扩展模块(ePIE,或简称PIE)连接到外设中断信号。PIE将多达16个外设中断多路复用到每条CPU中断线上。它还扩展了向量表,允许每个中断拥有自己的ISR。这使得CPU可以支持大量的外设。
中断路径分为三个阶段——外设、PIE和CPU。每个阶段都有自己的启用寄存器和标志寄存器。该系统允许CPU处理一个中断,而其他正在等待,实现和优先级嵌套中断在软件中,并在某些关键任务期间禁用中断。
280025的中断架构
外设阶段
每个外设都有自己独特的中断配置,这在该外设的章节中进行了描述。有些外设允许多个事件触发相同的中断信号。例如,通信外设可能使用相同的中断来指示数据已被接收或出现传输错误。
中断的原因可以通过读取外设的状态寄存器来确定。通常,在产生另一个中断之前,必须手动清除状态寄存器中的位
PIE阶段
PIE为每个外设中断信号提供单独的标志和启用寄存器位,这些信号有时被称为PIE通道。这些通道根据相关的CPU中断进行分组。每个PIE组有一个16位的使能寄存器(PIEIERx),一个16位的标志寄存器(PIEIFRx)和一个在PIE确认寄存器(PIEACK)中的位。PIEACK寄存器位作为整个PIE组的公共中断掩码
当CPU接收到中断时,CPU从PIE中获取ISR的地址。PIE返回标记和启用的组中编号最低的通道的向量。这使得编号较低的中断在多个中断挂起时具有更高的优先级。
如果没有标记和启用中断,则PIE返回通道1的向量。除非中断传播时软件改变了PIE的状态,否则这种情况不会发生。第3.5.4节包含在启用中断后安全修改PIE配置的过程。
CPU阶段
与PIE一样,CPU为每个中断提供标志和启用寄存器位。有一个启用寄存器(IER)和一个标志寄存器(IFR),它们都是CPU内部寄存器。还有一个全局中断掩码,它由ST1寄存器中的INTM位控制。这个掩码可以使用CPU的SETC和CLRC指令来设置和清除。在C代码中,C2000Ware的DINT和EINT宏可用于此目的。
对IER和INTM的写入是原子操作。特别是,如果设置了INTM,管道中的下一条指令在禁用中断的情况下运行。不需要软件延迟。
中断进入顺序
外设中断如何传播到CPU
当外设产生中断(在PIE组x上,通道y上)时,它触发以下事件序列:
- 中断锁存在PIEIFRx.y中。
- 如果PIEIERx.y被设置,中断传播。
- 如果PIEACK.x被清除,中断传播和PIEACK.x是固定的。
- 中断在IFR.x中被锁存。
- 如果IER.x被设置,中断传播。
- 如果INTM清除,则CPU接收中断。
- D2或后续阶段的任何指令都将运行至结束。较早阶段的指令被刷新。
- CPU将上下文保存在堆栈上。
- IFR.x和IER.X被清除。已设置INTM。清除EALLOW。
- CPU从PIE中获取ISR向量。PIEIFRx.y被清除。
- CPU分支到ISR。
中断延迟是PIEIFRx之间的时间。锁存中断和进入CPU管道执行阶段的第一条ISR指令。**最小中断延迟为14 SYSCLK周期。**ISR或堆栈内存上的等待状态增加了延迟。**外部中断为GPIO同步添加了至少两个SYSCLK周期,并为输入确认添加了额外的时间(如果使用的话)。**使用C28x RPT指令创建的循环不能被中断。
配置和使用中断
在上电时,默认情况下不启用中断。清除PIEIER和IER寄存器并设置INTM。
应用程序代码负责配置和启用所有外围中断。
启用中断
启用外设中断的步骤如下:
- 全局禁用中断(DINT或SETC INTM)。
- 通过设置PIECTRL寄存器的ENPIE位来启用PIE。
- 将每个中断的ISR向量写入PIE向量表中的适当位置。注意,向量表是EALLOW保护的。
- 为每个中断设置适当的PIEIER.x位。PIE组和信道分配可以后面找到。
- 为任何包含已启用中断的PIE组设置CPU IER位。
- 在外设中启用中断。
- 全局启用中断(EINT或CLRC INTM)。
步骤4不适用于直接连接CPU的Timer1和Timer2中断。
处理中断
ISR与正常功能类似,但必须完成以下操作:
- 保存和恢复某些CPU寄存器的状态(如果使用)。
- 为中断组清除PIEACK位。
- 使用IRET指令返回。
如果使用__interrupt关键字定义函数,则TMS320C28x C编译器会自动处理需求1和3。有关此关键字的信息,请参见TMS320C28x优化C/ c++编译器v6.2.4用户指南中的关键字部分。有关编写汇编代码来处理中断的信息,请参阅TMS320C28x CPU和指令集参考指南的可屏蔽中断的标准操作部分。
中断组的PIEACK位必须在用户代码中手动清除。这通常在ISR结束时完成。如果PIEACK位没有被清除,CPU不会从该组接收任何进一步的中断。这不适用于不经过PIE的Timer1和Timer2中断。
禁用中断
要禁用所有中断,请使用DINT或SETC INTM设置CPU的全局中断掩码。在设置INTM或修改IER后不需要添加nop——下一条指令在禁用中断的情况下执行。
可以使用PIEIERx寄存器禁用单个中断,但必须注意避免竞态条件。如果一个中断信号已经在PIEIER写完成时传播,中断信号可以到达CPU并触发一个伪中断条件。为避免这种情况,请使用以下步骤:
- 全局禁用中断(DINT或SETC INTM)。
- 为中断清除PIEIER位。
- 等待5个周期,以确保任何传播中断已到达CPU IFR寄存器。
- 清除中断的PIE组的CPU IFR位。
- 为中断的PIE组清除PIEACK位。
- 全局启用中断(EINT或CLRC INTM)。
中断组可以使用CPU IER寄存器禁用。这不会导致竞争条件,因此不需要特殊的过程。
由于读/修改/写操作可能导致传入中断丢失,因此PIEIFR位在软件中永远不能被清除。清除PIEIFR位的唯一安全方法是让CPU进行中断。绕过正常ISR的步骤如下: - 全局禁用中断(DINT或SETC INTM)。
- 修改PIE向量表,将piifr位的中断向量映射到一个空的ISR。这个ISR只包含中断指令(IRET)的返回。
- 在外围寄存器中禁用中断。
- 全局启用中断(EINT或CLRC INTM)。
- 等待挂起的中断由空ISR提供服务。
- 全局禁用中断。
- 修改PIE向量表,将中断向量映射回原来的ISR。
- 为中断的PIE组清除PIEACK位。
- 全局启用中断。
嵌套中断
默认情况下,中断不嵌套。可以使用软件控制IER和PIEIERx寄存器来嵌套中断并确定中断的优先级。示例代码可以在C2000Ware中找到,文档可以在software-dl.ti.com/C2000/docs/c28x_interrupt_nesting/html/index.html上找到。
矢量地址有效性检查
ePIE向量表有两个副本。主向量表位于地址0xD00 - 0xEFF。
冗余向量表位于地址0x01000D00 - 0x01000EFF。对主向量地址的写操作同时写入两个表,而对冗余向量地址的写操作只写入冗余表。
两个表都是独立读取的。
在矢量获取期间,ePIE对两个矢量表输出执行硬件比较。如果两个向量表之间不匹配,CPU分支到PIEVERRADDR寄存器中的地址,ePIE向pwm发送跳闸信号。如果未设置PIEVERRADDR寄存器值,则使用地址为0x003FFFBE的默认引导ROM处理程序。
PIE通道映射
显示了每个外围中断的PIE组和通道分配。每一行是一个组,每一列是该组中的一个通道。当多个中断挂起时,编号最低的通道即编号最低的组首先得到服务。因此,位于表顶部的中断具有最高优先级,而位于表底部的中断具有最低优先级。
标记为“-”的单元格是保留的
PIE中断优先级
信道优先级
对于每个PIE组,组中数量少的通道具有最高优先级。例如,在PIE组1中,通道1.1优先于通道1.3。如果这两个启用的中断同时发生,则首先为通道1.1提供服务,通道1.3处于挂起状态。一旦通道1.1的ISR完成,并且没有其他已启用和挂起的PIE组1中断,通道1.3就会得到服务。然而,为了使CPU能够处理来自PIE组的任何更多中断,必须清除该组的PIEACK。对于这个特定的例子,为了服务通道1.3,通道1.1的ISR必须清除组1的PIEACK。
下面的示例描述了另一种场景:通道1.1目前正在由CPU服务,通道1.3正在挂起,在通道1.1的ISR完成之前,通道1.2也已启用。
由于通道1.2具有比通道1.3更高的优先级,CPU服务通道1.2和通道1.3仍然处于挂起状态。使用中断进入序列(章节3.5.3)的步骤,通道1.2中断可以发生在步骤10 (CPU从PIE获取ISR向量)。PIEIFRx.Y被清除),并在通道1.3之前服务。
组优先级
一般来说,最低的PIE组中最低的通道优先级最高。通道1.1和2.1就是一个例子。这两个渠道在各自的群体中具有最高的优先级。如果这两个启用的通道的中断同时发生,并且没有其他启用的和挂起的中断,则通道1.1首先由CPU服务,通道2.1留下挂起。
但是,在某些情况下通道优先级会取代组优先级。这种特殊情况的发生取决于CPU当前在中断进入序列中的哪一步。
下面是这种特殊情况的一个例子。
- CPU即将为通道2.3提供服务,目前正在执行中断进入顺序(章节3.5.3)中的步骤。
- 当CPU到达第10步时(CPU从PIE中获取ISR向量)。PIEIFRx.Y被清除),两个启用的中断:通道1.1和通道2.1进入。
- 由于通道优先级,通道2.1优先于通道2.3。但是,组优先级要求通道1.1优先于通道2.1和2.3。
- 通道优先级取代这里,通道2.1优先于1.1和2.3。
- 通道2.1完成后,通道1.1被服务,然后是通道2.3。
只有当当前没有中断被服务时,也就是说,中断进入序列(章节3.5.3)没有执行时,才维持组优先级。
矢量表
显示了CPU中断向量表。在这个设备中不使用INT1 - INT12的向量。复位向量是从引导ROM中获取的,而不是从这个表中。所有载体都是EALLOW保护的。
寄存器
PIE_CTRL_REGS Registers
PIECTRL Register控制寄存器 (Offset = 0h) [Reset = 0000h]
PIEACK Register (Offset = 1h) [Reset = 0000h]
Acknowledge Register
当中断从ePIE传播到CPU中断线时,中断组的PIEACK位被设置。这可以防止该组中的其他中断在处理第一个中断时传播到CPU。写一个1到一个PIEACK位清除它,并允许另一个中断从相应的组传播。PIE中断的isr应该在从中断返回之前清除组的PIEACK位。
0的写入将被忽略。
PIEIER1 Register中断组1使能寄存器 (Offset = 2h) [Reset = 0000h]
这些寄存器位单独启用组内的中断。它们的行为非常像CPU中断使能寄存器(IER)中的位。
将一个位设置为1允许相应的中断传播到CPU。
将一个位设置为0可以防止相应的中断传播。注意外设中断信号仍然可以为被禁用的中断设置PIEIFR位
PIEIFR1 Register中断组1标志寄存器 (Offset = 3h) [Reset = 0000h]
这些寄存器位表示组中的每个中断当前是否处于挂起状态。它们的行为非常像CPU中断标志寄存器(IFR)中的位。
当外设发送中断时,相应的位被设置。当中断传播到CPU时,这个位被清除,此时设置了PIEACK。
注意:PIE IFR标志可以写入来创建软件中断。
当写入为零时,IFR标志将被清除。因此,当意图是触发一个中断时,它可能会导致无意中取消其他中断。建议仅在测试中使用它,或者在应用程序代码中非常谨慎地使用它。读取PIE IFR寄存器是安全的。