STM32 RTX 使用故障 PSP 0x00000020

STM32 RTX Usage Fault PSP 0x00000020

我有一个带有 RTX 的 STM32F446 项目,3 个线程(主线程 + 2 个由我声明)+ 当然是空闲线程。主线程在启动两个线程后进入等待状态,所以我只有两个线程运行。 RTX 已禁用循环法。该应用程序所做的是通过 SPI 与蓝牙模块通信。

我的问题是有时,在 SPI 传输期间(由一个线程启动并在另一个线程中完成)MCU 崩溃到 UsageFault_Handler 并且其中一个线程(不总是相同的)显示为溢出。现在我已经阅读了有关如何调试硬故障的信息,但问题是所有方法都依赖于 MSP/PSP 地址,对我来说 PSP 是 0x00000020。 有人遇到过类似的事情吗?关于可能出错的任何想法?

LE:我后来了解到该代码适用于 FreeRTOS 而不是 RTX。该代码使用临界区。我曾尝试对 RTX 的关键部分使用与 FreeRTOS(BASEPRI) 相同的实现,但我经常以 UsageFault 告终。 我知道 RTX 在代码中广泛使用了 SVC。

是否应该以不同方式实现关键部分? 您是否知道 FreeRTOS 和 RTX 之间可能导致问题的任何其他差异?

稍后编辑(已解决): 结果发现问题与分配给 SysTick 的优先级有关。它首先被设置为最低优先级,但一段代码在某处将 SysTick 设置为非常高的优先级。

谢谢!

当函数 return 恢复其堆栈指针时,如果堆栈已损坏,可能会恢复无效值,因此 SP 中的值不是特别有用或提供信息。

当然,包括程序计数器在内的所有其他寄存器也可能已损坏。 UsageFault 发生在未定义的指令、未对齐的内存访问上——如果使用损坏的堆栈执行 return,这两种情况都可能发生,因为 return 可能在任何地方结束。您甚至可能会发现更改代码会导致 不同的 故障类型。如果不查看代码,则无法确定原因,但可能的问题是本地数据缓冲区溢出或分配的堆栈 space 不足。

也许诊断此故障的最简单方法是使用具有跟踪功能的调试硬件,尽管这些硬件比更简单的 JTAG 或 SWI 调试器更昂贵。