【问题标题】:Hard fault in FreeRTOS in xPortPendSVHandlerxPortPendSVHandler 中 FreeRTOS 中的硬故障
【发布时间】:2020-07-30 22:17:45
【问题描述】:

我在 ATSAME54 (ARM Cortex-M4) 上运行的 FreeRTOS 应用程序出现硬故障。

我只使用静态分配的内存。当我以非常高的速率向它发送 CAN 消息时,就会发生硬故障。我需要运行它几秒钟到一分钟。

硬故障的类型是精确的 BusFault 错误(CFSR.PRECISERRCFSR.BFARVALID 位设置),BFAR5a5a5a5a

我使用来自https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html 的代码解码了堆栈帧。

这给出了:

r0  = 200030e8   <= part of a task stack
r1  = 200030a4
r2  = 5a5a5a5a   <= same as BFAR
r3  = 20003934
r12 = 2000317c   <= pxCurrentTCB
lr  = a5a5a5a5   <= ????? could this be the reason?
pc  = 00000955   <= in the middle of xPortPendSVHandler
psr = 00000960

随着内存任务堆栈r0 指向,FreeRTOS 内存启动。作为我的测试之一,我在两者之间设置了一个内存屏障,但这并没有改变,所以如果堆栈损坏,则不是因为从 FreeRTOS 内存写入我的任务堆栈。

5a5a5a5a 值恰好是 FreeRTOS 添加到其结构中的完整性检查值。 a5a5a5a5 是堆栈内存的正常填充值。

我还可以尝试找出是什么原因造成的?

【问题讨论】:

  • atollic studio 将为您解码 :)。迄今为止 IMO 最好的 IDE。
  • 你应该在hardfault handler处调试并停止,你应该很容易找到中断前的PC和导致无效内存访问的指令。如果您使用具有调试功能的 ide 或 gdb,这应该很简单,因为它应该自动为您解码堆栈。
  • @P__J__ 我同意,可惜它不再支持非 ST 处理器。
  • @RealtimeRik 它是 STM 的一部分。但不幸的是,他们继续在 atollic 上工作,他们发布了 STMCubeIDE——它甚至不接近 orinal atollic
  • @Damiano 如果调试 RTOS 应用程序如此简单......

标签: c arm freertos cortex-m


【解决方案1】:

最后,我找不到问题。我采取了完全删除 FreeRTOS 并用一些裸机代码替换它的方法。这完美无缺。然而,这不是一个令人满意的解决方案,也不是 FreeRTOS 出现问题时的通用解决方案。f

在我的研究中,我发现 ARM 程序代码应该是字对齐或半字对齐(16 位或 32 位宽的指令),所以0x955 对于程序计数器来说是一个奇怪的值。它也非常接近 PSR 的值,所以这让我想知道堆栈解码是否正确发生,以及发生硬故障时的 PC 是否实际上没有指向其他地方。

【讨论】:

  • 请注意,0x960 对于 PSR 来说是一个奇怪的值。您是否考虑过堆栈错位?堆栈在异常进入和退出时必须是 8 字节对齐的(请参阅 ARM DDI0419C B1.5.7)。编译器会为 C 代码处理这个问题,但如果有任何手工编码的汇编器,它必须注意保持 8 字节堆栈对齐。
【解决方案2】:

xPortPendSVHandlerFreeRTOS 的上下文切换器。如果在那里发生总线故障,除了损坏的堆栈帧之外,由于 SRAM 中的任务控制块损坏,您可能有一个损坏的进程堆栈指针。您可能需要使用静态分析器来检查代码中的常见错误,例如 NULL 指针取消引用、数组索引越界等。此外,它仅在以高速率发送消息时才会发生,这使得它看起来像是与赛车相关的问题。

【讨论】:

    猜你喜欢
    • 2018-05-27
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 2016-12-18
    • 2020-11-10
    相关资源
    最近更新 更多