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.

TM4C1237E6PM: SysTick_Handler stops being called

Part Number: TM4C1237E6PM

In our code, we set up SysTick as shown.

/* Init the SysTick module for 1ms interrupts @50 MHz.
*/
ROM_SysTickPeriodSet(50000000 / 1000);
ROM_SysTickIntEnable();
ROM_SysTickEnable();

The SysTick_handler routine is shown below.

void SysTick_handler(void)
{
/*
* === FUNCTION ======================================================================
* Name: Systick_handler()
* Description: Interrupt Service Routine for the systick.
*
* Handle all background processing.
* =====================================================================================
*/
sc_tmr_ms_ticked = true;
++tmr_ctr;

//
// The systick is 1mS - we want to poll the buttons every BUTTON_POLL_TIME mS.
//
if ((tmr_ctr % BUTTON_POLL_TIME) == 0) {
STbutton_poll();
}

// Check the wdog every 50msec. The output should be toggled.
if ((tmr_ctr % WDOG_POLL_TIME) == 0) {
wdog_check();
}

// poll the SAFETY_FAULT input
if ((start_the_main_loop == true) && ((tmr_ctr % SAFETY_FAULT_POLL_TIME) == 0)) {
safety_fault_poll();
}

// if ((tmr_ctr % WIRELESS_POLL_TIME) == 0) {
// read_BT_stat();
// }
//
// if ((tmr_ctr % WIRELESS_BATT_POLL_TIME) == 0) {
// read_BT_batt_stat();
// }

if (((proc.handpiece_state == LED_FAST_FLASH) && ((tmr_ctr % FAST_FLASH_RATE) == 0)) ||
((proc.handpiece_state == LED_SLOW_FLASH) && ((tmr_ctr % SLOW_FLASH_RATE) == 0)) ||
((proc.handpiece_state == LED_FASTER_FLASH) && ((tmr_ctr % FASTER_FLASH_RATE) == 0))) {
/**/
//proc.handpiece_on ^= 1; // flip status led
// Synchronize flashing of this LED
if (((proc.handpiece_state == LED_FAST_FLASH) && ((tmr_ctr % (FAST_FLASH_RATE*2)) == 0)) ||
((proc.handpiece_state == LED_FASTER_FLASH) && ((tmr_ctr % (FASTER_FLASH_RATE*2)) == 0)) ||
((proc.handpiece_state == LED_SLOW_FLASH) && ((tmr_ctr % (SLOW_FLASH_RATE*2)) == 0)))
proc.handpiece_on = 1;
else
proc.handpiece_on = 0;
if (proc.handpiece_on) {
SC_RAISE_EVT(Handpiece_led, on);
} else {
SC_RAISE_EVT(Handpiece_led, off);
}
}

/* more LED processing, all using the same code as above */

}

Here's the PROBLEM.  The code runs fine until some event occurs and SysTick_handler stops being called.  Our box stops processing input from buttons and stops flashing LEDs.  Using the debugger, I see that the main loop is still running, but no call to SysTick_handler.

  • I am up to image 150.  As I change to a new image, sometimes the failure disappears, and sometimes it appears at another place in the sequence.  If it appears, it is repeatable in that image.
  • I can monitor the SysTick Interrupt enable bit and Master Interrupt enable bit(PRIMASK register), and both levels of interrupt are enabled.
  • This box has a USB connection, and we use code built from TivaWare 2.1.2.111. 
    • If a USB cable is connected, the failure doesn't happen.  It only happens if no cable is connected.
    • If I plug in a cable after the failure occurs, the code starts running again.
    • I changed the code to pull in 2.2.0.295 libraries, but that did not fix the problem.
  • My STACK_SIZE = 2048.  I bumped it up by 512 to 2560, but that did not fix the problem.

Has this issue been seen by anyone else?  It's clearly tied to the USB interface, but I can't figure out why SysTick_handler stops being called, so I can't fix the problem.  I have workarounds available, but they will not be fully accepted if I can't point to the actual failure mechanism.

  • Hi Chuck,

      Not sure what is wrong with your described behavior. The sysTick has a relative high interrupt priority (at priority 15) compared to the USB (at priority 60). Therefore, if a USB interrupt comes in, it will not preempt the sysTick.  On the contrary, if the processor is currently serving the USB, a sysTick interrupt is supposed to preempt the USB since it is a higher priority. This is the case based on the default priority arrangement. However, it will be a different story if you remap the priority such that the sysTick priority is lower than the USB. Please confirm this point. 

      When you use the debugger, can you also view the sysTick registers in the NVIC module. Click on the "Continuous refresh" and do you see the NVIC_ST_CURRENT register changing value? Also observe the NVIC_ST_CTRL register, is the lower three bits set to high to use the System clock as the clock source and the interrupt is enabled as well as the sysTick counter is enabled. 

      If you think the USB has something to do with the sysTick, then can you do an experiment? Change the sysTick clock source from system clock to PIOSC. Does it make a difference?

  • Charles,

    I did not change the SysTick priority.

    I looked at the NVIC registers during a debug session with Continuous Refresh enabled.  I saw the CURRENT value updating constantly, and ST_CTRL would usually be 0x0000_0007, with brief periods of 0x0000_0005.  After the first debug run with Continuous refresh, I never saw the registers refresh automatically again.  If I halt the run and then restart it, the NVIC_CURRENT will change its value.  
    When the FW stops calling the SysTick ISR, I can use halt/start and see that NVIC_CURRENT is still changing its value.  I don't think the counter is getting to 0, since the breakpoint I set inside the ISR is never reached.

    I changed my SysTick setup to the following to use the PIOSC as the clock source

    ROM_SysTickPeriodSet(4000000 / 1000);
    //ROM_SysTickPeriodSet(50000000 / 1000);
    ROM_SysTickIntEnable();
    ROM_SysTickEnable();
    HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_CLK_SRC);

    After making that change, the SysTick ISR is always called.  I can't start jumping for joy, however, because if I make any of a number of changes to the code, the ISR will always be called.

  • Charles,

       I forgot to mention two other points.

    1. When I reach SysTickIntDisable() in the code, if I try to open the function in CCS I get the message.

      Can't find a source file at "C:/Jenkins/workspace/TivaWare-Git-Release/DriverLib/build/DriverLib.test/driverlib/systick.c"
      Locate the file or edit the source lookup path to include its location.



    2. When the ISR isn't being called, if I plug a USB cable into my console, then text is sent across the USB interface and the ISR is called again.

    Chuck Wilde

  • Hi Chuck,

     

    Chuck Wilde said:

    Can't find a source file at "C:/Jenkins/workspace/TivaWare-Git-Release/DriverLib/build/DriverLib.test/driverlib/systick.c"
    Locate the file or edit the source lookup path to include its location.

      Please see below. Click the "Locate File" button and provide the path to the driverlib. This will be C:\ti\TivaWare_C_Series-2.2.0.295\driverlib if you are using the TivaWare v2.2.0.295.