Lazy SysTick but works fine with debugger

rishitborad wrote on Wednesday, August 21, 2019:

Hello Everyone,

I am running FreeRTOS 10.2.0 on my SAML21 Eval board.
CPU clock is running at 48MHz and configTICK_RATE_HZ is 1000.

When I am running the program in debug mode on the board. It is working alright. I have an led toggling at 1second and xTimer running and calling the callback function every second.

When I stop the debug mode and let it run or flash the program on the chip using programmer 1second timer and tasks becomes ~14seconds.

I toggeled GPIO pin in Systick_Handler() and I see the same problem. While this is happening, I am requesting SysTick register values via UART and they look alright.

csr: 0x10007, rvr: 0xbb7f, cvr: 0xb3bf, calib: 0x40000000
Note that these register values are not changing when I stop the debugger.

Also, There is no problem when with SysTick when I am running a similar project on FreeRTOS 10.0.0, same eval board and at 4MHz clock freq.

I am not sure what is happening. I would appreciate any ideas or pointers.

Thanks in advance.
Risht

rishitborad wrote on Thursday, August 22, 2019:

Found the problem, the CPU is in Standby mode (level2) that stops CPU clock and 200uS ADC interrupt wakes up the CPU and its clock. SysTick timer counts for the time CPU clock is up and stops counting before it goes back to sleep.

The question is, How do i use the standby mode and also let the CPU context switch at evey 1mS? I am reading some meterial online which talks about “Tickles Idle” and using RTC as reference clock for SysTick. Getting more information on this.

Is there anything else I can do?

TIA

richard_damon wrote on Thursday, August 22, 2019:

It sounds like the tickless idle isn’t configured right for your system, as it shouldn’t cause that much time shift. One obvious factor is you shouldn’t be using a sleep mode that stops the timer that the tickless idle is using to time things in tickless mode.

I suspect the simplest answer is to just disable tickless idle until you can (if you need to) figure out what you want it to be doing and implement that. If you have a frequent interrupt, a mode like tickless idle is likely not that helpful, one of its main uses is that if the processor doesn’t need to be do ANYTHING for a period of time, rather than using some light sleep mode (if any) and waking up every tick to realize that there isn’t anything currently to do, is to instead configure the system to sleep for a longer period, and perhaps initiate a higher level of sleeping. These higher levels of sleep (like your Standby mode) will typically have lower power draw during them, but may have a power or time cost to enter/exit them so should only be used if you expect to be able to sleep for awhile.

rishitborad wrote on Thursday, August 22, 2019:

Thanks for the reply Richard.

I figured Tickless Idle is not ideal for my application so theres that.

If you may, I am still figuring out how to get SysTick running in STANDBY sleep mode. This sleep mode turns off the CPU_CLK so SysTick is not clocking during the sleep times. What I am figuring out right now is if I can use RUNSTANDBY and ONDEMAND functionality available on the MCU.

How do you run systick when in one of this deep sleep modes?

TIA

richard_damon wrote on Thursday, August 22, 2019:

It is a simple matter of fact that if you are using the core systick timer to generate your system ticks, you can’t shut of the clock to the processor core and keep time. FreeRTOS uses is by default as you know it is present in all processors in the family, but that doesn’t mean you have to use it in your application. FreeRTOS makes it fairly easy to replace the systick timer with some other resource in the system that can generate the periodic interrupts. If your processor has another time that can continue to run with the processor put to sleep, and can wake up the processor, than you can use that timer for the system tick.

rishitborad wrote on Thursday, August 22, 2019:

I agree and working on something similar.

How does causing SysTick exception by setting PENDSTSET in Interrupt Control and Status Register sounds? Thats is what SysTick is basically doing. Can I set PENDSTSET bit and in my periodic ADC interruptISR (ADC triggered by Timer at every 200uS, set PENDSTSET after every 5 services) and hope for it to context switch?

Again, thanks for your time :slight_smile:

Regards,
Rishit

richard_damon wrote on Friday, August 23, 2019:

The systick handler does more than just set the PENDSTSET bit, generally the tick intererupt needs to call xTaskIncrementTick() inside a critical section, and if that returns non-zero, to activate the scheduler (which is done with the PENDSV on the Arm). If you just do the PENDSV, time won’t advance.

One question though, does the timer for the ADC not get shut off like the SysTick? or is this a special timer designed to run in low power mode.

rishitborad wrote on Friday, August 23, 2019:

The systick handler does more than just set the PENDSTSET bit, generally the tick intererupt needs to call xTaskIncrementTick() inside a critical section, and if that returns non-zero, to activate the scheduler (which is done with the PENDSV on the Arm). If you just do the PENDSV, time won't advance

What I meant was ADC triggers SysTick_Handler() by setting the PENDSTSET. SysTick handler takes care of the call to xTaskIncrementTick() and triggers PendSV by setting PENDSVSET for scheduler. Time is advancing and scheduler is working but I am running into different problems now. My application is not working as it was, eg. UART stoped working. So I am trying to learn whats happening there.

One question though, does the timer for the ADC not get shut off like the SysTick? or is this a special timer designed to run in low power mode.

Timer and ADC are getting the clock signal OnDemand. In this lowpower mode all the peripheral interrupts are able to wake up/request the clock. Systick interrupt can not.

Thank you for guiding me through.

Regards,
Rishit

rtel wrote on Friday, August 23, 2019:

If you turn off the clock that generates the systick then the systick
won’t execute :o) However you don’t need to use the systick timer as
the tick interrupt source as the functions that setup the clock are
weakly defined symbols to enable you to use any clock you want and many
special low power MCUs have low power clocks that continue to execute in
various different sleep modes. Have a look at the tickless idle
examples in the main download for reference.