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.

Debugger jumps to wrong interrupt vector

Other Parts Discussed in Thread: CCSTUDIO, MSP430F2618, CODECOMPOSER, MSP430F2619, MSP430FG4618, MSP430F4793, CC430F5137, MSP430F427, MSP430F449

I have a strange behavior with debugging the enable interrupt instruction. In the following example I use the Timer B for description, but this looks like a general problem with all interrupts. When the timer requests an interrupt while the GIE bit is cleared, the interrupt is not accepted. That's expected. But when I set the GIE bit again, the wrong interrupt vector is executed. Following symptoms can be observed:

  • The PC register points to 0x0000 (special function register area)
  • The SP is decremented by two words. The stack got the values: return address and status register.
  • The SR register is cleared (GIE is zero)

So this looks like a normal interrupt accept cycle except that the vector at address 0xFFFA is ignored and read as zero. This happens while single stepping with CCS 5.1.1.00028. Is this a bug in the CCStudio debugger or in the program? An update to CCS 5.2.0.00071 does not change this behavior.

This is obviously a bug in the CCS debugger. Unfortunately this post has been moved to the microcontroller group. Any chance to get a comment from Texas Instruments?


#include <msp430F2618.h>


static unsigned int s_uTickCount;

// Timer B0 interrupt service routine for CCR0
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B(void)
{
 ++s_uTickCount;
}

#pragma vector=TIMERB1_VECTOR
__interrupt void Timer_BIV(void)
{
}

void main(void)
{
 WDTCTL = WDTPW + WDTHOLD;
 __bic_SR_register(SCG0);
 BCSCTL1 = XT2OFF | DIVA_2 | CALBC1_1MHZ;
 DCOCTL  = CALDCO_1MHZ;
 BCSCTL2 = SELM_0 | DIVM_0 | DIVS_0;
 BCSCTL3 = XT2S_0 | LFXT1S_0 | XCAP_2;

 TBCCR0 = 0xFFFF;
 TBCCTL0 = CCIE;    // CCR0 interrupt enabled
 TBCTL = TBSSEL_2 + MC_2; // SMCLK, continuous mode

 // await first counter register wrap
 while (TBR < 0xFFF0) ;
 while (TBR > 0x1000) ;
 // the interrupt request is pending now

 _bis_SR_register(GIE);

 __delay_cycles(10); // bad interrupt occurs here
}

  • Helge Kruse said:
    The PC register points to 0x0000 (special function register area)

    This usually happens when an interrupt is triggered and there is no ISR for it a tall. Then the interrupt vector table contains 0xFFFF as the address of the ISR and hte CPU jumps to 0xFFFE and rolls over to 0x0000 on next instruction.

    However, in your code I only see one interrupt being enabled. And this is TBCCTL0.CCIE. And you have TIMERB0_VECTOR. So it shouldn't happen.

    It would be interesting to see the applicaitons memory map (can be requested in the project options) and perhaps the disassembly of the application code, including the vector table.

    It's possible that the header file of the 2618 or the linker script has a bug in the interrupt vector assignment for the B0 vector. Maybe you're the first one who used teh B0 vector on this MSP with this version of the compiler :)

  • Hi,

    have you tried to add:

    while(1);

    in the last line of main() function?

  • Hello Jens-Michael,

    thanks for looking at this post. The problem I describe is only related to the debugger. The code works fine as long as I don't use the debugger single step operation. Therefore we could exclude a wrond interrupt table setup. To be honest, I initialized the whole table with the vector to my SpuriousInterruptServiceRoutine. Then you don't have any 0xFFFF in the table and your assumptions does not work.

    Since the Timer B0 ISR is called when the debugger is not single stepping, I think it's not worth to check the other suggestion. Do you agree?

    I posted a stripped down code that is complete and shows the misbehavior. Could you compile and single step it?

    BTW: I suspect this as a bug in the debugger. That's why I posted in the CodeComposer group, but the article has been moved to the MSP430 group.

    Thanks,
    Helge

  • Hi Ihend,

    Yes there was much more code behind the bis_SR_register(GIE); instruction. The __delay_cycles(10); is only a placeholder for any code, that will never be reached when you use single stepping.

    Helge

  • Helge Kruse said:
    Since the Timer B0 ISR is called when the debugger is not single stepping, I think it's not worth to check the other suggestion. Do you agree?

    Well, if the code runs if the debugger is not signle-stepping, then it seems to be a debugger problem indeed.

    However, there have been silicon errors in some MSPs that only apply when usign the debugger or even only whiel single-stepping (corrupted program counters or stack poitners for certain combinations of instructions when singöe-stepping through them etc.) But the errata sheet of your chip doN#t list any. (Well, this can of course just mean that nobody encountered them on this chip yet)

    Helge Kruse said:
     Could you compile and single step it?

    No. since I don't use CCS or IAR, and due to the realtime nature of mso tof my applications, using a debugger is impossible anyway. So I have none installed at all.

    Helge Kruse said:
    I suspect this as a bug in the debugger. That's why I posted in the CodeComposer group, but the article has been moved to the MSP430 group.

    Well, if we can really exclude a silicon bug, then this thread should be ponged back to the CCS forum.
    The problem is that CCS is not MSP alone. And if a bug seems to be MSP specific, then they usually push it into the MSP forum.

  • Well, if we can really exclude a silicon bug, then this thread should be ponged back to the CCS forum.

     

    Well I don't have the means to really exclude. But since it's really only happen when debuging, I think it should be in the CCS forum.

    Unfortunately I haven't the means to move a thread.

  • Hi Helge,

    i can confirm that i can reproduce the problem you mentioned above, and it is true that the problem only occurs when you do single stepping after setting the GIE. If you put a breakpoint in the ISR, the problem will not occur. Anyway i have seen this kind of problem sometimes, and basically putting breakpoint in the correct place will solve the problem, i hope you can at least live with it now :)

    I am going to forward this to the MSP430 tools team. FYI, It is correct that this kind of problem should be discussed in the MSP430 forum, since the DLL for the debugger comes from the MSP430 team.

  • Hi Helge,

    I ran into the same problem and reached the same conclusion: When single-stepping into an interrupt the PC is set to 0x0000 instead of the correct interrupt vector. This makes single-stepping basically unusable in an application with frequent interrupts (e.g. from a timer or the SD16_A).

    Since I'm using the open-source release of the MSP430v3 DLL I was able to come up with an adequate workaround: The attached patch clears the GIE flag before each single-step, and restores it afterwards. This allows to step through the main program without the CPU dying because of a misdirected interrupt entry. There's an unwanted side-effect, though: It cancels out the effect of instructions clearing the GIE flag (e.g. DINT) when single-stepping. Still, better than nothing. :-)

    HTH,
    Ingo

  • I don't use the OpenSource release. What is the effort to get this variant and setup the build environment for this patch? Do you think it's possible to get the current state of the GIE to restore the previous state?

  • Helge Kruse said:
    I don't use the OpenSource release. What is the effort to get this variant and setup the build environment for this patch?

    I'm using Linux, and the effort was little more than calling "make". According to the README you need Visual Studio 2003 or later to build it in Windows. You can download the source release here: http://processors.wiki.ti.com/index.php/MSP_Debug_Stack

    Helge Kruse said:
    Do you think it's possible to get the current state of the GIE to restore the previous state?

    That's exactly what my patch is doing. However, that's not correct in case the instruction stepped over was actually meant to clear the GIE flag. So, when you step over a DINT instruction my workaround will re-enable the GIE flag just after executing the instruction. I don't believe that's much of a problem, but if it turns out to be one it could be fixed by reading the opcode to tell if the instruction was meant to affect the GIE flag.
    Regards,
    Ingo
  • Using a MSP430F2619, CCS 5.2.0.00069, MSP430 Compiler v4.1.1 and a MSP-430FETUIF with MSP430.dll v3.2.4.5 I repeated the problem of the bad interrupt when single stepping.

    When I changed to using an MSP430-JTAG-TINY with Olimex.dll v1.0.4.2 then when single stepping after the GIE had been set the debugger single stepped into the Timer_B ISR rather than getting the bad interrupt. This appears to show that the problem is in the MSP-430FETUIF and/or MSP430.dll rather than in CCS or the MSP430.

    I was using the MSP430.dll v.3.2.4.5 compiled from source, so will see if can get it to behave in the same way as with the MSP430-JTAG-TINY.

  • The MSP320.DLL V3 still have the one or another bug. It is constantly updated and maybe with the next update of the compiler, the problem will vanish.

    The Olimex uses its own MSP430.DLL which likely is on the level (and mature like) the old V2 dll that was used with CCS4.x.

  • Jens-Michael Gross said:
    The MSP320.DLL V3 still have the one or another bug.

    Debugging the DebugManagerV3::singleStep function in MSP430.dll v3.2.4.5 at the point single step after the GIE bit has been set shows that:

    a) The PC and SR passed to the MSP-430FETUIF firmware are correct for the instruction after the GIE bit has been set.

    b) After the single step has been executed, the MSP-FET430UIF firmware returns the PC and SR as both zero, which explains why the CCS debugger shows the PC as zero.  The  MSP-430FETUIF firmware indicates that the MSP430F2619 has "stepped into an interrupt" which is reasonable, given that the code has enabled the GIE bit when a timer interrupt was pending.

    i.e. can't see any obvious bug in the MSP430.dll, so may be a problem in the MSP-430FETUIF firmware.

  • Trying MSP430.dll v3.2.4.5 with a number of devices when step the instruction following GIE being set when there is a pending (timer) interrupt:

    1) With a MSP430F2619 or MSP430FG4618 the PC is incorrectly reported as zero. These devices use a CPUX module.

    2) With a MSP430F4793 correctly steps into the interrupt routine. This device uses a CPU module.

    3) With a CC430F5137 correctly steps into the interrupt routine. This device uses a CPUXV2 module.

    Therefore, the problem seems to affect only devices with a CPUX module. Looking at the source code of the MSP-FET430UIF firmware in slac460c there is different code to handle the CPU, CPUX and CPUXV2 modules.

    The _hal_SyncJtag_Conditional_SaveContextX function in the MSP-FET430UIF firmware uses a different code path to report the PC back to the MSP430.dll, when the firmware has detected that the CPUX module has entered an interrupt routine. Need to try and determine if there is a bug in the firmware, or a CPUX module erratum has been "discovered".

  • Hi Chester,

    I can confirm your observations regarding MSP430.dll v3.2.4.5:

    1) With a MSP430F427 or MSP430F449 (CPU modul) there is no unusual behavior.

    2) With a MSP430F2618 (CPUX module) the PC incorrectly jumps to 0x0000

  • Hi all,

    this is a gred finding. Now we have to wait until TI will provice a bugfix for the JTAG debugger, I fear.

     

  • Hi,

    Does anyone have some feedback from the MSP430 tools team regarding this issue? Do they accept this bug?

    Do we have a filled a bug request for this problem so we can track its status?

  • Hi,

    just a small update from the tools team:

    this issue should be addressed in the upcoming IDE release which should be in next Sept/Oct.

  • When you have a project with any interrupts enabled you will not be able to single step anymore.

    So it's acceptible for you that the debugger is not usable for months? We would appreciate a bugfix for the JTAG adapter to allow continuing of development.

     

  • Helge Kruse said:
    So it's acceptible for you that the debugger is not usable for months?

    My debugger isn't working for >6 years now. Likely because I didn't install it. Didn't hinder me to do lots of bigger projects in the meantime.

    However, if you have a paid license for your debugger, I'd contact the manufacturer directly (not through a forum) and demand a solution or refunding.

  • The following program demonstrates what is probably another effect of the problem:

    #include <msp430f2619.h>

    //-------------------------init_LED------------------------
    void init_LED(void){
            P1DIR |= BIT0;                                     // P1.0  output
    }

    // ----------------Timer A0 interrupt service routine------
    #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A (void)
    {
            P1OUT ^= BIT0;                             // Toggle P1.0
        TACCR0 += 30000;                                               // Reset CCR0
    }

    //-------------------------init_TIMER------------------------
    void init_TIMER(void){
             WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
             TACCTL0 = CCIE;                           // CCR0 interrupt enabled
             TACTL = TASSEL_2 + MC_2 + ID_3;           // SMCLK/8, cont mode, divider 8
             TACCR0 =  30000;                          // 1 Hz
             _bis_SR_register(LPM0_bits + GIE);        // Enter LPM0 w/ interrupt
     }

    void main(void)
    {
            init_LED();
            init_TIMER();
    }

    When using CCS Version 5.2.1.00018 and a MSP-FET430UIF with MSP430.dll v3.2.4.5:

    1) If use Step Over (F6) then when try and Step Over the call to init_TIMER the LED connected to P1.0 starts to flash indicating the interrupt is running, but the debugger remains running since the processor is halted in LPM0 and hasn't returned from the init_TIMER function. When the debugger is suspended the PC is shown as the instruction after the  _bis_SR_register in init_TIMER. This is the expected behaviour.

    2) If use Step Into (F5) then when try and single step out of the init_TIMER function the debugger reports:

    MSP430: Can't Single Step Target Program: Could not single step device

    Trying to suspend the deugger to check the state of the target doesn't have any effect. The debugger register view reports "Error: unable to read"

    (using the same program and device but via an Olimex MSP430-JTAG-TINY-V2 results in single stepping into the Timer_A which is correct given that only the ISR is active)

  • Chester Gillon said:

    Trying MSP430.dll v3.2.4.5 with a number of devices when step the instruction following GIE being set when there is a pending (timer) interrupt:

    1) With a MSP430F2619 or MSP430FG4618 the PC is incorrectly reported as zero. These devices use a CPUX module.

    2) With a MSP430F4793 correctly steps into the interrupt routine. This device uses a CPU module.

    3) With a CC430F5137 correctly steps into the interrupt routine. This device uses a CPUXV2 module.

    Therefore, the problem seems to affect only devices with a CPUX module. Looking at the source code of the MSP-FET430UIF firmware in slac460c there is different code to handle the CPU, CPUX and CPUXV2 modules.

    The _hal_SyncJtag_Conditional_SaveContextX function in the MSP-FET430UIF firmware uses a different code path to report the PC back to the MSP430.dll, when the firmware has detected that the CPUX module has entered an interrupt routine. Need to try and determine if there is a bug in the firmware, or a CPUX module erratum has been "discovered".

    I have repeated the test using CCS BETA v5.3.0.00042 with MSP430.dll v3.2.5.3. With a MSP430F2619, MSP430F4793 and CC430F5137 now all devices correctly step into the interrupt routine.

    Looking at the MSP430.dll v3.2.5.4 source code in slac460d shows that a change has been made to the _hal_SyncJtag_Conditional_SaveContextX function

**Attention** This is a public forum