SysTick just stops for no apparent reason

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

SysTick just stops for no apparent reason

1,942 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sdt99 on Thu Sep 25 08:08:02 MST 2014
LPC1857 on Keil demo board with IAR, using 1ms SysTick as the primary clock source.  I have one variable updated by Systick and used by the main code so I wanted to suspend SysTick interrupts when the variable is accessed by the main code.  Here is SysTick initialization (works fine):(CoreClock=180MHz, so the countdown value is within range :  I checked)

#define TICKRATE_HZ1 (1000)/* 1000 ticks per second */
SysTick_Config(SystemCoreClock / TICKRATE_HZ1);


Here are functions I created to disable and re-enable SysTick, checking for a missed tick.  The intent was to disable the tick, access the variable (memcpy) and reenable the tick.

void DisableSysTick(void){
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; // disable Systick interupt
}

void EnableSysTick(void){
    // Check if an interrupt was missed
    if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk){
        SysTick_Handler();
    }
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; // Enable Systick interupt
}


If I call these functions then SysTick seems to randomly stop ticking.  When I dump memory from xe000e000 to xe000f000 to look for any register changes that might explain the stop I see no changes (other than the downcounter value, of course).

If I comment out these functions then SysTick continues to work.

I can't see why this code would cause a problem from either NXP or ARM documentation, but I am pretty new to NXP ARM CPUs.

Would be grateful if anyone can point out any obvious errors.   I could restructure my code to avoid masking systick, but I am bothered by the fact that I don't understand why the tick stops.

Thanks
Labels (1)
0 Kudos
4 Replies

1,281 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pacman on Fri Oct 03 04:08:55 MST 2014
Sorry for the noise and confusion.

-But if you call your systick from task-time and an interrupt occurs while it's being called, then you'd have a race-condition.

    ticks++;


The above might miss a tick now and then.
The correct way of incrementing a counter, which is updated both by interrupts and task-time, is to use atomic access.
-It gets even worse if you're doing other things in your SysTick interrupt, such as ... unlinking elements from a linked list.
0 Kudos

1,281 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sdt99 on Sun Sep 28 05:47:54 MST 2014
Thanks for the suggestion, but it's my understanding that the SysTick interrupt cannot be disabled in the NVIC: it can only be disabled in the Systick control register.  The NVIC controls peripheral interrupts, but not Cortex interrupts (shown as negative at this link http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABHGEAJ.html)


Anyway the solution it seems is to not call the Systick_Handler directly from the non-ISR code: since I made that change I have not has any further problems with SysTick.
0 Kudos

1,281 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pacman on Sat Sep 27 19:19:02 MST 2014
if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk){
SysTick_Handler();
}


I don't have a LPC18xx, but as far as I understand, the above code should not be necessary.
Try disabling it and see if it works then.
The reason I think it would work, is that the interrupt pending bit is set, and when this is set, all you have to do, is to enable the interrupt; then the NVIC sees that there's a pending interrupt and executes the SysTick_Handler.
-I might be wrong, though. If so, just ignore this.
0 Kudos

1,281 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sdt99 on Thu Sep 25 10:32:15 MST 2014
Looks like I might have found the problem: that the SysTick_Handler() is called from a normal function, not by an interrupt.  I guess this is illegal  (?).

This code was ported from another ARM processor at a slower clock speed, where the EnableSysTick() function did not directly call the SysTick_Handler() ISR, but called a normal function.
0 Kudos