ZHCAF18 February   2025 F29H850TU

 

  1.   1
  2.   2
  3.   商标

引言

在 CPU 上支持实时任务需要使用中断。如果外部传感器检测到故障,则需要中断或停止 CPU,以执行能够处理故障的子例程。在此示例中,信号到达 CPU 时中断的时序至关重要。中断是硬件或软件驱动的信号,可导致 CPU 暂停当前的程序序列并执行子例程。中断通常处理对应用至关重要并需要及时执行的时间关键循环和控制算法。大多数情况下,中断能以已知频率定期发生。但是,在设计软件架构时,您是否曾看到中断波形出现错误振荡,如 图 1 中所示?

 异常中断振荡(CH4:通过 GPIO 切换中断;Ch3:发生 ePWM ZRO 事件时触发中断,红色信号:示波器的频率趋势测量)图 1 异常中断振荡(CH4:通过 GPIO 切换中断;Ch3:发生 ePWM ZRO 事件时触发中断,红色信号:示波器的频率趋势测量)

中断传播路径和中断时序

首先,需要重点介绍中断延迟的两个概念,即中断传播路径和中断时序。中断传播路径是从触发中断请求到中断服务函数开始的时间。其次,确认在触发中断请求期间或在正常中断执行期间是否存在任何干扰因素。第三,通过合理设置中断优先级(例如中断嵌套和寄存器堆栈恢复/保护)并屏蔽其他中断干扰源,可以保持中断延迟正常执行。

C28x 上的中断传播路径主要分四个阶段处理中断:

  1. 接收中断请求。如 图 2 中所述,必须通过软件中断(来自程序代码)或硬件中断(来自引脚或片上器件)请求才能暂停当前程序序列。
  2. 批准中断。C28x 必须批准中断请求。如果中断可屏蔽,则必须满足某些条件,C28x 才能批准中断请求。对于不可屏蔽的硬件中断和软件中断,将立即批准,如 图 3 中所述。
  3. 准备中断服务例程并保存寄存器值,如 图 4 中所述。
  4. 执行中断服务例程。这是中断循环处理入口,调用 ISR。

大多数编程人员只关注前两个阶段,对后两个阶段的堆栈保护或恢复以及中断响应了解较少。本应用简报将深入探讨第三和第四阶段。

 中断触发源 (F28003x)图 2 中断触发源 (F28003x)

图 3 展示外设中断如何传播到 CPU。

 中断传播路径图 3 中断传播路径

图 4 展示 C28x 如何生成和响应中断服务函数。

 中断 PIE 初始化代码流程图 4 中断 PIE 初始化代码流程

从中断请求触发到中断服务函数 ISR 的中断时序:

  1. 最小延迟(到 ISR 中发生实际工作的时间),14 或 16 个周期:以 F280039C 120MHz CPU 为例,最小延迟(加上所有寄存器在准备实时中断时自动保存或恢复可能为 40 个周期)约为 50 个周期/415ns 延迟。
  2. 最大延迟:取决于 C28x 处理堆栈保护和恢复、等待状态、INTM,以及不可中断 RPT 指令的周期,如 图 5 中所述。
 中断延迟流程图 5 中断延迟流程

除了正确使用中断请求和中断批准操作位(例如 INTM、IER 位),还要考虑以下可能影响中断的干扰因素和中断嵌套。

中断嵌套和干扰因素

  • 当 C28x 正在执行中断或响应高优先级中断时,默认情况下,该中断无法继续响应其他低优先级中断。但是,可以通过一些步骤在当前中断内启用其他中断的服务。这称为中断嵌套。
  • 当如 RPT 指令之类的不可中断指令执行时间过长或过于频繁时,C28x CPU 无法及时响应中断。

这两点是可能影响中断时序方式的源头。

中断嵌套

关于中断嵌套,中断通过 C28x 硬件自动设置优先级。可在特定器件系列专用的系统控制指南中找到所有中断的优先级。当 C28x CPU 响应低优先级中断时,CPU 会干扰高优先级中断的正常响应,如 图 6 中所述。

 中断 PIE 通道映射图 6 中断 PIE 通道映射

因此,应用代码需要在低优先级中断期间添加简单的软件优先级。这使得 CPU 能够在执行低优先级中断时及时响应高优先级中断处理。以下是 C28x 执行中断嵌套的步骤:

  1. 设置全局优先级:
    1. 修改 IER 寄存器,以允许为用户优先级较高的 CPU 中断提供服务。(注意:此时 IER 已保存在堆栈中。)
  2. 设置组优先级:
    1. 修改相应的 PIEIERx 寄存器,以允许为用户设置优先级较高的组中断提供服务。(注意:除了此 ISR 服务的组以外,不要清除其他组的 PIEIER 寄存器位。这样做可能会导致发生错误的中断。)
  3. 启用中断:执行此操作有三个步骤:
    1. 清除 PIEACK 位。
    2. 等待至少一个周期。
    3. 清除 INTM 位。使用汇编语句 asm(" CLRC INTM");或者 TI 示例使用 #define EINT asm(" CLRC INTM")。
  4. 运行 ISR 的主要部分。
  5. 设置 INTM 以禁用中断。使用 asm(” SETC INTM”);或者 TI 示例使用 #define DINT asm(” SETC INTM”)。
  6. 恢复 PIEIERx(可选,具体取决于步骤 2
  7. 从 ISR 返回:
    1. 这将自动恢复 INTM 和 IER。同时,示例代码如下:
      // // 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 架构的所有寄存器在实时中断时由硬件自动保存/恢复,仅需十个周期。

 C29x 中断分组概述图 7 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.......                         

}

