cancel
Showing results for 
Search instead for 
Did you mean: 

sprintf gives a hard fault

APede.1
Associate II

Hi

I have a problem where my NUCLEO-U575ZI-Q board gets a hard fault if I use sprintf.

I reproduced the error by creating a new project based on the sample project "Tx_Thread_Sync". So I am using Threadx.

I then added two lines to the app_threadx.c

 char str[80];

 sprintf(str, "Value of Pi = %u", 3);

And then places a breakpoint at the variable definition. I run the code and when I click on step into the function for debugging the sprintf function the MCU goes directly to HardFault_Handler instead.

Please help.

What to do so I can use sprintf??

Best Regards

Anders

1 ACCEPTED SOLUTION

Accepted Solutions
Jocelyn RICARD
ST Employee

Hello @APede.1​ 

The issue is related to the thread stack size.

In the tx_Thread_Sync example, the thread stack size is set to 512B

The thread creation call uses the define APP_STACK_SIZE

Also, the stack is allocated in the byte pool provided as argument of App_ThreadX_Init function.

So, byte pool size needs to be increased accordingly.

To do this, you open the ioc file to get CubeMX interface, go to middlewares/ThreadX and ThreadX Tab. Memory configuration Topic: change ThreadX memory pool size to say 10*1024 to give room for further allocations and re-generated code with CTRL-S or ALT-K

Then in App_ThreadX_Init:

Replace APP_STACK_SIZE by APP_STACK_SIZE*4

if (tx_byte_allocate(byte_pool, (VOID **) &pointer, APP_STACK_SIZE*4, TX_NO_WAIT) != TX_SUCCESS)

And same for thread create:

if (tx_thread_create(&ThreadOne, "Thread One", ThreadOne_Entry, 0, pointer, APP_STACK_SIZE*4, THREAD_ONE_PRIO,

            THREAD_ONE_PREEMPTION_THRESHOLD, DEFAULT_TIME_SLICE, TX_AUTO_START) != TX_SUCCESS)

After executing in debug mode you can open the Window/Showview/ThreadX/ThreaXThreadList

In the ThreadX Thread List window, you will need to click on the top left icon with the 3 horizontal lines.

This will activate the Stack Usage column of this view.

On my side I could see a stack usage of 676 bytes when adding this sprintf.

So, you could have increased size to only APP_STACK_SIZE*2 but when you are not sure it is always better to have margin.

Best regards

Jocelyn

View solution in original post

7 REPLIES 7
TDK
Guru

sprintf can use the heap and may be failing an allocation.

If you feel a post has answered your question, please click "Accept as Solution".
APede.1
Associate II

I use the standard settings:

_Min_Heap_Size = 0x200 ; /* required amount of heap */

0x200 = 512 bytes

I just tried with

_Min_Heap_Size = 0x2000 ; /* required amount of heap */

0x200 = 8192bytes

Same error - Hard Fault

Yeah, so you might have to debug what's actually causing the fault. The processor has a number registers to convey details of the fault, and the context is pushed on the stack.

If you can pin-point the instructions, and addresses it is objecting too you can work toward where the problem is.

Watch stack allocations, perhaps make str[] a static allocation an see if it moves/changes the problems.

Check also what libraries you're linking, the Cortex-M isn't going to run 32-bit ARM code..

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
APede.1
Associate II

If define str[] static and then it works.

I then tried to define it in the function and increase the stack size to 0x4000 and 0x40000. But it still fails. Default is 0x400.

When I get hard fault the CFSR register is 0x100000 which seems to be an Unaligned access flag.

Unaligned access flag. Sticky flag indicating whether an unaligned access error has occurred.

https://developer.arm.com/documentation/100235/0004/the-cortex-m33-peripherals/system-control-block/configurable-fault-status-register

Any help/experience in how to avoid that ?

Jocelyn RICARD
ST Employee

Hello @APede.1​ 

The issue is related to the thread stack size.

In the tx_Thread_Sync example, the thread stack size is set to 512B

The thread creation call uses the define APP_STACK_SIZE

Also, the stack is allocated in the byte pool provided as argument of App_ThreadX_Init function.

So, byte pool size needs to be increased accordingly.

To do this, you open the ioc file to get CubeMX interface, go to middlewares/ThreadX and ThreadX Tab. Memory configuration Topic: change ThreadX memory pool size to say 10*1024 to give room for further allocations and re-generated code with CTRL-S or ALT-K

Then in App_ThreadX_Init:

Replace APP_STACK_SIZE by APP_STACK_SIZE*4

if (tx_byte_allocate(byte_pool, (VOID **) &pointer, APP_STACK_SIZE*4, TX_NO_WAIT) != TX_SUCCESS)

And same for thread create:

if (tx_thread_create(&ThreadOne, "Thread One", ThreadOne_Entry, 0, pointer, APP_STACK_SIZE*4, THREAD_ONE_PRIO,

            THREAD_ONE_PREEMPTION_THRESHOLD, DEFAULT_TIME_SLICE, TX_AUTO_START) != TX_SUCCESS)

After executing in debug mode you can open the Window/Showview/ThreadX/ThreaXThreadList

In the ThreadX Thread List window, you will need to click on the top left icon with the 3 horizontal lines.

This will activate the Stack Usage column of this view.

On my side I could see a stack usage of 676 bytes when adding this sprintf.

So, you could have increased size to only APP_STACK_SIZE*2 but when you are not sure it is always better to have margin.

Best regards

Jocelyn

APede.1
Associate II

Hi Jocelyn 

I tested it out and it works.

Thank you for your fast help.

Best regards

Anders

Thanks RICARD! I was having a similar Hard Fault while in a thread and stack size was the issue. Nicely done!