This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28384S:C28x 中断嵌套的一个问题

Guru**** 2393725 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1077661/tms320f28384s-one-question-of-c28x-interrupt-nesting

部件号:TMS320F28384S

嗨,香榭丽舍,

对于 C28x 中断嵌套,我们建议不要在 ISR 外部修改该组的 PIEIER 寄存器,否则可以触发假 INTX.1中断。

例如,我们有 INT3.8,INT9.2和 INT9.5中断,并希望优先处理 INT9.5,如果发生 INT9.2中断并在 IFR.9中锁定,然后在 CPU 分支到 INT3.8 ISR 之前,在 INT3.8 ISR 中修改 PIEIER9,然后触发虚假9.1, 这就是我们建议不在 ISR 之外为该组修改 PIEIER 的原因。

__中断无效 EPWM8_ISR (无效)        // INT3.8 ISR

  UINT16_t 模板接口;

  TempPIEIER = PieCtrlRegs.PIEIER9.ALL;  //保存 PIEIER 寄存器以供以后使用
  IER |= 0x100;               //通过调整 IER 设置全局优先级
  IER &= 0x100;
  PieCtrlRegs.PIEIER9.All &= 0x0010;   //通过调整 PIEIER9以允许设置组优先级
                      // INT 9.5中断当前 ISR
   
  PieCtrlRegs.PIEACK.ALL |= 0x0100;    //启用饼图中断
  ASM(" NOP");               //等待一个循环
  EINT;                   //清除 INTM 以启用中断

  //在此处插入 ISR 代码....

  丁;
  PieCtrlRegs.PIEIER9.ALL = TempPIEIER;
}

如果我们将上述 ISR 修改为低于函数,修改 INT9.5的 PIEIER9,然后在设置 IER 寄存器之前清除 IFR 寄存器中的其他位,那么我们是否可以修改 INT3.8 ISR 中的 PIEIER9并避免 虚假的 INT9.1中断?

如果在 C28x 分支到 INT3.8 ISR 之前发生了9.2,因为 INT9.2在 PIEIFR9.2中被锁定,那么在从 INT3.8 ISR 返回之前,INT9.2中断应该在将 TempPIEIER 写回 PIEER9到 PIEIER9时恢复。

请回答正确吗?

__中断无效 EPWM8_ISR (无效)        // INT3.8 ISR

  UINT16_t 模板接口;

  TempPIEIER = PieCtrlRegs.PIEIER9.ALL;   //保存 PIEIER 寄存器以供以后使用
  PieCtrlRegs.PIEIER9.All &= 0x0010;    //通过调整 PIEIER9以允许设置组优先级
                       // INT 9.5中断当前 ISR
  IFR &= 0x100;
  IER |= 0x100;                //通过调整 IER 设置全局优先级

  IER &= 0x100;
   
  PieCtrlRegs.PIEACK.ALL |= 0x0100;    //启用饼图中断
  ASM(" NOP");                //等待一个循环
  EINT;                   //清除 INTM 以启用中断

   //在此处插入 ISR 代码....

  丁;
  PieCtrlRegs.PIEIER9.ALL = TempPIEIER;
}

此致,

