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.

wierd (poss RAM) error getting started with debugging...

Other Parts Discussed in Thread: MSP430G2131

hi all,

just started getting my head around the MSP430 and failed at the first hurdle...

I've got a very basic program which does little at the moment, targetted to a MSP430G2131 on the Launchpad. In short, the program isn't running. When stepping through on the debugger, it gets as far as initialising a global variable then blows up with:

Can't find a source file at "/db/ztree/library/trees/gep/gep-d17x/src/ti/targets/msp430/rts430/boot_3.3.c"

The linker has been configured to give a 64byte stack and 64byte heap space (although various other configurations have been attempted), the main code is:

/*
 * ======== Standard MSP430 includes ========
 */
#include <msp430.h>

/*
 * ======== Grace related includes ========
 */
#include <ti/mcu/msp430/csl/CSL.h>

/* GLOBALS */
unsigned char gPulseIdx;
unsigned long gPulse;
typedef enum
{
   eIDLING,
   eCAPTURED
} STATE;
STATE gState;
/*
 *  ======== main ========
 */
int main(int argc, char *argv[])
{
    int i;
    unsigned short u;
    CSL_init();                     // Activate Grace-generated configuration
    
    __bis_SR_register(LPM0_bits + GIE); //enable interrupt

    //local inits
    gPulseIdx = 0;   //>>DEBUGGER BLOWS UP HERE<<
    
    //process loop
    for(;;)
    {
        switch (gState)
        {
        case eIDLING:
            break;
        case eCAPTURED:
             u = gPulse;
        }
    }
    return (0);
}

I'm almost certain its a memory allocation problem. The programs been repeatedly disappearing at this point, but only after clearing down the memory allocation have I now actually got an error!

Q> any ideas why it might be blowing up

Q> any ideas how to get the RAM allocation size from the linker?

Q> does the grace configuration add overhead to RAM size - i.e. should GRACE be avoided for such small memory devices?

Any comments/suggestions appreciated!

(CCS v5.1.1.00031)

