Systick occasionally stops triggering

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Systick occasionally stops triggering

3,337 Views
ignisuti
Contributor IV

I've setup a delay function that relies on the systick counter. In very rare occasions (not yet clearly defined), I get into a situation where my delay function never exits. After further investigation, I've found in these cases it's because SysTick function stopped triggering and therefore stopped incrementing the counter I'm watching in my delay loop as a condition to exit.

 

So, what conditions pause the SysTic timer?

 

I have mine set to trigger every 10us. The interrupt itself doing so little that there shouldn't be any concerns about the interrupt attempting to be re-entrant.

 

/* =================================================================================================  FUNCTION DESCRIPTION:==      SysTick Interrupt. == Interrupts every 10 microseconds and updates timer counters.====  OUTPUTS:== counter_10us==      counter_1ms==      counter_1sec== =============================================================================================*/void TIMERS__INTERRUPT__systick  (  void   )    {    /* Local Variables. */    counter_10us++;        /* Update millisecond counter after each 1000us. */    if( counter_10us % 100 == 0 ) {  counter_1ms++;  /* Update second counter after each 1000ms. */ if( counter_1ms % 1000 == 0 )     {      counter_1sec++;           DIAG_LED_D25( 2 /* TOGGLE */ ); //Toggle Diagnostic LED #25          }     }        } /* TIMERS__INTERRUPT__systick() *//* =================================================================================================  FUNCTION DESCRIPTION:== Configures SysTick interrupt to occur every 10us.== Accepts a variable input so that the SYSTICK_FREQUENCY can be trimmed.==== reload_val - Number of clock cycles (based on the Core Clock) before an interrupt occurs.====  OUTPUTS:==      N/A== =============================================================================================*/void TIMERS__INTERRUPT__initialize_systick  (  u32 reload_val  )    {            /* Configure SysTick     * Reference: Cortex M4 Generic Users Guide (ARM DUI 0553A) - Section 4.4 */    SYST_RVR = reload_val;    SYST_CSR = SysTick_CSR_ENABLE_MASK | SysTick_CSR_TICKINT_MASK | SysTick_CSR_CLKSOURCE_MASK;    }/* =================================================================================================  FUNCTION DESCRIPTION:==      Delays to for specified amount of time.== Allows for a wide variety of delays and avoids rollover errors.==== Example: The following function call will initiate a 1 minutes delay.==   TIMERS__delay( DELAY_TIMER__1sec, 60 )====  OUTPUTS:== N/A== =============================================================================================*/void TIMERS__delay  (  delay_timers_t timer_type,  u32      delay_amount  )    {    /* Local Variables. */    u32  last_count;    u32  current_count = 0;    u32 *timer_ptr;        /* Grab pointer to the specified timer. */    switch( timer_type ) { case DELAY_TIMER__1sec:     timer_ptr = (u32*)&counter_1sec;     break;      case DELAY_TIMER__1ms:     timer_ptr = (u32*)&counter_1ms;     break;      case DELAY_TIMER__10us:     default:     timer_ptr = (u32*)&counter_10us;     break; }        /* Record the current count from the interrupt counter. */    last_count = *timer_ptr;    /* Loop until the local counter matches the specified delay. */    while( current_count < delay_amount )  { /* Check if interrupt counter has been updated. */ if( last_count != *timer_ptr )     {     last_count = *timer_ptr;  //Record current count;     current_count++;  //Increment local counter.     } }    } /* TIMERS__delay() */

 

0 Kudos
8 Replies

1,254 Views
ignisuti
Contributor IV

I'm using a P&E MultilinK Universal programmer/debugger.


Does anyone know if this tool will occasionally hi-jack the SysTick timer in the ARM core? The reason I ask is because I'm having this trouble with my SysTick ceasing to fire with the debugger, but not when I run from flash without the debugger.

0 Kudos

1,254 Views
comsosysarch
Contributor III

10 microseconds is at most 1000 system clock cycles (if clocking at 100 MHz which is the max clock on my K60 anyhow).

And it is only 250 flash bus clock cycles if running from flash, as you indicate, which is typically limited to 25 MHz. You might get more if the caching works very well, but I suspect that is very difficult to quantify with any certainty.

The interrupt is in C code on a RISC machine. Accessing a bunch of global counter variables the compiler might turn each variable fetch or store into 4-5 instructions and depending on your optimization settings may or may not be repeating those stores and fetches for each operation.

0 Kudos

1,254 Views
ignisuti
Contributor IV

I hadn't been clearing the SysTick counter when initializing the timer. I read in the ARM manual that this was necessary. I've made this change and yet to see the problem return. So, I'm keeping my fingers crossed hoping that's all it was.

 

Yes, running at 100MHz on a K10. Using the System Core bus.

0 Kudos

1,254 Views
comsosysarch
Contributor III

Since you say you are running from flash... 25 MHz flash bus speed. That measn 250 instruction cycles per systick interrupt. You would save a little using caching but I do not know if you are getting that many interrupts if the caching will continue to work so well in terms of speed improvement either.

 

Maybe just to troubleshoot try slowing systick down by a factor of ten or a hundred and see if you still miss some? Just a suggestion.

 

0 Kudos

1,254 Views
Jeinstei
Contributor II
So before initializing systick you need to clear the counter? I thought systick was free running once the processor was hot?

I'd love to know which arm reference this is in!
0 Kudos

1,254 Views
ignisuti
Contributor IV

Here it is: Cortex™-M4 Devices Generic User Guide

 

Directly from section 4.4.5:

The SysTick counter reload and current value are not initialized by hardware. This means thecorrect initialization sequence for the SysTick counter is:1. Program reload value.2. Clear current value.3. Program Control and Status register.

 

0 Kudos

1,254 Views
Jeinstei
Contributor II

Okay. good to know. Thanks for the reference.

0 Kudos

1,254 Views
ignisuti
Contributor IV

The issue has returned. Something is killing my SysTick interrupt.

 

Any ides for things to check?

0 Kudos