Hi Amila, in tickless mode (
configUSE_TICKLESS_IDLE
), the following function is called when the kernel wants to sleep:
~~~
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
~~~
Now you can do anything you want, but you must guarantee three things:
- Wake-up on any ISR which is enabled
- Wake-up after at most
xExpectedIdleTime
clock ticks
- Tell the kernel how long the sleeping took by calling
vTaskStepTick(n_ticks)
Be aware that the kernel time, as provided by
xTaskGetTickCount()
, becomes less precise. That is because the sleeping duration won’t be a nice multiple of clock-ticks.
An example: I used “tickless idle” in an Atmel SAM4E. I decided to use a Timer-Counter (TC) as a source of time. This TC has an overflow interrupt every 30 seconds. This time sources has a resolution of 1 uS, and it is independent from the kernel tick.
It is still important to keep the kernel time as precise as possible, because many kernel delays depend in it.
Changing the system clock frequency is a bit tricky: make sure that no DMA is active. And also, if you use TC’s, their frequencies might, or might not, change as well.
In order to save energy ( batteries ), it is important to make long idle times, like e.g. 30 seconds.
I tested tickless mode in combination with FreeRTOS+TCP: that worked well. But I did disable the reception of UDP broadcasting packets, in order to increase the length of the idle periods.
USB : isn’t possible to run at a low frequency all the time, until a USB connector is plugged in? And as soon as the device is plugged-in, you increase the frequency to 48 MHz?
Once USB is connected, sleeping will be difficult because of the 1 ms USB clock-tick.