-卢克

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,卢克,

    感谢您的提问!

    有关如何避免虚假中断的详细信息,请参见此主题,特别是链接的帖子:

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/975599/tms320f280049c-interrupt-nesting-modifying-multiple-pieiers-within-in-interrupt/3605344#3605344

    此致,

    文斯

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Vince,

    感谢您的信息,并对打字错误表示抱歉。

    在我的示例中,如果我要修改 INT3.8 ISR 中的 PIEIER9,我必须清除 IFR.9,这将防止 INT9.2在修改 PIEIER9后成为虚假的 INT9.1中断,请参阅我的新代码部分。

    我知道 INTM 是在 CPU 向 ISR 分支之前设置的,因此我认为我们不必在 修改 PIEER/IER/IFR 寄存器之前再次执行 DINT。

    __中断无效 EPWM8_ISR (无效)        // INT3.8 ISR

      UINT16_t 模板接口;

      TempPIEIER = PieCtrlRegs.PIEIER9.ALL;   //保存 PIEIER 寄存器以供以后使用
      IER |= 0x100;                //通过调整 IER 设置全局优先级
      IER &= 0x100;
      PieCtrlRegs.PIEIER9.All &= 0x0010;    //通过调整 PIEIER9以允许设置组优先级
                           // INT 9.5中断当前 ISR
      IFR &=~0x100;              //清除 IFR.9以避免虚假 INT9.1中断
      PieCtrlRegs.PIEACK.ALL |= 0x0100;    //启用饼图中断
      ASM(" NOP");                //等待一个循环
      EINT;                   //清除 INTM 以启用中断

       //在此处插入 ISR 代码....

      丁;
      PieCtrlRegs.PIEIER9.ALL = TempPIEIER;
    }

    使用上述代码,我认为我可以修改 INT3.8 ISR 中的 PIEIER9,并确定 INT9.5中断的优先级。 你看到有什么问题吗?

    此致,

    -卢克

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,卢克,

    如链接的线程 I 中所述,在修改 PIEER/IER/IFR 寄存器之前,仍需要 DINT。 请按照该线程和 TRM 的“禁用中断”部分中的说明进行添加。 它应该在 IER |=行之前。

    另请参阅该电子邮件中提到的代码,第二次答复以及我在第三次答复中提到的更正:

    禁用中断时需要5个 NOP 周期,因为仍可能有中断在传播。

    总之,下面是 ISR 嵌套的伪代码,其中修改了另一个组的 PIEIERs:

    __interrupt void EPWM1_TZINT_ISR(void) // EPWM1 Trip Zone
    {
        //
        // make a variable for each PIEIER that gets updated, in this case only 1
        // backup the PIEIERs that will get modified
        //
        uint16_t TempPIEIER; 
        TempPIEIER = PieCtrlRegs.PIEIER2.all;
        
        // 
        // DINT -ONLY- needed because we are modifying the PIEIER of another group.
        // This prevents any additional interrupts from propagating to the CPU 
        // while we modify the IER and PIEIER
        //
        DINT;
    
        //
        // SET GLOBAL PRIORITY
        //
        IER |= M_INT2;
        IER &= MINT2;
        
        //
        // SET GROUP PRIORITY
        //
        // Note that PIEIER register has each bit representing one interrupt
        // e.g. setting "PIEIER" group 9 interrupt 5 is done by setting 
        // PIEIER9.all &= 0x0010
        PieCtrlRegs.PIEIER2.all &= MG21;      // Set "group" priority
        PieCtrlRegs.PIEACK.all = 0xFFFF;      // Enable PIE interrupts
        
        //
        // 5 NOP CYCLES -ONLY- needed because we are modifying PIEIER of 
        // another group. This can be skipped if NOT modifying PIEIER
        // of another group.
        //
        asm("       NOP");                      // Wait one cycle
        asm("       NOP");                      // Wait one cycle
        asm("       NOP");                      // Wait one cycle
        asm("       NOP");                      // Wait one cycle
        asm("       NOP");                      // Wait one cycle
    
        //
        // PIEACK to re-enable the interrupts to flow from PIEIFRs to IFRs
        // Then wait cycle + EINT allow interrupts to flow to CPU again.
        //
        PieCtrlRegs.PIEACK.all = 0xFFFF;        // Acknowledge all Interrupt
                                                // Groups to Enable PIE interrupts
        asm("       NOP");                      // Wait 1 cycle
        EINT;                                   // Clear INTM to enable interrupts
    
    
    
        //
        // Insert ISR Code here.......
        //
    
    
    
        //
        // Stop interrupts from interrupting the exit sequence
        //
        DINT;
    
        //
        // PIEACK to allow further interrupts from this group to occur after return
        //
        PieCtrlRegs.PIEACK.all = 0xFFFF;
        
        //
        // Restore registers saved
        //
        PieCtrlRegs.PIEIER2.all = TempPIEIER;
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Vince,

    感谢您的评论。

    我修改了下面的示例代码, 然后我能够修改 INT3.8 ISR 中的 PIEIER9并无问题地确定 INT9.5的优先级,对吗?

    __中断无效 EPWM8_ISR (无效)        // INT3.8 ISR

      UINT16_t 模板接口;

      TempPIEIER = PieCtrlRegs.PIEIER9.ALL;   //保存 PIEIER 寄存器以供以后使用
      丁;                   //将 INTM 设置为禁用中断
      IER |= 0x100;                //通过调整 IER 设置全局优先级

      IER &= 0x100;
      PieCtrlRegs.PIEIER9.All &= 0x0010;    //通过调整 PIEIER9以允许设置组优先级
                           // INT 9.5中断当前 ISR
      ASM(" NOP");                //等待一个循环
      ASM(" NOP");                //等待一个循环
      ASM(" NOP");                //等待一个循环
      ASM(" NOP");                //等待一个循环
      ASM(" NOP");                //等待一个循环
      IFR &=~0x100;              //清除 IFR.9以避免虚假 INT9.1中断

      PieCtrlRegs.PIEACK.ALL |= 0x0100;    //启用饼图中断
      ASM(" NOP");                //等待一个循环
      EINT;                   //清除 INTM 以启用中断

       //在此处插入 ISR 代码....

      丁;
      PieCtrlRegs.PIEACK.ALL = 0xFFFF;    //启用饼图中断
      PieCtrlRegs.PIEIER9.ALL = TempPIEIER;

    }

    此致,

    -卢克

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,卢克,

    正确,这将只允许 INT9.5嵌套在此 EPWM8_ISR 内。

    此致,

    文斯