snprintf() does not appear to work with floating point format within a task. Appears to work normally from main().
Please advise why, and what other functions may be affected similary?
I modified a 'blinky' project and observed the fault under simulation, single step, watch memory 'buffer'.
Seems to work ok if called from main.
---------------------------------------------- char buffer[100];
void test1(void) { float f;
f = 3.14159;
snprintf(buffer,100-1,"%f",f);
/* HELP!!!!! contents of buffer are now '0.000000' , should be '3.141590' */ } /*---------------------------------------------------------------------------- * Task 1 'phaseA': Phase A output *---------------------------------------------------------------------------*/ void phaseA (void) __task { for (;;) { test1(); os_evt_wait_and (0x0001, 0xffff); /* wait for an event flag 0x0001 */ IOSET = LED_A; signal_func (t_phaseB); /* call common signal function */ IOCLR = LED_A;
} } -------------------------------------------------------------------
1) Have you checked how to post source code?
2) Have you checked what limitations there are on the RTL when used with a RTOS, i.e. what functions are reentrant, and/or what protection you must help with?
www.danlhenry.com/.../keil_code.png
/* HELP!!!!! contents of buffer are now '0.000000' , should be '3.141590' */
Do you mean that the actual buffer content has been corrupted?
Or do you just mean that "0.000000" is displayed?
1) Source modification reposted below with tags. (project from C:\Keil\ARM\RV30\RTL\Kernel\Examples\Blinky)
2) Documentation states that snprintf (and similar functions): "Typically, they are thread-safe. However if you change locale in mid-session, you must ensure that these functions are not affected.". I have not added code to specifically change locale.
3) If test1() is called from main, the contents of buffer displayed in the debug window are ascii '3.141590'. If test1() is called from a task, the ascii contents of the buffer becomes '0.000000' immediately after returning from snprintf(). My guess would be that the floating point value is somehow corrupted during/after being passed to snprintf().
(thanks all)
/*---------------------------------------------------------------------------- * R T L K e r n e l E x a m p l e *---------------------------------------------------------------------------- * Name: BLINKY.C * Purpose: RTX example program * Rev.: V3.03 / 1-sep-2006 *---------------------------------------------------------------------------- * This code is part of the RealView Run-Time Library. * Copyright (c) 2004-2006 KEIL - An ARM Company. All rights reserved. *---------------------------------------------------------------------------*/ #include <RTL.h> #include <LPC21xx.H> /* LPC21xx definitions */ #include <stdio.h> OS_TID t_phaseA; /* assigned task id of task: phase_a */ OS_TID t_phaseB; /* assigned task id of task: phase_b */ OS_TID t_phaseC; /* assigned task id of task: phase_c */ OS_TID t_phaseD; /* assigned task id of task: phase_d */ OS_TID t_clock; /* assigned task id of task: clock */ char buffer[100]; void test1(void) { float f; f = 3.14159; snprintf(buffer,100-1,"%f",f); /* HELP!!!!! contents of buffer are now '0.000000' , should be '3.14159' */ } ..... /*---------------------------------------------------------------------------- * Task 1 'phaseA': Phase A output *---------------------------------------------------------------------------*/ void phaseA (void) __task { for (;;) { test1(); os_evt_wait_and (0x0001, 0xffff); /* wait for an event flag 0x0001 */ IOSET = LED_A; signal_func (t_phaseB); /* call common signal function */ IOCLR = LED_A; } } ...... /*---------------------------------------------------------------------------- * Task 6 'init': Initialize *---------------------------------------------------------------------------*/ void init (void) __task { IODIR = 0xFF0000; /* P1.16..23 defined as Outputs */ t_phaseA = os_tsk_create (phaseA, 0); /* start task phaseA */ t_phaseB = os_tsk_create (phaseB, 0); /* start task phaseB */ t_phaseC = os_tsk_create (phaseC, 0); /* start task phaseC */ t_phaseD = os_tsk_create (phaseD, 0); /* start task phaseD */ t_clock = os_tsk_create (clock, 0); /* start task clock */ os_evt_set (0x0001, t_phaseA); /* send signal event to task phaseA */ os_tsk_delete_self (); } /*---------------------------------------------------------------------------- * Main: Initialize and start RTX Kernel *---------------------------------------------------------------------------*/ int main (void) { #ifdef MCB2100 U32 volatile start; /* Wait for debugger connection 0.3s*/ for (start = 0; start < 1000000; start++) { ; } #endif os_sys_init (init); /* Initialize RTX and start init */ } /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/
Have you read this link?
http://www.keil.com/support/man/docs/armlib/armlib_chdhgdid.htm
Note that no *printf() functions are listed on this page: http://www.keil.com/support/man/docs/armlib/armlib_chdfgjej.htm
Oops, tvo errors in the previous post...
Error one was that I intended to mention s(n)printf and not *printf.
Error two was that I missed that s(n)printf is in the list of thread-safe functions.
The problem might be much simpler. Can you check if the stack is 8-byte aligned?
The newer versions of the RTX configuration file ensure that, but in early versions (before MDK 3.00) there was a way to mis-align the stack.
see: http://www.keil.com/support/docs/3387.htm
Thanks very much everyone, I'm now back to 3.141590. -Pete.