cancel
Showing results for 
Search instead for 
Did you mean: 

Memory Hard fault with string lib

dauphin2
Associate II
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

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

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

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

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

 

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

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

FJB2069
Associate III

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?

 

 

 

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.