Mat

  • Mathew Maher said:
    When stepping through on the debugger, it gets as far as initialising a global variable then blows up with:

    The line where the error occurs is also after interrupts have been enabled. Can you post the GRACE .cfg file to show if an peripherals have had interrupts enabled.

    Mathew Maher said:
    Q> any ideas how to get the RAM allocation size from the linker?

    The linker generates a .map file which gives the memory allocation. The linker can't tell if the stack size is sufficient for the application. The Code Generation Tools XML Processing Scripts can report the maximum stack usage for a program.

  • Good spot with the ISR enable. I'll have a play and see if removing that line resolves the problem. Copied grace config below. Bit strange: the grace config specifies stack/heap sizes, but I can't find anything under grace itself to specify these, instead have set them in linker properties. Which takes precidence: linker properties or grace config?

    Mat

    /**
     *  @fileOverview Grace
     */

    /* need to use the CSL module to generate the CSL code */
    var CSL = xdc.useModule('ti.mcu.msp430.csl.CSL');
    var USI = xdc.useModule('ti.mcu.msp430.csl.communication.USI');
    var Timer_A2 = xdc.useModule('ti.mcu.msp430.csl.timer.Timer_A2');
    var Flash = xdc.useModule('ti.mcu.msp430.csl.memory.Flash');
    CSL.configApiVersion = "1.00.00";

    /* these modules should be part of every project */
    var WDTplus = xdc.useModule('ti.mcu.msp430.csl.watchdog.WDTplus');
    var GPIO = xdc.useModule('ti.mcu.msp430.csl.gpio.GPIO');
    var BCSplus = xdc.useModule('ti.mcu.msp430.csl.clock.BCSplus');
    var System = xdc.useModule('ti.mcu.msp430.csl.system.System');

    /* set stack and heap sizes as appropriate for MSP430 */
    Program.sysStack = 0;
    Program.stack = 64;
    Program.heap = 0;
    Program.argSize = 0;

    /* Enable global interrupt */
    System.srRegs.SR.GIE = System.srDefs.GIE;
    BCSplus.regs.LFXT1CLKHz = 32768.0;
    BCSplus.regs.BCSCTL3.LFXT1S = BCSplus.defs.LFXT1S_0;
    BCSplus.regs.BCSCTL1.DIVA = BCSplus.defs.DIVA_0;
    USI.showSelectionPage = false;
    USI.regs.USICTL0.USIMST = USI.defs.USIMST;
    USI.usiEnabled = true;
    USI.regs.USICTL0.USIPE5 = USI.defs.USIPE5;
    USI.regs.USICTL0.USIPE7 = USI.defs.USIPE7;
    USI.regs.USICTL0.USIPE6 = USI.defs.USIPE6;
    USI.regs.USICTL0.USIOE = USI.defs.USIOE;
    Timer_A2.regs.TACTL.TASSEL = Timer_A2.defs.TASSEL_1;
    Timer_A2.txClkPin[0] = 0;
    Timer_A2.inputClockToTimer = 32.768;
    Timer_A2.regs.TACTL.ID = Timer_A2.defs.ID_0;
    Timer_A2.regs.TACTL.MC = Timer_A2.defs.MC_2;
    Timer_A2.ccrXTimerSelection_PowerUser[1] = xdc.module("ti.mcu.msp430.csl.timer.ITimer").CCRxTimerSelection_PowerUser_Selection_2;
    Timer_A2.ccrXTimerSelection_BasicView[1] = xdc.module("ti.mcu.msp430.csl.timer.ITimer").CCRxTimerSelection_BasicView_Selection_2;
    Timer_A2.regs.TACCR1 = 442;
    Timer_A2.regs.TACCTL1.CAP = Timer_A2.defs.CAP;
    Timer_A2.regs.TACCTL1.SCS = Timer_A2.defs.SCS;
    Timer_A2.ccInputPin[1] = 1;
    GPIO.regs.P1SEL.Bit2 = GPIO.defs.BIT2;
    Timer_A2.regs.TACCTL1.CM = Timer_A2.defs.CM_1;
    Timer_A2.regs.TACCR0 = 0;
    Timer_A2.regs.TACCTL1.CCIE = Timer_A2.defs.CCIE;
    Timer_A2.ccr1InterruptHandler = "TimerA2_ISR";
    BCSplus.userInputDCO = 1000.0;
    BCSplus.regs.BCSCTL1.RSEL3 = BCSplus.defs.RSEL3;
    BCSplus.regs.DCOCTL.MOD4 = BCSplus.defs.MOD4;
    BCSplus.regs.DCOCTL.MOD2 = BCSplus.defs.MOD2;
    WDTplus.regs.WDTCTL.WDTHOLD = WDTplus.defs.WDTHOLD_OFF;
    WDTplus.regs.WDTCTL.WDTSSEL = WDTplus.defs.WDTSSEL;
    WDTplus.wdtHandler = "Watchdog_ISR";
    System.ie1Regs.IE1.WDTIE = System.ie1Defs.WDTIE;

  • Mathew Maher said:
    the grace config specifies stack/heap sizes

    Well, there is no 'stack size' anyway. The stack grows when it wants to grow, eventually overwrite all variables until it spans whole ram. Ther eis nothign that can limit it except proper program design. Any 'stack size' setting is just a linker hint for the maximum amount of global variable allowed and for the debugger as a warning threshold.
    Same for the heap setting, it too is only a hint for the linker. However, heap management (with malloc) will refuse to use more heap than available (taking the current stack size at the moment of the request into account). However, none of these settings wil cause any difference in the produced binary.

    One more thing: it makes no sense to define main with parameters or return from main.

    Since there is no OS that can pass parameters or where you can return to, the definition of main should be
    void main (void)
    (Well, some compilers insist on a return type of int for main, but it has no meaning.)

    Ending main with return(0) is nonsense. You should enter LPM4 instead if there's really nothing to be done ever again (until power cycle)
    (Some compilers generate code that enters LPM4 when you really return from main, but this is compiler specific and not portable)

  • Jens-Michael Gross said:
    Ending main with return(0) is nonsense.

    To be fair, when you create a blank GRACE project the main which gets created is:

     

    nt main(int argc, char *argv[])
    {
        CSL_init();                     // Activate Grace-generated configuration
        
        // >>>>> Fill-in user code here <<<<<
        
        return (0);
    }


    Jens-Michael Gross said:
    (Some compilers generate code that enters LPM4 when you really return from main, but this is compiler specific and not portable)
    The RTS which comes with MSP430 Code Generation Tools 4.1.0 ends up in the following if main returns, or exit() is called:

    void abort(void)
    {
       /*-------------------------------------------------------------------*/
       /* SET C$$EXIT LABEL SO THE DEBUGGER KNOWS WHEN THE C++ PROGRAM HAS  */
       /* COMPLETED.  THIS CAN BE REMOVED IF THE DEBUGGER IS NOT USED.      */
       /*-------------------------------------------------------------------*/
       __asm("        .global C$$EXIT");
       __asm("C$$EXIT: nop");
    
       for (;;);   /* SPINS FOREVER */
    }
    
    <


    > Not exactly low power!

  • When I tried to compile a program with the posted GRACE configuration and the C code the following linker errors occured:

     

    undefined first referenced  
    symbol in file
    --------- ----------------
     TimerA2_ISR C:\DOCUME~1\workspace_v5_1\GRACE_timer\src\csl/csl.lib<CSL_init.obj>
     Watchdog_ISR C:\DOCUME~1\workspace_v5_1\GRACE_timer\src\csl/csl.lib<CSL_init.obj>

    error #10234-D: unresolved symbols remain
    This means the posted GRACE code enables ISRs for TimerA2 and the Watchdog, but the handlers are not in the posted C code.

  • Problem solved!

    It was indeed the call to the interrupt enable. GRACE has already enabled these interrupts, but for some reason re-enabling them causes problems. From my point of view, it's simply a case of removing that line and everything works.

    I didn't post the whole code because it's pretty irrelevant and would just swamp the posting, but here they are:

    void TimerA2_ISR()
    {
       _NOP();
    }
    void Watchdog_ISR()
    {
       _NOP();
    }:

    The main/return thing - it's good to hear what I was suspecting, but I didn't change it because, as the previous post confirms, the CCS wizard produces this code (I assumed it had good reason for doing this).

    Thanks for your support!

    Mat

  • Mathew Maher said:
    GRACE has already enabled these interrupts, but for some reason re-enabling them causes problems.

    Hard to believe. If they are enabled, they are enabled. You cannot "double-enable" them.
    It's possible that they actually weren't enabled (and at this point not ready to be enabled without additional code) and enabling them caused the problem.

    For example: I don't know what TimerA2_ISR is supposed to do. But if it is the TIMER2_A1_Vector, and the code does not reset the IFG bit inside the ISR, this will cause an eternal ISR loop and main is effectively stopped.

    Mathew Maher said:
    the CCS wizard produces this code (I assumed it had good reason for doing this).

    Well, at least one could assume that the wizard-generated code will work with the compiler that belongs to the wizard. Normally.
    However, it isn't portable. There is no portable specification of what happens if main returns on an MSP on other compilers. Nor is there a specification about where the passed parameters might come from or what happens if you actually try to access them.

**Attention** This is a public forum