Due to restrictions of the ARM EABI, printing floats correctly requires a couple of adjustments to the project and code:
The printf formatter must support float types. The Large or Full printf formatter must be selected in the IAR project menu under Options... > General Options > Library Options. Similarly, if scanf is used to parse float inputs, the appropriate scanf formatter should be selected.
The uC/OS-II task stack from which printf is called must be 8-byte aligned.
In most cases while prototyping, we will want to print float values in response to CLI commands. In order to print floating point values from the CLI task in an On-Chip SDK application, adjust the following declaration of cli_task_v in src/app/common/cli_task.c:
//=========================== variables ======================================= typedef struct { OS_STK cliTaskStack[CLI_TASK_STK_SIZE]; char* appName; dnm_ucli_cmdDef_t const* cliCmds; INT32U cliChannelBuffer[1+DN_CH_ASYNC_RXBUF_SIZE(DN_CLI_NOTIF_SIZE)/sizeof(INT32U)]; CH_DESC cliChannelDesc; INT8U numCliCommands; } cli_task_vars_t; #pragma data_alignment = 8 cli_task_vars_t cli_task_v;
Notice that the cliTaskStack field is moved to the beginning of the structure so that it is sufficient to align the cli_task_v variable. If the stack field was not at the beginning of the structure, we would have to align the cli_task_v variable and ensure that the fields before the stack occupied a multiple of 8 bytes.
In order to print floats from other tasks, it’s necessary to align the stack of the appropriate task. In the simplest case, when the task stack is declared separately, it’s straightforward to specify the data alignment.
In general, it’s possible to align the stack of any task using the data_alignment
pragma, as shown below for an arbitrary stack:
// app variables #pragma data_alignment = 8 OS_STK myTaskStack[STACK_SIZE]; // prototypes static void myTask(void* unused); void myStackInit() { // .. called from some init function .. // create the task osErr = OSTaskCreateExt( myTask, (void *) 0, (OS_STK*) (&myTaskStack[STACK_SIZE-1]), PRIORITY, PRIORITY, (OS_STK*) &myTaskStack, STACK_SIZE, (void *) 0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR ); }
If the task stack is defined as a member of a structure, then it’s best to put the stack at the beginning of the structure and ensure the definition of the structure is aligned.
See also http://supp.iar.com/Support/?Note=85413.