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.

[参考译文] TMS320F28386D:是否可以嵌套 FreeRTOS 计时器 ISR? 干扰控制环路 ISR

Guru**** 2448780 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1452845/tms320f28386d-is-it-possible-to-nest-the-freertos-timer-isr-interfering-with-control-loop-isr

器件型号:TMS320F28386D
主题中讨论的其他器件:MG2C2000WARE

工具与软件:

我将开发一个控制循环系统、并且面临中断的一个优先级问题。 我的设置如下:

1.控制循环 ISR (由 ADC 触发)应具有最高优先级。
2.使用 FreeRTOS 管理其他任务。  
3.它在 C28x 内核中运行。

问题:
我已经注意到、控制循环 ISR 经历了大约每1ms 1.8us 的延迟、与 FreeRTOS 计时器 ISR 触发相一致。

电流注意事项包括:
-删除 FreeRTOS 并实施自定义解决方案。
-探索在 FreeRTOS 框架内进行优化的方法

问题:
1.如何确保控制循环 ISR 保持最高优先级而不被 FreeRTOS 中断?
2.是否能够启用 FreeRTOS 定时器 ISR 的嵌套以最大限度地减少其对控制环路的影响?
3.是否有任何 FreeRTOS 配置或最佳实践来解决这种对时间敏感的情况?

如果您有任何见解、建议或替代方法来解决此问题、同时保持使用 FreeRTOS 的优势、我将不胜感激。

提前感谢

此致

