Tickless microsecond delay before sleep

I am using a samd21g18a and using the Atmel Software Framework with freeRTOS 9.0. I have implemented tickless using an external oscillator and my own vPortSuppressTicksAndSleep function (mostly just the version used by ASF and others online). The tickless mode works great. I am trying to implement a delay before sleeping so that my usart can empty before sleeping. To do this I put a notReadyToSleep function at the beginning of vPortSuprressTicksAndSleep: ~~~ bool notReadyToSleep(void) { if (head != tail) return true; // Delay to let last print byte be written delayMicroseconds(60); return false; } ~~~ If the function is true I don’t try and sleep. If it is false then I wait 60 microseconds and then continue. This causes serious random issues with my tick count (For example, vTaskDelay of a second will take microseconds). My Tick Rate is 1024 Hz. To avoid the need for uartReadyToSleep function I have implemented a waitToSleepTask: ~~~ void waitToSleepTask(void *params) { for (;;) { ulTaskNotifyTake(pdTRUE, portMAX_DELAY); while (notReadyToSleep()) { vTaskDelay(1); } // Delay to let last print byte be written delayMicroseconds(60); } } ~~~ The task method works fine but I would rather use a function check before tickless sleep, thus avoid having such a simple task running. Is there a way to implement this in vPortSuprressTicksAndSleep? I would have thought the 60 microsecond delay would just end up in the sleep noise.

Tickless microsecond delay before sleep

I’m afraid I don’t understand what your problem is. I think you are saying that calling delayMicrosencods() is causing a problem with the tick frequency, so I’m going to GUESS that you have implemented delayMicroseconds() such that it uses the same clock as the tick timer.

Tickless microsecond delay before sleep

Thanks for your response and I am sensing further insight in your response. I am using the SysTick in my delay. I read it and then just wait for the 60 microseconds to pass. I was using the Atmel Studio Framework (ASF) to configure the SysTick Counter (SysTickConfig) for this purpose (corecm0plus.h): ~~~ __STATICINLINE uint32t SysTickConfig(uint32t ticks) { if ((ticks – 1) > SysTickLOADRELOAD_Msk) return (1); /* Reload value impossible */ SysTick->LOAD = ticks – 1; /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) – 1); /* set Priority for Systick Interrupt */ SysTick->VAL = 0; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0); /* Function successful */ } ~~~ Your answer makes me believe that by doing this I am cuasing issues with the FreeRTOS tick when I configure this SysTick? I will explore, but any further enlightenment is appreciated…

Tickless microsecond delay before sleep

By default, FreeRTOS needs to control the SysTick timer.

Tickless microsecond delay before sleep

Thanks, I see that now. I had made the false assumption that SysTick was just another counter and that FreeRTOS had its own systick counter.

Tickless microsecond delay before sleep

So follow on question. In this tickless implementation it uses a timer/counter to fire the callback xPortSysTickHandler every freeRTOS tick (in my case 1/1024 sec). Since SysTick never gets enabled in vPortSetupTimerInterrupt (because I am user a timer/counter) is SysTick just a place to store tick counts?

Tickless microsecond delay before sleep

Maybe without re-reading the whole thread I made a mistake in the last answer. If you are using your own clock to generate the tick, and the systick is not used by RTOS, then you can use the SysTick for your own purposes – but it will likely stop if you go into a deep sleep.

Tickless microsecond delay before sleep

Thanks again for the responses, they have been very helpful. It looks like my problem is that the default SysTickConfig from ASF as shown above was setting the systick handler (SysTickHandler) to fire when it reached the LOAD value. The problem is that the same handler is still tied to xPortSysTickHandler. So the SysTickHandler was getting called every tick (1/1024) and then every time the SysTick reach full load (0x00FFFFFF) or in my case about every 350 ms. This extra call was thus causing all kinds of randomness. Is there a way to replace SysTickHandler with another handler? ~~~

define xPortSysTickHandler SysTick_Handler

~~~ Thanks again

Tickless microsecond delay before sleep

Yes – the systick handler is just an entry in the vector table and you can replace it with whatever you like. Its is best not to edit the vector table directly, but instead provide the definition of a function call SysTick_Handler – which is the name of the installed handler. The line of code in your post above is effectively doing that by using a

define to change the name of the FreeRTOS SysTick handler, which is

called xPortSysTickHandler, to SysTick_Handler.