freeRTOS Bad sprintf behavior

dajar wrote on Sunday, May 17, 2009:

I have been fighting with sprintf outputting floats. I need to be able to print formatted floating point data. I created a gatekeeper task for the serial port and put sprintf under that task. sprintf can only run within the gatekeeper task.

As a test case I modified the sprintf statement to

sprintf( OutString, "% 06.2f", 23.456 );

and I get " 00.00" in OutString. Any float value returns a zero. Modifying for integers works fine.

I have researched this problem and found the two most common comments are stack size and reentrancy. I have made sure that the stack for the task is large enough, 1500 words are unused on the stack according to the high water mark routines. To test for reentrancy issues, I ensured that the gatekeeper is the highest priority, and even have gone as far as putting sprintf within a critical area and turned off interrupts. Nothing has worked.

This same sprintf line works fine before I start the scheduler, so it is not a library issue.

Any suggestions?
Thanks.

davedoors wrote on Sunday, May 17, 2009:

This has come up here a few times. Set the stack alignment in the task to be 8 instead of 4 and it should then work.

frankandersen wrote on Monday, May 18, 2009:

Hi,

If you are using the IAR compiler, then try this in port.c

portSTACK_TYPE *pxOriginalTOS;

        #if (__IAR_SYSTEMS_ICC__ >= 7) /* if EW 5.x or higher */
        if (((portBASE_TYPE)pxTopOfStack) & 0x7)
        {
          pxTopOfStack = (portSTACK_TYPE *)(((portBASE_TYPE)pxTopOfStack) & ~0x7);
        }
        #endif 

    pxOriginalTOS = pxTopOfStack;

Best regards,

Frank Andersen

dajar wrote on Monday, May 18, 2009:

Dave,

Then only thing I can find for setting the stack alignment is in portmacro.h as:

#define portBYTE_ALIGNMENT 4

After setting this value to 8 the problems remains unchanged.

Frank,

Thanks, but I am using the CodeSourcery Lite GCC compiler. I am also using Cortex and have looked through the port.c file for something similar, but cannot figure out which function you are suggesting that I modify.

dajar wrote on Monday, May 18, 2009:

Dave,

Then only thing I can find for setting the stack alignment is in portmacro.h as:

#define portBYTE_ALIGNMENT 4

After setting this value to 8 the problems remains unchanged.

Frank,

Thanks, but I am using the CodeSourcery Lite GCC compiler. I am also using Cortex and have looked through the port.c file for something similar, but cannot figure out which function you are suggesting that I modify.

dajar wrote on Monday, May 18, 2009:

It looks like there is some sort of an alignment issue. I made some code changes to a total unrelated area of the code and now sprintf is working.

I will have to experiment some more when it break again.

frankandersen wrote on Tuesday, May 19, 2009:

Hi Stephen,

In port.c it is the function portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )

just in the top of it.

It is the stack, that is aligned wrong when calling the sprintf function, I had problem where it was working from one task, but not from another.

Try to remove the #if … and see if it helps you.

Best regards,

Frank Andersen