cancel
Showing results for 
Search instead for 
Did you mean: 

Does STM32CubeIDE and Azure RTOS properly support Sprintf?

GreenGuy
Lead

I am having issues using sprintf in an application on a STM32H743 using Azure RTOS.  The function works correctly the first time it is used to convert a float to a string but after the first use, it inserts garbage characters where the decimal point should be while the digits are as expected.  The garbage characters continue to show up on subsequent calls to the routine where the sprintf is used and show up in other routines that use sprintf.  The garbage characters are always the same and only appear for float values that have digits to the right of the decimal point.  An example is when printing the conversion for the internal battery measurement which comes out as ...MCU Bat : 3.15 V on the first pass, then comes out as ...MCU Bat : 3"KOq@=xZ15 V on the second pass.  It is repeatable.  The format string is ...MCU Bat : %.2f V\r.  Changing the format string does not seem to effect the result.

I have gone over numerous posts regarding sprintf and RTOS but none seems to match with what I have implimented and what I am seeing.  There are no hard faults or crashing.  

Version info:

STM32CubeIDE - Version: 1.14.1 - Build: 20064_20240111_1413 (UTC)

STM32CubeMX - STM32 Device Configuration Tool - Version: 6.10.0-RC9 - Build: 20231120-2037 (UTC)

Linux LMint 21

 

1 ACCEPTED SOLUTION

Accepted Solutions
GreenGuy
Lead

An an answer with solutions that work this is the summary.

I had to set Optimization to something other than none to get sprintf to work with floats correctly after ThreadX was instantiated.  The other option is to avoid the use of floats by reducing floats to integer values before and after the decimal point and sprintf them separate with %d.%d.

 

I think this is a bug in the compiler since setting Optimization to none does something with the standard c library that affects its runtime code.  So the above solutions are work arounds.  It is noted that there are various valid complaints concerning the lack of reentrancy with respect to the standard C libraries that come with the CubeIDE toolset.

View solution in original post

20 REPLIES 20
AScha.3
Chief III

I would set in debug a breakpoint at the sprintf line , to look , what is the float now ; + whats in the string, after sprintf ; then run ..and look.

+

what did you set : in project settings ->

AScha3_0-1713375383532.png

 

If you feel a post has answered your question, please click "Accept as Solution".
GreenGuy
Lead

GreenGuy_0-1713376013369.png

 

I guess I could uncheck the scanf option since it is not used.  But that does not make a difference.

I already did the break point on the sprintf line.  The float values are good and the string after the sprintf has the garbage characters in it.  I also tried stepping into the sprintf function but it simply steps over it.  The local string buffer is initialized to all 0 upon entering the routine containing the sprintf.

 

 

> I also tried stepping into the sprintf function but it simply steps over it.

Hm - whats your optimizer setting ?

+

Just for test: set D-cache off (or dont enable it ), to be sure its not just some ...cache effect.

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

Pull the full runtime, not the nano stuff.

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

@GreenGuy  Please test before starting the RTOS scheduler. If that works, you'll need to fix the multi-threading locks in newlib for ThreadX.

maximum(g3)

Dcache disabled changes the inserted garbage but still garbage.

Also, applied cache maintenance (SCB calls) but no change in behavior and yet the garbage is different.

 

that will take a good deal of rearranging since I use threading to send the messages.

But it is worth a try to understand what is wrong with sprintf.

Right now my work around is to reduce every thing to non decimal by doing:

bat_left = (UINT)battery;

bat_right = (UINT)((battery - bat_left)*100); //2 decimal places

and then just building the message with %d.%d - no problems!

 

can you translate into steps relative to files and perhaps CubeMX?