Agustin J. Gomez

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

    你好  Agustin ,

    我正在处理类似的主题:

    具有最高优先级的 ISR:

    150kHz ADC A1、 ADC C1

    第二 优先级 ISR:

    50kHz ADC C2

    第3 优先级 ISR:

    LIN 通信

    第4 优先级 ISR:

    1ms 定时器1

    最低 ISR:

    FreeRTOS 端口节拍(定时器2)

    +

    FreeRTOS 1ms/10ms/100ms 任务

    ==================

    我所做的是按照"interrupt_ex3_sw_priority"示例进行操作、并修改第2个/第3个/第4个 ISR 和"portasm.asm"以允许嵌套。

    ==================

    您可以将其与原始 "portasm.asm"进行比较

    _portTick_isr:

    ;嵌套启用
    IER #0x1225
    NOP
    CLRC INTM


    ;保存上下文
    asp

    MOV32 STF、*--SP
    MOVL XAR7、*--SP
    MOVL XAR6、*--SP
    MOVL XAR5、*--SP
    MOVL XAR4、*--SP
    MOVL XAR3、*--SP
    MOVL XAR2、*--SP
    MOVL XT、*--SP
    弹出 RPC
    Pop AR1H:AR0H
    PoP RB
    NASP


    ;嵌套结束
    SETC INTM


    IRET

    ==================================


    //文件:sw_prioritized_isr_levels.h

    #ifdef __cplusplus
    extern "C"{
    #endif

    //
    //中断组的屏蔽
    //
    #define M_INT1 0x0001 // INT1掩码
    #define M_INT2 0x0002 // INT2掩码
    #define M_INT3 0x0004 // INT3掩码
    #define M_INT4 0x0008 // INT4掩码
    #define M_INT5 0x0010 // INT5掩码
    #define M_INT6 0x0020 // INT6掩码
    #define M_INT7 0x0040 // INT7掩码
    #define M_INT8 0x0080 // INT8掩码
    #define M_INT9 0x0100 // INT9掩码
    #define M_INT10 0x0200 // INT10掩码
    #define M_INT11 0x0400 // INT11掩码
    #define M_INT12 0x0800 // INT12掩码
    #define M_INT13 0x1000 // INT13掩码
    #define M_INT14 0x2000 // INT14掩码
    #define M_DLOG 0x4000 // DLOGINT 屏蔽
    #define M_RTOS 0x8000 // RTOSINT 屏蔽

    //
    //中断使能寄存器分配:
    //可以使用 CPU 中断使能寄存器来启用/禁用中断
    //(IER)和 PIE 中断使能寄存器(PIEIER1至 PIEIER12)。
    //

    //
    //设置"全局"中断优先级(IER 寄存器):
    //
    //用户必须为每个 CPU 设置适当的优先级
    //中断。 这被称为"全局"优先级。 优先级
    //必须是1 (最高)到16 (最低)之间的数字。 值必须为0
    //对于保留的中断或未使用的中断。
    //
    //注意:下面的优先级用于计算 IER 寄存器
    //中断屏蔽 MINT1到 MINT16。
    //
    //注意:此处显示的优先级在 A 中可能没有意义
    //实际应用程序。 这仅用于演示目的!!!
    //
    //用户应将这些值更改为合理的值
    //他们的应用程序。
    //
    // 0 =未使用
    // 1 =最高优先级
    //...
    // 16 =最低优先级
    //
    #define INT1PL 1 //组1中断的全局优先级
    #define INT2PL 0 //组2中断的全局优先级
    #define INT3PL 3 //组3中断的全局优先级
    #define INT4PL 0 //组4中断的全局优先级
    #define INT5PL 0 //组5中断的全局优先级
    #define INT6PL 4 //组6中断的全局优先级
    #define INT7PL 0 //组7中断的全局优先级
    #define INT8PL 0 //组8中断的全局优先级
    #define INT9PL 0 //组9中断的全局优先级
    #define INT10PL 2 //组10中断的全局优先级
    #define INT11PL 0 //组11中断的全局优先级
    #define INT12PL 0 //组12中断的全局优先级
    #define INT13PL 7 // INT13的全局优先级(TINT1)
    #define INT14PL 8 // INT14的全局优先级(TINT2)
    #define INT15PL 0//数据日志的全局优先级
    #define INT16PL 0 // RTOSINT 的全局优先级

    //
    //设置"组"中断优先级(PIEIER1到 PIEIER12寄存器):
    //
    //用户必须为每个 PIE 设置适当的优先级
    //中断。 这被称为"组"优先级。 优先级
    //必须是1 (最高)到16 (最低)之间的数字。 值必须为0
    //对于保留的中断或未使用的中断。
    //
    //注意:下面的优先级用于计算以下内容
    // PIEIER 寄存器中断屏蔽:
    // MG1_1至 MG1_16
    //将 MG2_1更改为 MG2_16
    // MG3_1至 MG3_16
    //将 MG4_1更改为 MG4_16
    //将 MG5_1更改为 MG5_16
    // MG6_1至 MG6_16
    // MG7_1到 MG7_16
    // MG8_1至 MG8_16
    // MG9_1至 MG9_16
    // MG10_1至 MG10_16
    // MG11_1至 MG11_16
    // MG12_1至 MG12_16
    //
    //注意:此处显示的优先级在 A 中可能没有意义
    //实际应用程序。 这仅用于演示目的!!!
    //
    //用户应将这些值更改为合理的值
    //他们的应用程序。
    //
    // 0 =未使用
    // 1 =最高优先级
    //...
    // 16 =最低优先级
    //
    #define G1_1PL 1 // ADCA1_INT
    #define G1_2PL 1 // ADCC1_INT
    #define G1_3PL 0 //保留
    #define G1_4PL 0 // XINT1_INT
    #define G1_5PL 0 // XINT2_INT
    #define G1_6PL 0 // SYS_ERR_INT
    #define G1_7PL 4 // TIMER0_INT
    #define G1_8PL 0 // WAKE_INT

    #define G2_1PL 0 // EPWM1_TZ_INT
    #define G2_2PL 0 // EPWM2_TZ_INT
    #define G2_3PL 0 // EPWM3_TZ_INT
    #define G2_4PL 0 // EPWM4_TZ_INT
    #define G2_5PL 0 // EPWM5_TZ_INT
    #define G2_6PL 0 // EPWM6_TZ_INT
    #define G2_7PL 0 // EPWM7_TZ_INT
    #define G2_8PL 0 //保留

    #define G3_1PL 0 // EPWM1_INT
    #define G3_2PL 0 // EPWM2_INT
    #define G3_3PL 0 // EPWM3_INT
    #define G3_4PL 0 // EPWM4_INT
    #define G3_5PL 0 // EPWM5_INT
    #define G3_6PL 0 // EPWM6_INT
    #define G3_7PL 0 // EPWM7_INT
    #define G3_8PL 0 //保留

    #define G4_1PL 0 // ECAP1_INT
    #define G4_2PL 0 // ECAP2_INT
    #define G4_3PL 0 // ECAP3_INT
    #define G4_4PL 0 //保留
    #define G4_5PL 0 //保留
    #define G4_6PL 0 //保留
    #define G4_7PL 0 //保留
    #define G4_8PL 0 //保留

    #define G5_1PL 0 // EQEP1_INT
    #define G5_2PL 0 // EQEP2_INT
    #define G5_3PL 0 //保留
    #define G5_4PL 0 //保留
    #define G5_5PL 0 //保留
    #define G5_6PL 0 //保留
    #define G5_7PL 0 //保留
    #define G5_8PL 0 //保留

    #define G6_1PL 0 // SPIA_RX_INT
    #define G6_2PL 0 // SPIA_TX_INT
    #define G6_3PL 0 //保留
    #define G6_4PL 0 //保留
    #define G6_5PL 0 // LINA_0_INT
    #define G6_6PL 0 // LINA_1_INT
    #define G6_7PL 0 // DCC0_INT
    #define G6_8PL 0 //保留

    #define G7_1PL 0 //保留
    #define G7_2PL 0 //保留
    #define G7_3PL 0 //保留
    #define G7_4PL 0 //保留
    #define G7_5PL 0 //保留
    #define G7_6PL 0 //保留
    #define G7_7PL 0 // PMBUSA_INT
    #define G7_8PL 0 //保留

    #define G8_1PL 0 // I2CA_INT
    #define G8_2PL 0 // I2CA_FIFO_INT
    #define G8_3PL 0 // I2CB_INT
    #define G8_4PL 0 // I2CB_FIFO_INT
    #define G8_5PL 0 // SCIC_RX_INT
    #define G8_6PL 0 // SCIC_TX_INT
    #define G8_7PL 0 //保留
    #define G8_8PL 0 //保留

    #define G9_1PL 0 // SCIA_RX_INT
    #define G9_2PL 0 // SCIA_TX_INT
    #define G9_3PL 0 // SCIB_RX_INT
    #define G9_4PL 0 // SCIB_TX_INT
    #define G9_5PL 0 // CANA0_INT
    #define G9_6PL 0 // CANA1_INT
    #define G9_7PL 0 // MCANSS0_INT
    #define G9_8PL 0 // MCANSS1_INT

    #define G10_1PL 0 // ADCA_EVT_INT
    #define G10_2PL 0 // ADCA2_INT
    #define G10_3PL 0 // ADCA3_INT
    #define G10_4PL 0 // ADCA4_INT
    #define G10_5PL 0 // ADCC_EVT_INT
    #define G10_6PL 0 // ADCC2_INT
    #define G10_7PL 0 // ADCC3_INT
    #define G10_8PL 0 // ADCC4_INT

    #define G11_1PL 0 //保留
    #define G11_2PL 0 //保留
    #define G11_3PL 0 //保留
    #define G11_4PL 0 //保留
    #define G11_5PL 0 //保留
    #define G11_6PL 0 //保留
    #define G11_7PL 0 //保留
    #define G11_8PL 0 //保留

    #define G12_1PL 0 // XINT3_INT
    #define G12_2PL 0 // XINT4_INT
    #define G12_3PL 0 // XINT5_INT
    #define G12_4PL 0 //保留
    #define G12_5PL 0 // FMC_INT
    #define G12_6PL 0 // VCRC_INT
    #define G12_7PL 0 // INT_MCANSS_WAKE_AND_TS_PLS
    #define G12_8PL 0 // INT_MCANSS_ECC_CORR_PLS


    //
    //包含带软件中断优先级逻辑的头文件
    //
    #include "sw_interrupt_priority_logic.h"

    #ifdef __cplusplus
    }
    #endif /* extern "C"*

    #endif // eof

    //
    //文件结尾
    //

    ============================================

    中断失效 IsrAdcA2 (void)

    IsrAdcA2_Enter_ticks++;

    //设置全局和组优先级以允许 CPU 中断
    //具有较高的优先级
    IER &= MINT10;


    //启用中断
    __ asm (" NOP");
    EINT;

    …………

    颜色;
    /*清除中断标志*/
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;

    /*确认中断*/
    PieCtrlRegs.PIEACK.all = PIEACK_group10;

    }

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

    您好、先知、感谢您的分享!

    虽然我避免接触装配体、但您的解决方案似乎非常好。

    我将分析您的答案、以了解它是如何工作的以及它是如何适合我的。

    和 IER、#0x1225

    0x1225是要执行此操作的数字、还是它取决于应用程序? 是否可以从外部对其进行定义以使其更通用? 我将进行检查、以便重复使用端口。 我想在我检查过你告诉我的例子后、我会更好地理解它。

    再次感谢!  

    此致

    Agustin J. Gomez

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

    Agustin、您好!  

    C2000Ware 中的 FreeRTOS 端口不直接支持嵌套、但可以按照本主题前面所述进行修改。 您可以查看 此链接 以了解有关 C28x 中断嵌套的进一步说明。

    谢谢!

    Arnav