DSP——中断可嵌套的实现

目录


前言

DSP的中断默认是不可嵌套的,即当执行某个中断服务函数时,即使有更高优先级的中断触发,也需要等待当前中断执行完后才可响应。近来工作需要保证TMS320F28377D的IPC中断优先执行,即使当前正在执行其它中断也需要挂起,优先执行IPC中断。


一、DSP的中断是怎样的?

28377D的CPU有14个外设中断线,其中两个(INT13和INT14)分别直接连接到CPU定时器1和2.其余12个通过增强型外设中断扩展模块(ePIE)连接到外设中断信号。CPU内核有IER中断使能寄存器和IFR中断标志寄存器,这两个十六位的寄存器的低十四位分别对应INT1到INT14的中断使能和中断标志。如果使用的是新的driverlib库,在cpu.h文件中有如下声明,可直接代码中对IER和IFR寄存器读写。

#ifndef _TMS320C28XX_CLA_
extern _cregister volatile uint16_t IFR;
#endif

#ifndef _TMS320C28XX_CLA_
extern _cregister volatile uint16_t IER;
#endif


PIE将多达16个外设中断复用到每个CPU中断线上,它还扩展中断向量表,以允许每个中断具有自己的ISR,这允许CPU支持大量的外设。

中断路径位外设->PIE->CPU,每个级都有自己的使能和标志寄存器,该系统在处理一个中断时,其它可屏蔽中断是禁止的,需要在软件中实现嵌套中断,并在某些关键任务期间禁用中断。

                                                        设备中断架构

28377D的PIE有12组,每组有16个通道中断,其中断优先级如下表从上往下优先级逐减,从左往右优先级逐减,即左上优先级最高,右下优先级最低。

PIE的寄存器如下

外设到CPU的执行流程:

1.当外设产生中断,中断被锁存在PIEIFRx.y

2.如果设置了PIEIERx.y中断将被传递

3.如果PIEACK.x清零(非零将不传递),则中断传递到CPU,PIEACK.x被置位直到ISR中软件手动清除ACK

4.中断在CPU的IFR.x中锁存

5.如果cpu的IER.x设置了,则中断传播

6.如果INTM清零(指EINT使能中断,或CLER INTM),CPU接收中断

7.CPU保存上下文

8.清除IFR.x,和IER.x,INTM设置(DINT 或SETC INTM),这时禁止其它可屏蔽中断

9.CPU从PIE中获取ISR向量,PIEIFRx.y被清除

10.CPU分支到ISR

注意:当对IER、IFR、PIE的寄存器操作时需要先DINT,禁用中断,操作完后再EINT,启用中断

二、中断可嵌套的实现

1.官方例子

添加简单的软件优先级(嵌套):

第 1 步:设置全局优先级:

修改 IER 寄存器以允许处理具有更高用户优先级的 CPU 中断。

注意:此时 IER 已经保存在栈上。

第 2 步:设置组优先级:(可选)

修改相应的 PIEIERx 寄存器以允许处理具有更高用户设置优先级的组中断。

不要从除此 ISR 服务的组之外的另一组清除 PIEIER 寄存器位。这样做可能会导致发生错误的中断。

第 3 步:启用中断:

有三个步骤可以做到这一点:

清除 PIEACK 位

等待至少一个周期

清除 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 返回

这将自动恢复 INTM 和 IER。

实例代码:

// // C28x ISR Code // // Enable nested interrupts // // interrupt
void EPWM1_TZINT_ISR(void)
{
        uint16_t TempPIEIER;
        TempPIEIER = PieCtrlRegs.PIEIER2.all; // Save PIEIER register for later
        IER |= 0x002;                         // Set global priority by adjusting IER
        IER &= 0x002;
        PieCtrlRegs.PIEIER2.all &= 0x0002;    // Set group priority by adjusting PIEIER2 to allow INT2.2 to interrupt current 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.PIEIER2.all = TempPIEIER;
}

官方例子是在EPWM1_TZ的中断中能够响应EPWM2_TZ的中断,通过下图可看出EPWM2_TZ的优先级比EPWM1_TZ的优先级低,这说明软件实现中断可嵌套根据用户的需求来实现,非常灵活

2.应用实例

下图是DSP两个引脚的逻辑分析仪采集的波形图,其中tst_adInterrupt引脚在DSP的外部中断5的ISR进入时置1,执行完时复位,dsp_Ad_update引脚在DSP的IPC1中断的ISR进入时置位,执行完后复位。从图中可以看出第二个波形即IPC1中断需要等外部中断5执行完才执行,导致IPC1中断执行太晚了,因此需要中断可嵌套,保证IPC1中断优先执行


查询IPC1的中断通道号位INT1.14,XINT5的中断通道号为INT12.3,因此IPC1的中断优先级本来就比XINT5的中断优先级高,因此不需要在XINT5的ISP中设置全局优先级和组优先级,只需要在XINT5的ISR中做如下修改

__interrupt void xint5ISR()
{
    GPIO_writePin(Pin_CON4,1);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP12);//清除PIE的ACK对应位

    NOP;

    EINT;//使能中断

    //业务代码


    GPIO_writePin(Pin_CON4,0);
}
//__interrupt关键字,编译器在ISR执行完后会自动执行IRET指令

以上修改后再用逻辑分析抓取DSP引脚波形图如下

可以看出第二个引脚即IPC1中断能够打断XINT5的中断,保证了IPC1中断的优先执行


总结

本文主要讲解了DSP中断可嵌套的实现,借助了官方同组内低优先级的PWM2_TZ中断能够打断PWM1_TZ的例子,实现了IPC1中断打断XINT5中断的需求,其它中断可嵌套的实现可参考本文,原理上是相同的

  • 33
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值