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.

[参考译文] RTOS/TM4C1294NCPDT:在 SWI 中使用时 FPU 寄存器损坏

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/757162/rtos-tm4c1294ncpdt-fpu-registers-corrupted-when-using-in-swi

器件型号:TM4C1294NCPDT
Thread 中讨论的其他器件:SYSBIOS

工具/软件:TI-RTOS

大家好、

我在 SWI 上下文中使用 FPU (优先级为15)。 在2个浮点值之间进行比较时、我会发现比较结果有时会相等(大约超过一百万)。

放置一个硬件断点会显示 S0、有时 S1也会报告错误值。

我附加了一个屏幕截图、其中 CPU 在比较失败后停止。

S0和 S1从包含在 R0和 R1中的地址加载、两个位置都包含正确的值30.152075、即0x41F13773。 但是、在 S0中、我现在看到0、这是命中断点的原因。

通过使用一些自制 RAM 记录器跟踪流量、我发现只有在 HWI 中断此 SWI 功能时才会出现问题、我会考虑不使用浮点单元。

我使用 的是 tirtos_tivac_2_14_00_10。

我可以想到的是 FPU 寄存器不会保存在上下文切换中、而是有人可以使用它们。

在抢占 SWI 时、是否有任何方法可以告诉操作系统保存它们?

BR。

