ZHCAF18 February 2025 F29H850TU
在 CPU 上支持实时任务需要使用中断。如果外部传感器检测到故障,则需要中断或停止 CPU,以执行能够处理故障的子例程。在此示例中,信号到达 CPU 时中断的时序至关重要。中断是硬件或软件驱动的信号,可导致 CPU 暂停当前的程序序列并执行子例程。中断通常处理对应用至关重要并需要及时执行的时间关键循环和控制算法。大多数情况下,中断能以已知频率定期发生。但是,在设计软件架构时,您是否曾看到中断波形出现错误振荡,如 图 1 中所示?
首先,需要重点介绍中断延迟的两个概念,即中断传播路径和中断时序。中断传播路径是从触发中断请求到中断服务函数开始的时间。其次,确认在触发中断请求期间或在正常中断执行期间是否存在任何干扰因素。第三,通过合理设置中断优先级(例如中断嵌套和寄存器堆栈恢复/保护)并屏蔽其他中断干扰源,可以保持中断延迟正常执行。
C28x 上的中断传播路径主要分四个阶段处理中断:
大多数编程人员只关注前两个阶段,对后两个阶段的堆栈保护或恢复以及中断响应了解较少。本应用简报将深入探讨第三和第四阶段。
图 2 中断触发源 (F28003x)图 3 展示外设中断如何传播到 CPU。
图 4 展示 C28x 如何生成和响应中断服务函数。
从中断请求触发到中断服务函数 ISR 的中断时序:
除了正确使用中断请求和中断批准操作位(例如 INTM、IER 位),还要考虑以下可能影响中断的干扰因素和中断嵌套。
这两点是可能影响中断时序方式的源头。
关于中断嵌套,中断通过 C28x 硬件自动设置优先级。可在特定器件系列专用的系统控制指南中找到所有中断的优先级。当 C28x CPU 响应低优先级中断时,CPU 会干扰高优先级中断的正常响应,如 图 6 中所述。
因此,应用代码需要在低优先级中断期间添加简单的软件优先级。这使得 CPU 能够在执行低优先级中断时及时响应高优先级中断处理。以下是 C28x 执行中断嵌套的步骤:
// // C28x ISR Code // // Enable nested interrupts // // ADCA1 interrupt for loop Interrput
void INT_myCPUTIMER2_ISR(void)
{
uint16_t TempPIEIER;
TempPIEIER = PieCtrlRegs.PIEIER1.all; // Save PIEIER register for later
IER |= 0x001; // Set global priority by adjusting IER
IER &= 0x001;
PieCtrlRegs.PIEIER1.all &= 0x0001; // Set group priority by adjusting PIEIER1 to //allow INT1.1 to interrupt current CPU time0 ISR
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
asm(" NOP"); // Wait one cycle
EINT; // Clear INTM to enable interrupts
//
// Insert ISR Code here.......
// for now just insert a delay
//
//for(i = 1; i <= 10; i++) {}
//
// Restore registers saved:
//
DINT;
PieCtrlRegs.PIEIER1.all = TempPIEIER;
}
我们的下一代 C29x 架构 F29H85x 支持硬件中断优先级,无需软件开销,并允许中断嵌套。与 C28x 的 40 个周期相比,C29x 架构的所有寄存器在实时中断时由硬件自动保存/恢复,仅需十个周期。
在中断服务程序 (ISR) 中,可通过将 CPU 级别 DSTS.INTE 位设置为活动状态来启用 PIPE 模块中的 INT 嵌套,因为此位在进入 ISR 时禁用,如 图 7 中所述。以下是 C28x 执行中断嵌套的步骤:
// // C29x ISR Code // // Enable nested interrupts // // ADCA1 interrupt for loop Interrput
void INT_myCPUTIMER0_ISR(void)
{
// Set INTE to 1 to enable interrupts here.
ENINT;
// Insert ISR Code here.......
}
以下测试结果通过两个中断得出:150kHz 时的 EPWM 中断(黄色信号)和 1kHz 时的 Timer2 中断(蓝色信号)。Timer2 中断的优先级低于 EPWM 中断。如果未启用 C28x 中断嵌套,EPWM 的中断频率不会是 150kHz,如 图 8 中所示。只有利用 C28x CPU 中断嵌套,才能使 EPWM 中断固定在 150kHz,如 图 9 中所示。测试结果基于 LAUNCHXL-F280039C。如果未通过如上述代码所述的软件方法启用中断嵌套,则会出现异常中断行为。
启用中断嵌套后,即使发生了较低优先级的中断,仍然可以进入和执行较高优先级的中断。这可确保较高优先级的中断频率保持不变。
以下测试结果通过两个中断得出:150kHz 时的 EPWM 中断(粉色信号)和 1kHz 时的 Timer2 中断(绿色信号)。Timer2 中断的优先级低于 EPWM 中断。如果未启用 C29x 中断嵌套,EPWM 的中断频率不会是 150kHz,如 图 10 中所示。只有利用 C29x CPU 中断嵌套,才能使 EPWM 中断固定在 150kHz,如 图 11 中所示。此测试基于 F29x 器件。如果未通过如上述代码所述的软件方法启用中断嵌套,则会出现异常中断行为。
启用中断嵌套后,即使发生了较低优先级的中断,仍然可以进入和执行较高优先级的中断。这可确保较高优先级的中断频率保持不变。
关于不可中断指令 RPT,如果在主程序或状态机中使用大量重复的全局初始化变量(例如 Memcopy、for 循环为相同数组赋值或执行重复操作),C2000 编译器会自动生成 RPT 指令。重复 (RPT) 指令允许单条指令执行 (N + 1) 次,其中 N 指定为 RPT 指令的操作数。该指令执行一次,然后重复 N 次。执行 RPT 时,重复计数器 (RPTC) 会加载 N。然后,每次执行重复指令时,RPTC 递减,直到 RPTC 等于 0。有关 RPT 的说明和可重复指令列表,请参阅 TMS320C28x CPU 和指令集参考指南 的 C28x 汇编语言指令 一章中的 RPT *8bit/loc16 部分。
由于这条 RPT 指令不可中断,它不具备上下文保存堆栈保护或恢复功能。因此,PC 指针此时留在 RPT 中,它可能无法及时响应中断请求,如 图 12 中所述。
因此,您可以使用正确的设置进入 C2000 编译器,也可以避免生成 C 语言使用说明。关于 C2000 编译器,可以更改项目属性 -> C2000 编译器 -> 高级选项 -> 运行时模型选项 -> 启用“不生成 RPT 指令”,如 图 13 中所述。
最后,按照上述 C2000 编译器设置操作,EPWM ISR 将正常工作,如 图 16 中所述。
通过遵守最小中断延迟,中断得以正常执行。然而,影响中断正常执行的因素包括:
本技术文章介绍如何找到影响中断的因素并进行故障排除。