2025-02-17 10:17 PM
Hi,
I am encountering a hard fault on my STM32F407ZG when using snprintf(). We are using FreeRTOS for the development.
The system resets due to a precise data access violation (PRECISERR).
Below is the fault status:
HFSR: 0x40000000
BFAR: 0x38383600
BF: 0x82
PC: 0x0806D62E at "_Balloc"
This error occurs randomly after multiple calls to snprintf(). Below is a simplified version of my actual code:
#define BUF_SIZE 10
char temp_str[9][BUF_SIZE];
float temp[9];
for (int n = 0; n < 9; n++) {
snprintf(temp_str[n], BUF_SIZE, "%.3g", temp[n]);
}
Fault Trace:
task1() → snprintf() → _svfprintf_r() → _dtoa_r() → _Balloc() → <signal handler called>() → HardFault_Handler() at STM32f4xx_it.c
Memory Layout (Snippet from Linker Script):
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20020000; /* end of RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x08040000, LENGTH = 1024K
}
Any insights or debugging tips would be greatly appreciated!
2025-02-17 11:00 PM
I didn't work with FreeRTOS on a F40x, to put this first.
But the fault being triggered by a memory allocation function points to an issue with stack/heap sizes.
AFAIK "_Balloc()" allocates storage for a "big integer" to store a floating point variable.
Using bare-metal code, I use to be generous with stack size when I intend to use floats in printf-style functions, usually at least 2kByte.
Not sure how this is implemented in your environment.
2025-02-18 12:55 AM
Thanks @Ozone ,
I have task1() running which is of 512Bytes, I tried increasing it to 1KBytes but facing same issue. I also check the available free stack size for each task running and I can see that there is generous amount for stack free.
The only thing is, this task1() keep calling snprintf() and let's say once in 12-15 hours hardfault occurs.
2025-02-18 01:13 AM
Unfortunately I'm lacking the detailled experience with FreeRTOS here.
I had to deal with OSEK/VDX some while ago, and there one had to set stack sizes for each task separately, in some specific OSEK handler. And those were managed inside OSEK, unrelated to the stack/heap settings applied bythe toolchain and relating to the clib.
I would inspect the fault address(es), and cross-reference it with the map file.
This should give you an idea where it happens.
As a side note ...
I remember another task/stack related issue I had come across, which might apply to your situation as well.
In this case, a realtime task re-used a pointer to a stack variable from a previous run, causing all sorts of strange side effect. Mind you, this was a system without MPU, so the address was not illegal as such, but already belonged to something else.
As further explanation, realtime tasks in OSEK are executed as a sequence of function calls, which are expected to terminate in a certain time limit. They are not implemented as endless loops.
Not sure how this applies to FreeRTOS, AFAIK this can be configured.
2025-02-18 01:15 AM
I don't use FreeRTOS nor other RTOS so won't provide detailed help, but you may want to read this.
JW