Skip to main content
Visitor II
September 2, 2016
Question

Memory Hard fault with string lib

  • September 2, 2016
  • 3 replies
  • 1887 views
Posted on September 02, 2016 at 15:29

Hi everyone,

I have a question about an hard fault generated by a line of code.

I'm working with a STM32F401RE and Atollic True Studio

The line is :

sprintf

(str,

''PAIR %s\r''

,BT_deviceTAB[0].BDADDR);

the BT_deviceTAB[0].BDADDR type is char tab[13];

and previously filled with a string ended with '\0'

The hardfault is :

Bus, memory management or usage fault (FORCED)

 

Attempt to switch to invalid state (INVSTATE)

But when i use the following methode i don't have any problems :

strcpy

(str,

''PAIR ''

);

strcpy

(name,BT_deviceTabHeadset[BT_number].BDADDR);

strcat

(str, name);

Do you have an explanation of how this functions works.

I'm very surprised that sprintf generate memory hard fault Oo !

Thanks a lot

#sprintf-hardfault

    This topic has been closed for replies.

    3 replies

    Graduate II
    September 2, 2016
    Posted on September 02, 2016 at 17:43

    I'd look at the machine instructions that are faulting, and the registers. Hard Faults are gross in nature they should be pretty easy to identify and solve with a handler that outputs diagnostic information (or reviewing the stacked state) and some basic debugging skills.

    With printf/scanf function you'd want to make sure you have an adequate stack allocation.

    Visitor II
    March 22, 2024

    I am having the same issue using various   sprintf(usb_buffer, "vis modify_btn,0"); calls with STM32F446RETx and STM32CubeIDE.   I have increased/decreased STACK and HEAP with no changes.  Fault will occur at the same line of code regardless of Stack/Heap size.  

    Can you give me some direction on "Hard Faults are gross in nature they should be pretty easy to identify and solve with a handler that outputs diagnostic information (or reviewing the stacked state) and some basic debugging skills."

    Graduate II
    March 22, 2024

    Its a topic I've covered several times on the forum. Avail of a search.

    Look at the code/registers at the site of the fault, and work backward. Understand what the MCU is objecting too in it's language, and then relate that to your source.

    If it's not the stack, it's likely the pointer, what it points too, where and the size.

    https://github.com/cturvey/RandomNinjaChef/blob/main/KeilHardFault.c

     

    Super User
    March 22, 2024

    <on my soapbox>And please stop using sprintf() and switch to snprintf().  Helps prevent buffer overflows.  This may not be your issue in this case, but it is just plain good programming practice.  Likewise, strncpy() instead of strcpy() - though strncpy() has an annoying quirk that it does not NULL terminate the destination if the source is longer than the "length" parameter.<off soapbox>

    Visitor II
    March 22, 2024

    Tesla Delorean,  Thanks for the suggestion.

    Bob S, thanks for the reply.  snprintf() may be the better choice.

    But I found what the issue is.  It is the stack size allocated in the FREERTOS for each task was set to 128 bytes, this needed to be increased.  I set it to 512.  Apparently, the buffer that is being loaded with sprintf is being sent via the Usart task was overrunning the Usart app stack.  Not sure why it was causing the stack to grow as I would think after each Usart call is completed the stack would return?   I am using the Usart in DMA mode.

     

    Any idea why the stack was being overwritten?

     

     

     

    Visitor II
    March 23, 2024

    What is:

    strcpy (name,BT_deviceTabHeadset[BT_number].BDADDR);

    the  BT_deviceTabHeadset[BT_number].BDADDR ?

    If this is just a value, not an address (!) - you will crash!

    Yes, sprintf (or snprintf) might be needed to convert a value into a string stored on memory so that you can use strcpy() or strcat() - which need two pointers to C-strings (NUL-terminated).

    Adding just a value to a string, via strcpy() or strcat() "must" fail, because a value is not a valid pointer (pointing to a memory location, where the value would be stored, instead).

    Pointers and Values are two different things. Using a Value as a Pointer (memory address) - will (potentially, luckily) crash.