FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [November 2016 Threads] Tickless microsecond delay before sleepPosted 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 sleepPosted 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 sleepPosted 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 sleepPosted by rtel on November 23, 2016 By default, FreeRTOS needs to control the SysTick timer.
Tickless microsecond delay before sleepPosted 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 sleepPosted 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 sleepPosted 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 sleepPosted 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 sleepPosted 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.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|