Bad sprintf() behaviour on PIC32

thomashh wrote on Thursday, November 18, 2010:

Hi there,

I’m a newbie on freeRTOS.
I have a problem with using sprintf() for converting a float value within a task.
I’ve seen that some other guys had the same problem in the past.
Unfortunately I’m not very familiar with the kernel itself and I’m relatively new on C programming at all.

The problem occurs when I want to print a float value into a string using sprintf(). After the conversion the string content is always “-0.000”. I read several posts but I haven’t found a solution for PI32.
I’ve seen that some people got it work but on other ports.

Can anybody tell me what I have to do to get the sprintf() properly working with float numbers on the PIC32?

Setup:
C32 Compiler v1.11(b)
freeRtos v.6.0.0
PIC32MX795F512L

Thank you in advance

Tom

rtel wrote on Thursday, November 18, 2010:

Upgrade to at leave version 6.0.2 where you should find it works ok - the issue is due to the stack alignment requirement of the sprintf() library call.  Best off to use V6.1.0 in fact which is the latest.

Regards.

thomashh wrote on Friday, November 19, 2010:

Hi there,

it’s working with version V6.1.0!!
Many many thanks Barry.
You saved me from a heart attack… :wink:

Regards

Tom

bkerske wrote on Wednesday, November 06, 2013:

I am having this same issue with version 7.1.1. I am using C32 v1.11b and PIC32MX695F512L. Can you elaborate on the stack alignment or point me in the right direction to fix this? Is it a configuration aspect of freeRTOS? Is it a Microchip library issue?
Thanks for any help!

rtel wrote on Wednesday, November 06, 2013:

XC V1.2.1, FreeRTOS V7.5.3:

It looks like the stack is 4 byte aligned, which I think is correct from the MIPS documentation (even though the alignment setting in portmacro.h is 8).

My first attempt was with printf-stdarg.c included in the build, and sprintf’ing a %f worked no problem (didn’t realise it was supported in that file?).

I then removed printf-stadarg.c to use the GCC library. Again, it seems to work as expected.

However, when I changed %f to %lf, I got garbage output, and changing to 8 byte aligned stacks made no difference to that.

Can you elaborate on the format string you are using to get the error?

Regards.

bkerske wrote on Wednesday, November 06, 2013:

Here are a couple examples that I just tried.

TestFloat = 1.234;
(void)sprintf(TxDataBuffer, “Test: %f”, TestFloat );
Result
Test: -0.000000

TestFloat = 1.234;
(void)sprintf(TxDataBuffer, “Test: %1.3f”, TestFloat );
Test: -0.000

rtel wrote on Wednesday, November 06, 2013:

Ok - which sprintf() implementation are you using (the one that comes with the XC compiler?).

Some GCC printf() routines call malloc(). If you are using an official FreeRTOS demo as a base for your application then it is likely that the project is configured without a heap because FreeRTOS manages its own heap. If you define a heap for your project does it make a difference?

Finally, go into FreeRTOS/Source/portable/MPLAB/PIC32MX/port.c. Near the top of the file you will find a function called pxPortInitialiseStack(). One of the first lines in the function should be “pxTopOfStack–;” Try changing this line to pxTopOfStack-=2; That will change the stack byte alignment. Does that make a difference?

Regards.

bkerske wrote on Tuesday, November 12, 2013:

Sorry for the long delay…

I am still using the C32 v1.11 compiler and yes I’m using the one that comes with the compiler.

I already had a 5k heap defined so I went right to your last suggestion and modified port.c. This corrects the situation. I truly appreciate the quick response. I can now go back and remove all the nasty “work around” code I had to write.

On this note, this seems like a fundamental change, how are “other” aspects of the software not running into issues if the stack isn’t aligned correctly? Any suggestions on what other type of “sprintf” functions will have odd behavior? Is it just contained to malloc operations? I’m just trying to figure out what I should go back and test a little deeper.

Thanks again.