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.

CCS/TMS320F28069: Using - STDIO - Sometimes sprintf is incorrect...

Part Number: TMS320F28069

Tool/software: Code Composer Studio

Hello,

My app is doing the following as a debug print about once every second:

sprintf((Uint8 *)&debug_string[0], "HRC1: H%lu, %lu, L%lu, %lu\r\n", xMessage.int_HRC1pulsewidthhigh0[i], xMessage.frac_HRC1pulsewidthhigh0[i], xMessage.int_HRC1pulsewidthlow0[i], xMessage.frac_HRC1pulsewidthlow0[i] );
USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (Uint8 *)&debug_string[0], strlen(debug_string));

I'm using the terminal in CCS to see the debug print - also - the app will run for a while and will eventually crash; usually hitting an ESTOP statement in an unhandled vector.  (Only happens when I enable this debug priint output.)

The following is an example output:  (<== marking the issue)

HRC1: H47, 61566, L48, 3970
HRC1: H61566, 47, L3970, 47  <==
HRC1: H47, 61566, L48, 3970
HRC1: H47, 63609, L48, 1927
HRC1: H47, 61682, L48, 3854
HRC1: H47, 61682, L48, 1927
HRC1: H47, 61682, L48, 3854
HRC1: H63609, 47, L3854, 47 <==
HRC1: H47, 63609, L48, 3854
HRC1: H47, 63609, L48, 1927
HRC1: H47, 61682, L48, 3854
HRC1: H47, 61682, L48, 3854

Any advice on this appreciated.

Thanks In Advance,
John

  • I see you are officially a Guru so you probably know this already, but a very common cause of problems with the printf family of functions is stack overflow. They take around 1k of stack just for themselves. Part of our release process is to use the debugger to fill the stack with 0x5555 before the code starts, let the code run for a while, and make sure the stack area is not overflowing.

    Lloyd
  • Lloyd,

    Yes, I've increased stack - the app can run OK if I'm not in the debugger; and will crash when I'm in the debugger rather consistently; which is a curiosity right now; evidently caused by the debug prints.

    I will see if I can use the JTAG Debugger's second serial port to print debug messages; I seem to remember something like that being possible with the XDS probes - I just need to get this debug info out. I've done that before but with a different family of DSP's.

    But, yes, setting a watermark for the stack is always a good idea.

    Thanks,
    John
  • Hello John,

    as I remember, servicing back channel functions holds interrupts.

    Post this issue on a piccolo related forum.
    <<< usually hitting an ESTOP statement in an unhandled vector
    Please post:
    a peace of code where it stops (for a while(1) I am guessing) ,
    an MCU stack trace.

    If it hits any other "ESTOPs", post them also.
  • Well...it has to be asked, what is your allocation for debug_string? Are the structure members the right type for "%lu"?

    I can't see many ways that the "int_" and "frac_" members could be swapped in printf(). Possibly a glitch in the stack pointer that would shift the arguments. But that would show as a garbage value in first or fourth argument.

    Perhaps the "int_" and "frac_" members get swapped earlier.

    Maybe it is something to do with the USBBufferWrite() call. Would it modify debug_string?
  • In addition to the stack, make sure you don't run out of heap.  For more tips like this one, please see the article Tips for using printf.  

    Thanks and regards,

    -George

  • George,

    Yes - and as far as USBBufferWrite() - I don't know if it's thread-safe or reentrant as I am using it in an RTOS task - not 100% sure if that can be an issue at the moment - but I would hazard a guess it probably isn't (thread-safe or reentrant).

    I do have an IRQ routine that just bounces out one char at a time in interrupt time that uses USBBufferWrite() and that seems to work OK.

    I have reviewed all that is there regarding using printf.

    Thanks,
    John W.
  • Norman,

    String allocation is fine; but it's a fair/good question. I've obviously checked that.

    The real issue could be USBBufferWrite() is neither thread-safe nor reentrant since that is being called in RTOS task time - a 'little' detail I didn't add to the OP; but at the same time I'm making sure the RTOS task is about as cooperative as it can be, making sure this call has plenty of time to complete.

    And I don't have source for some of the USB lib stuff for the '69.

    Thanks,
    John
  • Hi John,

    Which RTOS are you using?

    Todd
  • Since it has been a while, I presume you have resolved your problem.  I'd appreciate hearing how you resolved it.

    Thanks and regards,

    -George

  • Hello Todd,

    FreeRTOS (aka Amazon RTOS) - v10.x.

    Regards,
    John W.
  • George,

    It would appear that USBBufferWrite() isn't thread-safe or reentrant - or maybe I need to do a better job with buffering, or both perhaps.
    I do think I resolved this - but I don't want to declare any of these yet without further testing - but I did have more than one thread using USBBufferWrite() - albeit I had slowed the timing down to the point that there shouldn't (key word shouldn't) have been any issues with reentrantcy or threads clobbering buffers - but again I would like to do more testing.

    Actually staring at the OP revealed the issue - at least I think.  It's periodic.

    Thanks,
    John W.

  • George,

    I did add some more stack and available heap to the threads that are using/calling USBBufferWrite() ; but I also made sure that some of the buffer pointers I have been using didn't go out of bounds; making sure I wasn't breaking any reentrancy rules and following thread safety so to speak and it seems to be working OK now.

    So, root cause? Maybe one thread was stomping on the output of another? Maybe.
    Maybe one of the pointers was either getting corrupted or being reset while USBBufferWrite() was executing? Maybe.

    Thanks,
    John