C28x 中断嵌套测试结果

以下测试结果通过两个中断得出:150kHz 时的 EPWM 中断(黄色信号)和 1kHz 时的 Timer2 中断(蓝色信号)。Timer2 中断的优先级低于 EPWM 中断。如果未启用 C28x 中断嵌套,EPWM 的中断频率不会是 150kHz,如 图 8 中所示。只有利用 C28x CPU 中断嵌套,才能使 EPWM 中断固定在 150kHz,如 图 9 中所示。测试结果基于 LAUNCHXL-F280039C。如果未通过如上述代码所述的软件方法启用中断嵌套,则会出现异常中断行为。

启用中断嵌套后,即使发生了较低优先级的中断,仍然可以进入和执行较高优先级的中断。这可确保较高优先级的中断频率保持不变。

 C28x 中断嵌套禁用测试结果(CH1:EPWM 中断,CH2:TIMER2 中断)图 8 C28x 中断嵌套禁用测试结果(CH1:EPWM 中断,CH2:TIMER2 中断)
 C28x 中断嵌套启用测试结果(CH1:EPWM 中断,CH2:TIMER2 中断)图 9 C28x 中断嵌套启用测试结果(CH1:EPWM 中断,CH2:TIMER2 中断)

C29x 中断嵌套测试结果

以下测试结果通过两个中断得出:150kHz 时的 EPWM 中断(粉色信号)和 1kHz 时的 Timer2 中断(绿色信号)。Timer2 中断的优先级低于 EPWM 中断。如果未启用 C29x 中断嵌套,EPWM 的中断频率不会是 150kHz,如 图 10 中所示。只有利用 C29x CPU 中断嵌套,才能使 EPWM 中断固定在 150kHz,如 图 11 中所示。此测试基于 F29x 器件。如果未通过如上述代码所述的软件方法启用中断嵌套,则会出现异常中断行为。

启用中断嵌套后,即使发生了较低优先级的中断,仍然可以进入和执行较高优先级的中断。这可确保较高优先级的中断频率保持不变。

 C29x 中断嵌套禁用测试结果(CH1:EPWM 中断,CH2:TIMER2 中断)图 10 C29x 中断嵌套禁用测试结果(CH1:EPWM 中断,CH2:TIMER2 中断)
 C29x 中断嵌套启用测试结果(CH1:EPWM 中断,CH2:TIMER2 中断)图 11 C29x 中断嵌套启用测试结果(CH1:EPWM 中断,CH2:TIMER2 中断)

不可中断指令影响中断时序

关于不可中断指令 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 中所述。

 RPT 指令简介图 12 RPT 指令简介

因此,您可以使用正确的设置进入 C2000 编译器,也可以避免生成 C 语言使用说明。关于 C2000 编译器,可以更改项目属性 -> C2000 编译器 -> 高级选项 -> 运行时模型选项 -> 启用“不生成 RPT 指令”,如 图 13 中所述。

 关于 RPT 指令的 C2000 编译器设置图 13 关于 RPT 指令的 C2000 编译器设置
 由上述函数生成的 RPT 指令图 14 由上述函数生成的 RPT 指令
 源代码图 15 源代码

最后,按照上述 C2000 编译器设置操作,EPWM ISR 将正常工作,如 图 16 中所述。

 异常中断振荡已修复(CH4:通过 GPIO 切换中断;Ch3:发生 ePWM ZRO 事件时触发中断,红色信号:示波器的频率趋势测量)图 16 异常中断振荡已修复(CH4:通过 GPIO 切换中断;Ch3:发生 ePWM ZRO 事件时触发中断,红色信号:示波器的频率趋势测量)

总结

通过遵守最小中断延迟,中断得以正常执行。然而,影响中断正常执行的因素包括:

  • 中断请求是否正常触发
  • 是否启用 INTM 或 IER 启用位,以及 IFG 标志是否正常设置
  • 中断传播路径是否可能已阻止
  • 保存寄存器时,中断响应是否可能受到干扰,如不可中断指令 RPT
  • 无论中断是否嵌套,当低优先级中断响应时,高优先级中断会被阻止,从而影响中断响应的及时性

本技术文章介绍如何找到影响中断的因素并进行故障排除。