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.

Compiler/CC430F5137: How do I analyze the stack after a "run into the weeds"

Part Number: CC430F5137


Tool/software: TI C/C++ Compiler

Dear experts,

My embedded firmware currently has a case of the program "running into the weeds". My suspicion is that a function pointer or the stack itself somehow gets corrupted, but its at best a guess.

My goal is therefore to first establish what the last actual piece of legitimate code the processor was busy with, before things go wrong.

Firstly, I can confirm that I am definitely not getting a stack overflow. I checked that by writing the stack with known values at the beginning of main() and then checking the stack after the crash.

After a crash, the PC always points to the value 0x2B12, which is definitely not a valid program memory location (should be above 0x8000 for this MSP430). This location is in fact a location in the stack itself.

When the program crashes, I do not see the call trace in CCS (v7.4.0) with the debugger. At this point the SP's value is 0x2B26, which is still within the stack boundaries.

I have tried the special breakpoints that CCS provides in the debug perspective, e.g. "Break in program range" (below 0x8000), "Break before Program Address" (0x2B12) "Watchpoint on write" (the specific stack address). However, none of these approaches worked. I am not sure if the HW actually supports this or I am just using it wrong.

Can you please advise how I can analyze the stack to determine that last function that was being executed? Maybe so specific tips and tricks?

Thanks in advance!

  • Hi,

    I am not very familiar with the CC430 family of devices, thus I am not entirely sure of what types of advanced debugging features it supports, but the page below has some resources that may help you debug this post mortem scenario. 

    http://processors.wiki.ti.com/index.php/MSP430_Advanced_Debugging_using_CCSv5 

    I will defer this thread to the device experts, as they will be much more familiar with these devices. 

    Hope this helps,

    Rafael

  • Hello,

    I checked the CC430F5137 Device Erratasheet (Rev. AA),  there is a bug CPU18 related to the PC/SR register corruption.

    Since you have confirmed there is no stack overflow. Maybe the bug is the cause. Please check this bug.

  • Hi Winter,

    thanks a lot for your reply!

    The described behaviour of the CPU18 seems very much related to the additional information I managed to get in the meantime.

    On my side, I further did debugging and I narrowed the problem down to our I2C driver, which exactly used the LPM modes to pole certain events of the I2C protocol. For example, an I2C start condition is generated and then the processor is put into LPM0 sleep mode, until the ISR received the event interrupt and then wakes the processor up again. I was exactly this code that somehow caused this corruption and when I replaced it and explicit polling loop (e.g. with a while()-loop), I no longer got the problem.

    However, this does not yet entirely solve the issue, because it appears as though the previous developer (who no longer works here) was indeed aware of this HW bug, based on the code and it seems the problem still occurred. The errata compiler flag was also already set in CCS.

    Some example code is given below

    In the foreground I2C driver for generating a start condition:

    _generateStartCondition();
     
    // Enter LPM0, enable interrupts
    _nop();
    __bis_SR_register(LPM0_bits + GIE);
    _nop();                                 
    




    In the ISR after all bytes have been transmitted:

    UCB0CTL1 |= UCTXSTP;                  // I2C stop condition
    UCB0IFG &= ~UCTXIFG;                  // Clear USCI_B0 TX int flag
    __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0

    I therefore have two questions:

    1) Is this the correct usage of CPU18 workaround for the I2C driver? If not, can you please give me a good example of the usage?

    2) What is the preferred way of implementing the I2C bus synchronization? As mentioned, I managed to get it working without switch LPM modes for polling and it seems to work quite okay. I am just not sure if this will for example have a significant impact on the power consumption. We only have a single threaded system and we are not using the I2C bus for extensive data transfers, probably under ~100 bytes per cycle.

    Thanks in advance! 

  • Hello,

    Sorry for late reply.

    The CPU18 bug is already fixed by compiler. User is required to add the compiler or assembler flag option. You don't need to implement the workaround by yourself. Could you please check below table for more details?