Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Tickless microsecond delay before sleep

Posted by cajjed on November 23, 2016

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

Posted by rtel on November 23, 2016

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

Posted by cajjed on November 23, 2016

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) > SysTickLOADRELOADMsk) return (1); /* Reload value impossible */

SysTick->LOAD = ticks - 1; /* set reload register / NVICSetPriority (SysTickIRQn, (1<<_NVICPRIO_BITS) - 1); / set Priority for Systick Interrupt / SysTick->VAL = 0; / Load the SysTick Counter Value / SysTick->CTRL = SysTickCTRLCLKSOURCEMsk | SysTickCTRLTICKINTMsk | SysTickCTRLENABLE_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

Posted by rtel on November 23, 2016

By default, FreeRTOS needs to control the SysTick timer.


Tickless microsecond delay before sleep

Posted by cajjed on November 23, 2016

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

Posted by cajjed on November 23, 2016

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

Posted by rtel on November 23, 2016

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

Posted by cajjed on November 23, 2016

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

Posted by rtel on November 24, 2016

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.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS