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.

High frequency interrupt conflicting with debugger?

Other Parts Discussed in Thread: SEGGER, TM4C1231D5PZ

Hello,

I'm using IAR v6.50.5, a Segger J-Link with utilities v4.74a, and a Tiva TM4C1231D5PZ (Stellaris LM4F112C4QC) microcontroller clocked at 50MHz.

I have a periodic timer interrupt, which executes a handler that consumes about 1600 clock cycles (measured by reading the value of a 64-bit timer at the beginning and end of the handler).

In the following case, the program unexpectedly 'jumps' to the wrong address:

  • Using rev A3 silicon (this problem does NOT occur with rev B1 silicon--I have tried on several boards of each revision that are identical other than the microcontroller)
  • Attached to the debugger (this problem does NOT occur when not communicating the debugger--when this problem occurs a simple Power On Reset 'fixes' it)
  • The timer load value is set to 6000Hz (50000000/6000)or above (does not occur when the frequency is 5000Hz or below; I also checked the disassembly and the only thing that the compiler changed is this load value)
  • The TI flash-resident serial bootloader is present (does not occur when the bootloader is removed from the project)


When I say the program 'jumps', I mean it is re-entering the bootloader and getting stuck there.  The 'jump' occurs immediately after the timer that triggers this interrupt is enabled via a call to MAP_TimerEnable().

I checked the errata, but do not see anything to explain why this problem only occurs on the rev A3 silicon.

Any advice on how to further troubleshoot this would be greatly appreciated.

Thanks!

  • Ben H. said:
    Any advice on how to further troubleshoot

    Following very much qualifies as, "any advice."

    Feel your pain - have almost identical paid IAR (ours 6.60.1) & J-Link.

    Have you disabled the offending Timer - prior to its "set-up/config" - and only then call to, "Timer Enable()?"

    And - would not IAR's "Cycle Counter" provide far easier/faster means to note that handler's, "consumption?"  (access via Options > Registers > CPU Registers)  You can "break" first just upon entry to that ISR - note Cycle Count - and then break upon exit - Cycle Count Delta alive/present - and easy.

    Have you checked that offending Timer may be otherwise, "shared" or operated upon - by bootloader or another mechanism? 

    Perhaps the best advice is your own - look for commonality between that Timer & boot-loader - seems most fertile ground...

     

  • cb1,

    Thanks for the quick response, and also for bothering to answer this not-so-clear-cut question at all!

    cb1_mobile said:
    Have you disabled the offending Timer - prior to its "set-up/config" - and only then call to, "Timer Enable()?"

    Is adding the following to the timer initialization what you are suggesting?  This timer is not enabled at this point, so this should have no affect.  I tried this anyway, and got the same results.

        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);      /*Enable timer peripheral               */

        MAP_TimerDisable(TIMER0_BASE, TIMER_A);                         /*Disablethe timer                      */


        MAP_TimerConfigure( TIMER0_BASE,                                      /*Configure timer as periodic timer     */
                                TIMER_CFG_PERIODIC);

        MAP_TimerLoadSet(   TIMER0_BASE,                                      /*Set timer reload value to the display */
                            TIMER_A,                                                               /*  update frequency                    */
                            (MAP_SysCtlClockGet() / 6000));

        MAP_IntEnable(INT_TIMER0A);                                                /*Enable the timer interrupt            */

        MAP_TimerIntEnable( TIMER0_BASE,                                      /*Trigger timer interrupt on timeout    */
                                TIMER_TIMA_TIMEOUT);

        MAP_TimerEnable(TIMER0_BASE, TIMER_A);                         /*Enable the timer                      */

    cb1_mobile said:
    Have you checked that offending Timer may be otherwise, "shared" or operated upon - by bootloader or another mechanism? "

    This timer is definitely not used by the boot loader.  I'm unsure what you might mean by 'another mechanism'.

    cb1_mobile said:
    And - would not IAR's "Cycle Counter" provide far easier/faster means to note that handler's, "consumption?" "

    Thanks for the trick.  I should confess that I'm actually using the IAR plug-in for Eclipse.  If this feature has been implemented in the plug-in, it is not documented well and there is nothing similarly named (like Registers > CPU registers).

    My local TI field applications engineer suggested using the MPU to troubleshoot this problem.  We have never used a part with an MPU before and decided not to take advantage of it for this project.  That may have been the wrong decision--it seems useful even if only left in for debugging.  By adding memory protection, maybe I can 'catch' the root cause of this jump back into the boot loader.  He could not explain the inconsistency between the revA3 and rev B1 silicon other than saying that there may be some kind of race condition that is exposed by some minor change (not related to any errata) between those two versions of silicon.

    I will report my findings when I make more progress.

  • @Ben,

    You've nailed the Timer set-up/config - w/that TimerDisable().  Always best to be "safe."

    By "another mechanism" - might some other piece of code (or past code remnant) be impacting Timer_0?  Also - can you examine the pertinent Timer Registers - after the ill-fated "jump?"  (perhaps early w/in the boot-loader those Timer Registers can be copied/dumped for your review)

    I recall reading here - that Watchdog should be OFF during bootloader operation.  Might suggest your "restricting" other interrupts/operations & the WDG (as/if possible) prior to enabling that offending Timer... 

    You've a wealth of Timers w/in any ARM.  Perhaps helpful to try an unused "other" - see if issue persists...

    Here's our Cycle Counter - in all its time/effort-saving glory...  Shown is cycle count for, "ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);"

    Invoked via View > Registers > CPU Registers.

  • Ben,

    That certainly is some interesting behavior. When it jumps into the bootloader, has the timeout interrupt triggered? Does it jump to the bootloader if you configure Timer 1 instead? Is your program under 32KB? If so, you could try using an evaluation version of Keil to see if the problem is limited to IAR or not.

    Also, right after the program jumps to the bootloader, check the value of the entry in the interrupt vector table for the Timer 0 interrupt. I'm doubtful that this is the case, but errata 2.8 here allows for incorrect SRAM operation in A3 under specific code sequences.

  • cb1_mobile said:

    You've a wealth of Timers w/in any ARM.  Perhaps helpful to try an unused "other" - see if issue persists...

    @John,

    While we've over-lapped - this particular Timer suggestion - find your "inside" knowledge always welcome/helpful.

    Do note - poster has a very "non-standard" IAR implementation - may add issues... (i.e. poster: "confess that I'm actually using the IAR plug-in for Eclipse.") 

  • After further investigation, I've discovered that the root problem also exists on the rev B1 silicon.  Both are doing this 'jump' back into the boot loader, but only the rev A3 is getting stuck there.

    The Reset Cause register (RESC 0x400fE05C) shows a Software Reset and Watchdog 0; however, this reset happens before I even reach the part of the program where the watchdog is initialized!  It does not seem like the debugger is reflecting what is really happening.

    Disabling the watchdogs makes the Reset Cause register only show the software reset after the 'jump'.

    The Reset Cause register doesn't specify what type of software reset it is, but I'm guessing something is generating a Software System Request Reset using the VECTRESET bit in the APINT register, because this is the only reset source that does not perform a peripheral reset.  I'm saying the peripherals must not be getting reset if adding/removing watchdogs and timers affects what happens after the reset.

    Looking back, I HAVE noticed an inconsistent delay before the display elements on my control turn on.  When I start running the debugger while halted at main(), it takes slightly longer than it does when just doing a Power On Reset.  This jump back into the boot loader and watchdog reset must have always been happening while debugging, but after doing it once apparently caused no additional problems.

    I can only conclude that I've been using the debugger wrong for the past year and never noticed...  After looking at IAR's application notes (http://www.iar.com/Global/Resources) about boot loaders, the method I've been using is not what they recommend.  I've simply been including the boot loader image in the application, and then running the debug session with the default settings.

    IAR's approach for debugging the application that's placed after the boot loader is to add a long delay loop before executing any 'real' application code so you have time to attach the debug session to the already running target.  This works with no problems (which is expected since I haven't had any problems with Power On Resets or previously even when debugging once this one-shot reset occured).

    I am still interested to know why the method I was using didn't work.  The answer probably lies in the Debugging Guide that comes with the IAR installation, which I will read through more carefully unless anyone can give me an answer off the top of their head.

    I'm getting the impression that this is a limitation of IAR's debug tools that other toolchains don't have.  Is this true?

    Also, thanks for all the assistance!  Your suggestions did help eliminate a lot of possibilities.