Lorenzo。

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

    调度程序将 d0-D7以及 fpscr 推入 Hwi 条目并在退出时将其弹出。 是由内核管理的 Hwi、还是零延迟中断。 如果是后者、ISR 代码负责保留寄存器。

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

    您好 Todd、

    感谢您的快速响应。

    Hwi 由内核管理、实际上中断 HWI 是2:(INT_CAN0_TM4C129和 INT_CAN1_TM4C129);它们的优先级定义如下。

    #define HWI_Priority_CAN0INT (3 << 5)
    #define HWI_Priority_CAN1INT (4 << 5)

    还有另外2个 HWI、它们在运行时通过 Hwi_construction (...)、UART 和 ADC 构建、它们有 (7 << 5)和 (1<< 5)作为优先级;因此没有 HWI 是零延迟中断、因为 Hwi_disablePriority 等于32。

    在 TI-RTOS 之外没有注册 ISR。

    当 bk 被命中时、以及在任何其他时候、FPCCR 寄存器显示 Aspen 位清零、应该将其置位还是可以?

    我已经检查 了 ti_sysbios_family_arm_m3/Hwi_deign_i 的反汇编、并且__ TI_VFP_support_下的条件指令确实存在。  

    我将尝试扼要重述、以便尽可能清晰。

    • ADC 配置为由硬件计时器触发转换。
    • 与 INT_ADC1SS1相关联的一个 Hwi 会复制转换后的值、并在有大量计算的位置布置 swi。
    • 如果一个 hwi (我的情况下与 CAN 相关)中断了 swi、我可能会在某些 FPU reg 损坏时使 swi 恢复。
    • 无论如何、CAN Hwi 没有使用浮点的代码

    最后一个附录是、我通过调用函数进入并退出以下2个 FNC 来输入 CAN HWI S0和 S1的轨迹:

    全局__get_s0
    _get_s0:
    vmov r0、s0
    BX LR


    全局_get_S1
    _get_S1:
    vmov r0、s1
    BX LR

    这两个寄存器报告的值始终正确(0x41F13773 = 30.152075)

    BR

    Lorenzo。

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

    您好 Lorenzo、

    首先、您能否确认您使用的编译器。 从快照看、它看起来像 IAR、但请确认。

    此外、您能否将优先级从(1<5)提升至(2<5)。 我知道应该可以、因为 Hwi_disablePriority 是32、但这是一个简单的测试:)

    根据您的描述、我们认为您的 CAN ISR 正在破坏堆栈。 ISR 中的局部变量是什么? 也许一个缓冲区正在被覆盖并破坏堆栈上保存的 D0-D7寄存器? 一个简单的测试是添加一个 char buffer[32]作为第一个局部变量。 将所有元件初始化为 ISR 中的某个已知值(例如0xA5)。 在 ISR 结束时、确认缓冲区值仍然是该值。 注意:如果您靠近系统堆栈的顶部、则可能需要将其向上提升。 您可以检查 ROV->Hwi->模块以查看峰值、以查看是否接近。

    Todd

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

    您好 Todd、

    我使用的编译器是 TI ARM v5.2.2;快照取自我的调试系统 TraceTM 32 Lauterbach。

    我已将优先级从32更改为64。

    我还添加了32字节保护缓冲区作为第一个局部变量。

    局部变量为:

    CanDrvChannelId canDrvChannelId =(CanDrvChannelId) arg;
    CanDrvChannelStrutPtr canDrvChannelPtr;
    uint32. CanDrvChannelBase;
    CANMsgObjId canMsgObjId;
    uint32. canMsgObjInts; 

    其中:

    /*可以驱动程序通道标识符*/
    typedef enum {
    CAN_DRV_CHANNEL 流程= 0、
    CAN_DRV_CHANNEL 服务、
    
    CAN_DRV_CHANGE_ID_MAX
    }CANDrvChannelId、* CANDrvChannelIdPtr; 

    CanMsgObjId 是另一个枚举、范围为0至31和
    CANDrvChannelStructPtr 是一个指向包含相关 CAN 外设基址的结构的指针、也是 HWI 要更新的一些计数器、以提供一些外部统计信息。

    当然、我已经检查过我没有堆栈用尽。

    我还在 HWI 的末尾添加了一个防护缓冲器自动检查:这样、我会通过计数来拦截硬件断点的问题、其中断点会断言损坏。

    对于(i=0;i<=7;++I){
    if (buffer[i]!= 0xA5A5A5){
    损坏= true;
    }
    } 

    新的 FW 刚刚启动并运行。 由于故障通常在4-24小时内发生、我明天会告诉您更多信息。

    Lorenzo。

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

    感谢您的更新。 让我们希望这能揭示一些东西。

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

    您好 Todd、

    问题再次出现、请找到所附的演示文稿。

    在 Hwi 末尾的检查中、发现无符号长整型缓冲区[8]为整数。顺便说一下、当出现问题时、我会看到这些值被部分损坏:只有3个字、而不是8个字。 通过查看 A5字的近似值、我认为缺失的5是具有较高地址(0x200014D8-0x200014EB)的5个字。 我已在该区域识别 Timer1_base。

    在0x20001530时、我看到 LR 指向我中断的 SWI (请在右侧找到反汇编);这与 FPU 上下文中 S0-S7的损坏完全兼容:实际上此时 S1仍需要写入、而 S0将从损坏的堆栈副本中恢复。

    我还发现了黄色部分、我认为堆叠的 FPU 背景。

    浅蓝色表示当前 SP。

    唯一的优点是、问题在几个小时内系统发生、因此、一旦 CPU 在 bk 中停止、我可以获取所需的所有数据。

    请注意、我使用嵌套中断。

    此致。

    Lorenzo。

    e2e.ti.com/.../FPU-stacking.zip

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

    Lorenzo、

    “顺便说一下,当出现问题时,我会看到这些值已部分损坏:”

    我将这条语句解释为 Hwi 函数正文中的某个函数会破坏栈。

    我是否正确理解了这一点?

    Alan

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

    您好!

    我的意思是、在控制权返回到 SWI 后、0XA5A5A5字被破坏。 但我不会认为 HWI 的主体内部会发生损坏、因为该函数以以下方式结束:

    对于(i=0;i<=7;++I){
    if (buffer[i]!= 0xA5A5A5){
    损坏= true;
    } 

    我在赋值损坏语句中设置了一个 bk。 我遇到了问题、但没有在那里停下来。

    因此、我猜是部分存储器稍后在调度程序中或恢复 SWI 之前损坏。 如果配置不正确、RTOS 可能会以这种方式运行?

    Lorenzo。

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

    您说您有嵌套 Hwi。 是否所有的 Hwi 函数都具有损坏缓冲区检查功能? 也许只有当 Hwi 嵌套发生时、条件才会出现。

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

    [引用用户="Lorenzo Verniani"]

    我使用 的是 tirtos_tivac_2_14_00_10。

    我可以想到的是 FPU 寄存器不会保存在上下文切换中、而是有人可以使用它们。

    [/引用]您提到没有使用零延迟中断、因此这可能不起作用、但应用 Tiva SYS/BIOS FPU 上下文切换中列出的代码更改是否会导致零延迟中断损坏 、从而防止了这一问题?

    SysBIOS-208针对引用线程中的错误提出、该错误已在 SYS/BIOS 6.46.00.23中修复。  tirtos_tivac_2_14_00_10使用 SYS/BIOS 6.42.01.20、因此存在该错误。

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

    [引用用户="Alan DeMars"]Lorenzo、

    您说您有嵌套 Hwi。 是否所有的 Hwi 函数都具有损坏缓冲区检查功能? 也许只有当 Hwi 嵌套发生时、条件才会出现。

    Alan

    [/报价]
    Alan、在我的上一个测试中、防护缓冲器只插入了 CAN Hwi 中。 我还会将其包含在 ADC 和 UART Hwi 中。
    不幸的是、我现在无法进行任何测试、因为我的办公室将于1月6日关闭。 但是、这个问题在我的团队中不断升级、所以一旦我回到工作岗位、我就会发布结果。
    我同意你的意见,即应考虑嵌套 IRQ。 我如何对此进行调查? 在您看来、从 SYSBIOS 配置中禁用中断嵌套可能是一项有效的测试、还是有助于排除任何问题?
    感谢您的观看。
    Lorenzo。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    切斯特、

    我将尝试将更改应用到 Hwi 调度程序、并告知您。 正如我先前所讲的、下一个测试将于1月7日运行。
    此致。

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

    您好!

    我还尝试在 UART 和 ADC hwis 中插入防护缓冲器。

    更重要的是、我更改了 Hwi 调度程序部分、按照 Alan 在 Chester 链接的帖子中的建议处理 FPUregs 堆栈。

    从中删除  

    .if __TI_VFP_support__
    vstmdb {d0-D7},r1! ;将 VFP 暂存寄存器推入适当的堆栈
    vmrs r2、fpscr ;也按 fpscr
    结构 R2、[R1、#-8]! ;(保持偶数对齐)
    
    TST LR、#4 ; PSP 上的上下文?
    信息技术 不可
    Msrne PSP、R1 ;更新相应的 SP
    moveq sp、R1
    .endif 

    更改为

    .if __TI_VFP_support__
    子部分 R2、R1、#72 ;备份9*8字节
    TST LR、#4 ; PSP 上的上下文?
    信息技术 不可
    Msrne PSP、R2 ;在推送之前更新相应的 SP
    moveq sp、R2
    vstmdb {d0-D7},r1! ;将 VFP 暂存寄存器推入适当的堆栈
    vmrs r2、fpscr ;也按 fpscr
    结构 R2、[R1、#-8]! ;(保持偶数对齐)
    .endif 

    超过28小时后、测试问题仍未发生。 通常、6-10小时就足够观看了。

    顺便说一下、我还不知道会发生什么:我不使用零延迟中断。 我只有一个 swi (使用 FPU)被2倍 CAN hwis 抢先。

    我将继续测试并随时更新。

    BR

    Lorenzo。

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

    很高兴听到它仍在运行。 因此、没有任何内容写入防护区域...正确。

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

    我刚刚和 Alan 交谈过。 我们错过了您使用的 SYS/BIOS 版本。 是的、Chester 指向的错误位于您的版本中。 当零延迟或高中断优先于正在运行的中断时、会有一个小的竞争窗口。 线程中的修复是推荐的解决方案。 我们已在较新版本的 SYS/BIOS (6.46)中修复了这一问题、但遗憾的是、没有针对 TivaC 版本的 TI-RTOS 具有修复功能(虽然可能可行、但我们不建议将 SYS/BIOS 版本与针对 TivaC 的 TI-RTOS 混合使用)。

    鉴于需要发布产品、最好的解决方案是使用您拥有的修复程序。

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

    您好 Todd、

    它仍然运行得非常完美!

    我将继续测试、直到星期一。

    然后、我将帖子标记为已解决。

    感谢您的观看。

    P. S。是否有发布用于 Tiva 的新 TI_RTOS 的计划日期? Relaxed️ μ A

    Lorenzo。

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

    [引用用户="Lorenzo Verniani"]它仍然运行良好!

    很棒!

    [引用 user="Lorenzo Verniani"]然后我将该帖子标记为已解决。

    谢谢

    [引用用户="Lorenzo Verniani]P. S。是否有发布用于 Tiva 的新 TI_RTOS 的计划日期? Relaxed️[/报价]

    不幸的是、不是 我们没有针对 Tiva 的 TI-RTOS 的任何调度补丁版本。 您需要在您拥有的版本中保留错误修复。

    Todd