MSP430F5529: Yet another debug works fine / release fail to run problem

Part Number: MSP430F5529

Tool/software:

This seems to be a frequent issue and in reading the search results a clear resolution is not shown.

In the code below the getVersionInfo(); routine being called in main() is hanging where I commented in release mode. Debug runs fine.

Any ideas? Timer interrupt issue? 

static void getVersionInfo()
{
    // Wait around for the bluebox to be awake, and try to get the verison info.
    // But timeout eventually to allow for the case of an older bluebox that doesn't support reporting version

    u8 attempts = 0;

    while(attempts++ < 10)
    {
        if(strncmp(G.blueboxVersionInfo->ProcVariant, DEFAULT_VARIANT, VARIANT_INFO_SZ) != 0)
            break;

        bluebox_packetToRequestVersionInfo(&G.blueboxTxFifo);
        bluebox_sendPacket(&G.blueboxTxFifo);

        // Wait 0.1s; using LED timer for convenience

// hangs here in RELEASE mode AD
        while(!G.ledTmr.timedOut) {}
        RestartGenTimer(&G.ledTmr);

        bluebox_periodic();
    }
}

void getClkID()
{
    // read 4 position dip switch
    if (DIP_SW & 8)  // screen alignment, hangs here as long as SW6-4 is on
    {
        drawAlign();
        while(1);
    }
    else
        clk_id= (DIP_SW & 3);

}

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;  // Stop wdt

    initHardware();
    RUNledOff;
    initGlobals();
    bluebox_init();

    _enable_interrupts();
// hangs in RELEASE mode AD
//    getVersionInfo();
    getClkID();


    menus_init();  // I think it requires interrupts to be enabled, but I'm not sure.  For now, don't put it before _enable_interrupts().
    drawClkID();

    RUNledOn;
    for(;;)
    {
        buttons();
        menu();
        bluebox_periodic();  // parse and display received data packet AD
//        LPM0;
    }
}

  • Is G.ledTmr.timedOut declared "volatile"?

  • Well we have this:

    Globals G;
    
    void initGlobals()
    {
        memset(&G, 0, sizeof(Globals));
    
        G.adcTmr.period = 100;
        G.adcTmr.on = 1;
    
        G.ledTmr.period = 125;
        G.ledTmr.on = 1;
    
        G.passLockTmr.period = 4000;
        ResetGenTimer(&G.passLockTmr);
    
        unsigned i = NUMBUTTONS;
    
        while(i--)
        {
            G.buttons[i].numbnessTmr.period = 25;
            G.buttons[i].numbnessTmr.on     = 1;
        }
    
        G.blueboxStatus = bluebox_status();
        G.blueboxVersionInfo = bluebox_versionInfo();
    
        G.blueboxTxFifo.data = G.blueboxTxFifoData;
        G.blueboxTxFifo.sz = BLUEBOX_TXFIFO_SZ;
    }
    

    this:

    #ifndef GLOBALS_H_
    #define GLOBALS_H_
    
    #include "genTimer.h"
    #include "fifo.h"
    #include "buttons.h"
    #include "bluebox.h"
    
    // 7 char and 6 char, respectively
    #define FIRMWARE_VARIANT "STD"
    #define FIRMWARE_VERSION "190327"
    #define NUMBUTTONS (5)
    
    void initGlobals();
    
    enum { // used to index buttons in buttons array
        BTNIDX_S1Up    ,
        BTNIDX_S1Right ,
        BTNIDX_S1Left  ,
        BTNIDX_S1Center,
        BTNIDX_S1Down  ,
    };
    
    #define BLUEBOX_TXFIFO_SZ (16)
    
    typedef struct Globals
    {
        GenTimer adcTmr;
        GenTimer ledTmr;
        GenTimer passLockTmr;
    
        Button buttons[NUMBUTTONS];
        BlueboxStatus * blueboxStatus;
        BlueboxVersionInfo * blueboxVersionInfo;
        FIFO8 blueboxTxFifo;
        unsigned char blueboxTxFifoData[BLUEBOX_TXFIFO_SZ];
    
    } Globals;
    
    extern Globals G;
    
    #endif
    

    and this:

    /*
     * genTimer.h
     *
     *  Created on: Dec 4, 2012
     *      Author: alex
     */
    
    #ifndef GENTIMER_H_
    #define GENTIMER_H_
    
    typedef struct GenTimer
    {
    	unsigned int cnt;		// counting variable
    	unsigned int period;	// in "ticks"
    	unsigned on:1;		    // whether it should advance when ticked
    	unsigned timedOut:1;	// flags a cnt reaches period condition
    } GenTimer;
    
    void ResetGenTimer(GenTimer* tmr);
    void RestartGenTimer(GenTimer* tmr);
    void Tick(GenTimer* tmr);
    
    #endif /* GENTIMER_H_ */
    

  • >  unsigned timedOut:1; // flags a cnt reaches period condition

    I suggest:

    >  volatile unsigned timedOut:1; // flags a cnt reaches period condition

    More generally, since (evidently) timedOut can be updated in an ISR, I suggest not using a bit-field here, since changing "on" could interfere. Maybe it will use BIS and maybe it won't, but a byte write is atomic.

    [Edit: Small wording fix.]

**Attention** This is a public forum