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.

[参考译文] TMS320F28379D:用户1中断嵌套

Guru**** 2587695 points
Other Parts Discussed in Thread: TMS320F28379D, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1105267/tms320f28379d-user1-interrupt-nesting

主题中讨论的其他器件:TMS320F28379DC2000WARE
  1. 器件型号:TMS320F28379D

尊敬的 TI:

我对嵌套中断有疑问。 我使用 C2000示例学习这一点、因为直接从我的项目中我无法运行我的理论。 这个问题的目的是确认一个 User1中断是否可被另一个中断中断中断中断中断。

User1中断是不可屏蔽的中断、这意味着如果执行了_asm (" trap #number)、CPU 将到达它的任何情况下、该中断是否可以通过其他外设的更高中断来中断?

为了进行本实验、我在 c2000ware 中对 swperped_interrupts_cpu01项目添加了一些小的修改。如果需要、您可以从您的角度执行同样的操作、因此我将使用此示例。

首先、我在该文件 SWPrioritizeDefaultIsr.c 中向 User1 ISR 添加了一些代码:

//
// Connected to USER1 of CPU (non-maskable):
//
__interrupt void USER1_ISR(void)     // User Defined trap 1
{
    EINT;

    //
    // Insert ISR Code here.......
    //
    for(i = 1; i <= 100; i++) {}


    // Next two lines for debug only to halt the processor here
    // Remove after inserting ISR Code
//   __asm ("      ESTOP0");
//    for(;;);
    //
    //  Add ISR to Trace
    //
    ISRTrace[ISRTraceIndex] = 0xCA01;
    ISRTraceIndex++;
}

for 循环比其他中断服务例程中的 for 循环长10倍。 我的目标是查看此中断服务例程是否会嵌套具有最高优先级的中断。

其次、我在    PieCtrlRegs.PIEIFR1.all = ISRs_Group1之后和之前运行__asm (" trap #20")指令:

//
// CASE 1:
//
#if (CASE==1)
       //
       // Force all group 1 interrupts at once by writing to the PIEIFR1
       // register
       //

       //
       // Prepare for the test:
	   // Disable interrupts
	   // Clear the trace buffer, PIE Control Register, CPU IER and IFR
       // registers
       //
	   DINT;
	   for(i = 0; i < 50; i++)
       {
           ISRTrace[i] = 0;
       }

	   ISRTraceIndex = 0;
       InitPieCtrl();

       IER = 0;
       IFR &= 0;

       //
       // Enable the PIE block
       //
       PieCtrlRegs.PIECTRL.bit.ENPIE = 1;

       //
       // Enable PIE group 1 interrupt 1-8
       //
       PieCtrlRegs.PIEIER1.all = 0x00FF;

       //
       // Make sure PIEACK for group 1 is clear (default after reset)
       //
       PieCtrlRegs.PIEACK.all = M_INT1;

       //
       // Enable CPU INT1
       //
       IER |= M_INT1;

       //
       // Force all valid interrupts for Group 1
       //
       __asm("    TRAP #20");
       PieCtrlRegs.PIEIFR1.all = ISRS_GROUP1;


       //
       // Enable global Interrupts CPU level:
       //
	   EINT;   // Enable Global interrupt INTM

       //
	   // Wait for all Group 1 interrupts to be serviced
       //
	   while(PieCtrlRegs.PIEIFR1.all != 0x0000 ){}

       //
       // Stop here and check the ISRTrace to determine which order the
       // ISR Routines completed.  The order is dependant on the priority
       // assigned in the F2837xD_SWPrioritizedIsrLevels.h file
       //
       // The ISRTrace will contain a list of values corresponding to the
       // interrupts serviced in the order they were serviced.
	   // For example if the ISRTrace looks like this
	   //        0x0014     ISR Group 1 interrupt 4
	   //        0x0017     ISR Group 1 interrupt 7
	   //        0x0016     ISR Group 1 interrupt 6
	   //        0x0015     ISR Group 1 interrupt 5
	   //        0x0018     ISR Group 1 interrupt 8
	   //        0x0012     ISR Group 1 interrupt 2
	   //        0x0011     ISR Group 1 interrupt 1
	   //        0x0000     end of trace
       //
	  __asm("        ESTOP0");

我正在执行示例的第一个示例。

我使用  的 F2837xD_SWPrioritizedIsrLevels.h 与 TI 相同:

#define	INT1PL      2        // Group1 Interrupts (PIEIER1)
#define	INT2PL      1        // Group2 Interrupts (PIEIER2)
#define	INT3PL      4        // Group3 Interrupts (PIEIER3)
#define	INT4PL      2        // Group4 Interrupts (PIEIER4)
#define	INT5PL      2        // Group5 Interrupts (PIEIER5)
#define	INT6PL      3        // Group6 Interrupts (PIEIER6)
#define	INT7PL      5        // Group7 Interrupts (PIEIER6)
#define	INT8PL      5        // Group8 Interrupts (PIEIER6)
#define	INT9PL      3        // Group9 Interrupts (PIEIER9)
#define	INT10PL     6        // Group10 Interrupts (PIEIER6)
#define	INT11PL     6        // Group11 Interrupts (PIEIER6)
#define	INT12PL     8        // Group12 Interrupts (PIEIER6)
#define	INT13PL     4        // XINT13
#define	INT14PL     4        // INT14 (TINT2)
#define	INT15PL     4        // DATALOG
#define	INT16PL     4        // RTOSINT



...
#define G1_1PL		5		// ADCA1_INT
#define G1_2PL		3		// ADCB1_INT
#define G1_3PL		1		// ADCC1_INT
#define G1_4PL		4		// XINT1_INT
#define G1_5PL		4		// XINT2_INT
#define G1_6PL		1		// ADCD1_INT
#define G1_7PL		12		// TIMER0_INT
#define G1_8PL		5		// WAKE_INT
#define G1_9PL		0   	// Reserved
#define G1_10PL		0   	// Reserved
#define G1_11PL		0   	// Reserved
#define G1_12PL		0   	// Reserved
#define G1_13PL		8		// IPC1_INT
#define G1_14PL		13		// IPC2_INT
#define G1_15PL		15		// IPC3_INT
#define G1_16PL		9		// IPC4_INT

结果:

在这张图片中、我们可以看到、即使 #define G1_3PL 1 // ADCC1_INT 是最高优先级、用户1中断也会获得执行的第一个中断?

用户中断到达 ADCC1_INT 时是否中断? 我不确定 User1中断是否嵌套了高优先级、我认为即使我们定义了最高优先级中断、当用户中断开始执行时、它也不会停止、直到结束和其他最高优先级处于挂起状态。

请您澄清这一点吗?

提前感谢您、

此致、

S.Tarik

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

    尊敬的 S.Tarik:

    用户中断是不可屏蔽的、 它将在陷阱指令之后被立即处理。  

    使用 SW 优先级逻辑、您只能控制 PIE 中断和 C28x 中断 INT1-16的优先级。

    此致、

    Veena

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

    它们是不可屏蔽的、但您是否不能通过 EINT 指令在 User1_ISR 内启用所有其他中断?

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

    您好!

    EINT/DINT 指令只控制可屏蔽中断。 因此,在您的代码中,您可以强制执行中断:  

    __asm(" TRAP #20");
    PieCtrlRegs.PIEIFR1.all = ISRS_GROUP1;

    即使 INTM 被禁用、在 TRAP 指令之后、用户中断 ISR 立即被命中。 因此、组1中断标志可能甚至不会在用户 ISR 内部设置。 您可以尝试撤销订单吗?

    PieCtrlRegs.PIEIFR1.all = ISRS_GROUP1;
    __asm(" TRAP #20");


    这样、您可以确保在用户 ISR 命中之前设置组1中断。 在 ISR 内部、启用 EINT 后、硬件将看到组1中断标志并分支到相应 的 ISR

    此致、

    Veena

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

    Stephans 和 Veena 大家好、

    我按照您提到的顺序颠倒了顺序

    这里是结果、

    用户中断是最后执行的中断、它具有最低的优先级!

    我对头文件中的顺序优先级进行了一些更改:

    我同意您的观点、陷阱指令不可屏蔽、但我要尝试的是执行和中断用户中断的能力。

    我正在尝试在用户中断中使计时器中断变为 TRIG。

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

    您好!

    正如 Stephen 提到的、EINT 指令将启用所有中断。 理想情况下、应选择仅启用需要更高优先级的中断。 这就是在软件优先级中断逻辑中执行的操作。 如果查看 interrupt_ex3_SW_Prioritization 示例、可以发现 ISR 在 EINT 之前更新 IER 和 PIE 寄存器。 宏 M_INT1 和 MG1_7的配置方式使其仅启用优先级高于定时器中断的中断。 您可以使用类似的逻辑来扩展这些中断以用于用户中断。  

    此致、

    Veena

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

    很棒

    我正在调试此示例以练习此操作并深入了解嵌套。

    为此、我将使用具有 Timer0最高中断的第一个组。 在示例第一种情况下、我将触发8个中断、并向每个中断添加一个断点、如下图所示。

    当我单击 F8时、PC 运行到 ADCA1中断、它不是软件的最高优先级、而是先进入该中断。

    这种情况第一次是正常的、因为硬件发生、软件优先级将从 ADCA1_ISR 开始。

    我的问题是:

    在第二个 F8中、程序计数器命中 Timer0中断、但在到达 Timer0中断之前、PIEIER1.ALL = 0x00FE。

    它支持 PIEIER1.ALL =  0x0040? 我无法理解、MG1_7移位是否需要更多的周期、在此阶段、PIEIER1.所有的操作仍不受影响?

    2.循环的10个周期是否在中断中是必需的? 我是否必须将其保留用于嵌套循环、还是仅用于演示 CPU 负载?

    提前感谢您、

    S.t

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

    您能否分享您为每个中断配置的优先级? 是否在 EINT 语句之前检查 IER 寄存器的值?

    [引用 userid="300446" URL"~/support/microcontrollers/C2000-microcontrollers-group/CC2000/f/C2000-microcontrollers-forume/1105267/tms320f28379d-user1-interrupt-nesting/4098094#4098094"]

    2.循环的10个周期是否在中断中是必需的? 我是否必须将其保留用于嵌套循环、还是仅用于演示 CPU 负载?

    [/报价]

    仅用于演示。 您可以将其删除并在此处插入实际的 ISR 代码

    此致、

    Veena

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

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

    您好!

    在这种情况下、ISR 1.1将启用所有其他组1中断(因为它们的优先级高于 INT1.1)、因此您会看到0xFE。 接下来、由于硬件优先级、它应该到达 ISR1.2;在 ISR1.2中、只有优先级高于自身的中断才会被启用、等等...

    希望这一点很清楚。

    此致、

    Veena

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

    您好、Veena、

    我想为用户中断做同样的事情、

    可以共享 User1代码示例、请提前感谢您