Skip to main content
Visitor II
October 27, 2021
Solved

sprintf gives a hard fault

  • October 27, 2021
  • 5 replies
  • 4200 views

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

    This topic has been closed for replies.
    Best answer by Jocelyn RICARD

    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

    5 replies

    Super User
    October 27, 2021

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

    APede.1Author
    Visitor II
    October 27, 2021

    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

    Graduate II
    October 27, 2021

    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..

    APede.1Author
    Visitor II
    October 28, 2021

    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 ?

    ST Employee
    October 29, 2021

    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

    Visitor II
    November 17, 2022

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

    APede.1Author
    Visitor II
    October 29, 2021

    Hi Jocelyn 

    I tested it out and it works.

    Thank you for your fast help.

    Best regards

    Anders