This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

sprintf slowly fails

Other Parts Discussed in Thread: MSP430F5418A, MSP430F5419

Hello

I am using CCS4.1.3 with an MSP430F5418A device.  I am making calls to sprintf to format floating point numbers.  I am finding that sprintf will periodically fail to properly format the float.  I have read various threads on this issue and have increased my stack and heap sizes accordingly.  I have also built the project using the "full" version of printf.

I set my stack and heap to 2048 bytes and filled the stack with 0xEE to see how big it got.  The stack usage is less than 512 bytes.

I find that if I call the function infrequently, it will work as advertised. 

If I call it every time thru my main() loop it will sometimes put a non-numeric ascii character in the buffer which then causes other functions to fail and the app ultimately crashes.

I have read in other threads that this may be a problem introduced in CCS4 vs CCS3 (X vs non-X versions of compiler?)

Anyone else run into this issue?

rich

  • I have not see this issue before.  The sprintf function doesn't have much state associated with it.  I doubt the number of times you call it is causing the problem.  It seems more likely that certain floating point values are the cause of the problem.  When the failure occurs, are you able to somehow record the value that is being formatted?  If I'm right, then you should be able to reproduce a similar failure with that same value in a small test case which calls sprintf.

    Thanks and regards,

    -George

  • George

    I was wondering about the specific value I was formatting as well.

    For a test, I had set a local floating point variable equal to a constant...

    fVal = 1.0;

    I then format to the buffer...

    sprintf(pcBuf,"%5.1f",fVal);

    "pcBuf" points to a statically allocated buffer 16 characters long declared at file scope (passed as arg to function call)

    Most of the time when I look in the buffer, I see what you would expect...

    cDisplayBuf[] = "0x20,0x20,0x31,0x2E,0x30,0x00"

    After a few times thru the loop I will see the following...

    cDisplayBuf[] = "0x20,0x20,0x66,0x2E,0x30,0x00"

    this non-numeric character screws up the subsequent processing...

     

    rich

     

  • To do anything useful, I need a test case which reproduces this behavior.  In the meantime ...  Is is possible some other stray pointer in your loop is overwriting this one byte in the buffer?

    Thanks and regards,

    -George

  • I will put something together for you.  One thing I did was to remove the sprintf calls and manually stuff the buffer with 0x20,0x20,0x31,0x2e,0x30,0x00.  In this case it never fails.

     

    will advise...

    thanks

    rich

  • George

    Attached is my "bare bones" project for the MSP430F5418A.  I have stripped everything out with the exception of calls to sprintf in a while(1) loop and an enabled watchdog timer. (along with necessary clock init..etc)

    The application uses two buffers.  One local buffer gets formatted characters from sprintf each time thru the loop.  The same float is formatted each time "1.0".  Each time thru the loop after the local buffer is loaded, the other buffer (declared at filescope) is compared (using strcmp) to the local buffer.  If they are different, the local buffer is copied to the filescope buffer.

    My intent is that once the local buffer is copied to the filescope buffer, they will always be the same and the comparison will always return 0.

    What happens however is that the application runs for some random amount of time at which point one of two things happen:

    1)  The comparison does not return 0 - upon inspecting the local buffer filled by sprintf I see that sprintf did not format the buffer the same way - eg. "0x31,0x2E,0x30,0x00" vs "0x20,0x20,0x31,0x2e,0x30,0x00"

    2)  The application resets - I am attempting to determine the cause of the reset by writing my own reset routine but I get a linker warning saying
    "creating output section ".int63" without a SECTIONS specification".  The debugger will not load the code because the linker does not know where to put the reset vector???2475.SprintfTest.zip

  • Rich,

    I'm trying to duplicate this issue using your test case but haven't been able to so far. I am running the test case on a MSP430F5419 and I tested with both CCS 4.2 and 4.1.3.

    The sprintf is behaving as expected for me. The first time through the loop, the local buffer contents are copied to the file scope buffer, and then after that the copy does not happen because the comparison returns 0. I tested this by setting a breakpoint on the strcpy line and it only hits the breakpoint one time. If you set a breakpoint on the strcpy line do you see it hitting it multiple times?

    I also don't observe the resets happening. However if something is resetting the system that could explain the file scope buffer getting reinitialized and needing to be copied again. How much time does your application run before you observe these behaviors? Are you able to duplicate this behavior with the test case you attached above?

  • Aarti

    I am using CCS 4.1.3 as well. 

    I tested the code the same way.  I set the breakpoint on the strcpy line and run the code.  The first time in it hit the breakpoint as expected.  After clicking continue, the code will run for seemingly random amount of time but usually within 10 seconds to 1 minute it will hit the breakpoint again.  The only difference I notice is that sprintf removes the spaces padding the beginning of the buffer...eg. normally I get a buffer "0x20,0x20,0x31,0x2E,0x30,0x00".  When it fails, I get "0x31,0x2E,0x30,0x00".

    I also set a breakpoint at the beginning of the code to detect if I ever reset.  When the buffer corruption occurs it is not preceeded by hitting the breakpoint @ the init section of my code.  It just seems that sprintf occasionally fails to perform the same formatting on a floating point number that never changes.

    For the reset thing, I tried the following...

    1)  Extended the watchdog timeout period from 21ms to 300ms thinking that maybe sprintf might be timing it out...no change

    2)  disabled the watchdog completely...no change

    3)  Tried to determine the cause of the reset but had difficulty getting the linker to behave

    The code I sent will fail on my system.

    At this point, this is not a critical issue for me.  I have pulled out the floating point support for sprintf and have written my own formatting function.  works much better now :)

    FYI

    Rich

  • Hi,

    I know a lot of time has passed on this thread, but I thought I should report that I have just seen the same problem on a C5402 CPU using CCS3.1. I am supporting a legacy project where there was a conversion issue in a customized float to ASCII-string converter, and I wondered why sprintf was not used. When employing sprintf I found that periodicaly float values converted using sprintf would occasionally have non-numeric ASCII characters in the output. I have not dug into this, but based on what I have seen here I'm guessing it may be better to repair the custom converter.

    I just thought it should be reported for whomever looks at this part of the compilers.

     

    Dan.

  • We've never been able to reproduce the symptom.  Unless we can do that, there's little hope of finding a fix.

  • If I find some time I will try to make a subset of the project to see if it still fails and pass it along, but regarding details:

     I was also using a size-16 temporary array. It was memset() to 0 before each sprintf(), and the temporary array was strcat() to a larger array that was being assembled piece, by piece, if that helps.

    Dan.

  • As the original poster of this thread I apologize for not updating the status of my issue for awhile.  Ultimately I had to run my project on TI's development board to determine that the problem was in hardware and not software.  The board I had been developing my application on had been designed by my predecessor.  When I was at the stage of tearing the last of my hair out I looked at the hardware schematic to find out that there was no bypassing of the Vcore pin on the MCU!  When I tacked the capacitor to the board the code worked fine.

    Again, sorry for the delay in my update!