xPortPendSVHandler 中 FreeRTOS 中的硬故障

问题描述 投票:0回答:4

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

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

硬故障类型是精确的 BusFault 错误(

CFSR.PRECISERR
CFSR.BFARVALID
位设置),
BFAR
5a5a5a5a

我使用来自 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
是堆栈内存的正常填充值。

我还可以尝试什么来找出导致此问题的原因?

c arm freertos cortex-m
4个回答
1
投票

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

在我的研究过程中,我发现ARM程序代码应该是字对齐或半字对齐(16位或32位宽指令),因此

0x955

对于程序计数器来说是一个奇怪的值。它也非常接近 PSR 的值,所以这让我想知道堆栈解码是否正确发生,以及硬故障时的 PC 是否实际上没有指向其他地方。


1
投票

xPortPendSVHandler

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


0
投票
有一个类似的问题,在我的例子中,将任务堆栈大小从 128 个字扩大到更大的值解决了我的问题


0
投票
我也遇到了同样的问题,事实上,它与堆栈溢出有关。

在我的例子中,我使用特定 GPIO 引脚中的上升沿/下降沿中断来解码温度传感器 (DHT22)。我将边缘之间的间隔存储在缓冲区数组中,并在每个中断事件中递增它。

事实是,由于一些电气间歇性,我的缓冲区变得异常高,并且堆栈边界被侵犯。 就我而言,我通过限制缓冲区大小的单个条件解决了这个问题,即,我为其设置了“增长限制”!

© www.soinside.com 2019 - 2024. All rights reserved.