简体   繁体   English

xPortPendSVHandler 中 FreeRTOS 中的硬故障

[英]Hard fault in FreeRTOS in xPortPendSVHandler

I have a hard fault occurring in my FreeRTOS application running on ATSAME54 (ARM Cortex-M4).我在 ATSAME54 (ARM Cortex-M4) 上运行的 FreeRTOS 应用程序发生了硬故障。

I am only using statically allocated memory.我只使用静态分配的 memory。 The hard fault occurs when I am sending CAN messages to it at a very high rate.当我以非常高的速率向它发送 CAN 消息时,就会发生硬故障。 I need to run it for a couple of seconds up to one minute.我需要运行它几秒钟到一分钟。

The type of hard fault is a precise BusFault error ( CFSR.PRECISERR and CFSR.BFARVALID bits set), with a BFAR of 5a5a5a5a .硬故障的类型是精确的 BusFault 错误(设置了CFSR.PRECISERRCFSR.BFARVALID位), BFAR5a5a5a5a

I decoded the stack frame using the code from https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html .我使用https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html中的代码解码了堆栈帧。

This gives:这给出了:

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

Following the memory task stack r0 points to, the FreeRTOS memory starts.在 memory 任务堆栈r0指向之后,FreeRTOS memory 启动。 I have put a memory barrier in between the two as one of my tests, but this stays untouched, so if there is corruption of the stack it is not by something writing from the FreeRTOS memory into my task stack.作为我的测试之一,我在两者之间放置了一个 memory 屏障,但这保持不变,所以如果堆栈损坏,这不是因为从 FreeRTOS memory 写入我的任务堆栈。

The 5a5a5a5a value happens to be the integrity check value that FreeRTOS adds to its structures. 5a5a5a5a值恰好是 FreeRTOS 添加到其结构中的完整性检查值。 The a5a5a5a5 is the normal fill value for stack memory. a5a5a5a5是堆栈 memory 的正常填充值。

What more can I try to find out what is causing this?我还能尝试找出导致这种情况的原因吗?

In the end, I could not find the issue.最后,我找不到问题。 I resorted to removing the FreeRTOS altogether and replace it by some bare metal code.我采取了完全删除 FreeRTOS 并用一些裸机代码替换它的方法。 This worked flawlessly.这完美无缺。 This is, however, not a satisfying solution route, and is also not a general solution in case of issues with FreeRTOS.f但是,这不是一个令人满意的解决方案,也不是 FreeRTOS.f 问题的通用解决方案

During my research, I found that ARM program code should be word-aligned or half-word aligned (16-bit or 32-bit wide instructions), so 0x955 is a strange value for a program counter.在我的研究中,我发现 ARM 程序代码应该是字对齐或半字对齐(16 位或 32 位宽的指令),所以0x955对于程序计数器来说是一个奇怪的值。 It is also remarkably close to the value of the PSR so this makes me wonder whether the stack decoding happened correctly and whether the PC at the time of the hard fault was not actually pointing elsewhere.它也非常接近 PSR 的值,所以这让我想知道堆栈解码是否正确发生,以及发生硬故障时的 PC 是否实际上没有指向其他地方。

xPortPendSVHandler is FreeRTOS 's context switcher. xPortPendSVHandlerFreeRTOS的上下文切换器。 If a bus fault happens in there you may have a corrupted process stack pointer as a result of a corrupted task control block in SRAM, besides the corrupted stack frame.如果在那里发生总线故障,除了损坏的堆栈帧之外,由于 SRAM 中的任务控制块损坏,您可能有一个损坏的进程堆栈指针。 You may want to use a static analyzer to check the code for common bugs like NULL-pointer de-references, array index out-of-bounds and such.您可能需要使用 static 分析器来检查代码中的常见错误,例如 NULL 指针取消引用、数组索引越界等。 In addition, the fact that it only happens when sending messages at a high rate makes it look like a racing related problem.此外,它仅在以高速率发送消息时发生的事实使它看起来像是与赛车相关的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM