FreeRTOS with calendar time

kivie wrote on Monday, August 24, 2015:

I need to schedule and run tasks at certain intervals each hour. To get correct calendar time the clock is synchronized with GPS. I am using Giant Gecko from Sililabs and need to use tickless mode. I’m using the FreeRTOS version (v7.4.2) that comes with Simplicity Studio. I need millisecond precision.

My first idea was to use the vTaskDelay function with a calculated value when to run the task. The problem with this method was that the time drifted. I just couldn’t get it right with the RTC. It worked quite well (within approx 10ms) when I only got one task and I redefined portTICK_PERIOD_MS to 9.94875.

Currently the application is running without FreeRTOS and the wake-ups for the tasks is done with the BURTC and this works really good (but it seemed simplier to use a RTOS to enable multitasking then extend current application). The way the calender time is kept on the mcu is by letting the BURTC count 1024 ticks per second. So I thought I could use the BURTC, but to be able to keep the calendar time I could not reset the the tick counter. The tick counter is reset by the GPS synchronization (each hour, no overflow). The problem here was that I had to set ISR to run each tick and this made the same task run multiple times for some reason.

So my third idea was to rewrite some parts of the FreeRTOS to get things working. The idea is to make some changes to tasks.c.

Redefine xTickCount to BURTC->CNT. Also remove everything that updates xTickCount. This way the xTickCount is always correct.
#define xTickCount BURTC->CNT

Whenever the BURTC->CNT is reset a loop goes through the list with tasks and reduces the time for each task.

vTaskDelay (chould be renamed) is supplied with a calculated value from BURTC->CNT and the value supplied is not subracted with xTickCount.

With these changes the vPortSuppressTicksAndSleep (there are changes in this function as well, e.g. the vTaskSetTick is not called since task.c get the tick count directly from BURTC->CNT) function sleeps to exactly the correct time. When it wakes up it starts to tick again but the task does not get executed.
The xTaskResumeAll is called when it is woken up and xYieldPending is set to pdTRUE.

I’m sure it can be unsafe to define xTickCount as I have done but I still think the task should be running after the cup have slept.

For some reason I can’t debug after the prvPortStartFirstTask is executed which makes it hard to see what goes wrong. I’m using eclipse and gdb for debugging.

Anyone have any suggestion why my Task isn’t running after sleep?
How I can use the RTC with a resolution of 1ms and no drift?
How I can use the BURTC with a resolution of 1ms and no drift (without reset the counter)?
Any idea why I can’t debug after prvPortStartFirstTask?

rtel wrote on Monday, August 24, 2015:

I’m using the FreeRTOS version (v7.4.2)

I’m sure the default tickless implementation will have changed since then, as the current version is V8.2.2.

Are you using the default tickless implementation, or have you defined your own, or even is it an implementation provided by SiLabs themselves?

Anyone have any suggestion why my Task isn’t running after sleep?

Same question - if you have provdied the implementation yourself please post it. Did you copy an exiting implementation?

How I can use the BURTC with a resolution of 1ms and no drift

I don’t know what BURTC is, although it is evident from your post that it is some kind of clock.

Any idea why I can’t debug after prvPortStartFirstTask?

I have never experienced that on any of the many many platforms I have used. Have you tried putting a break point actually within a task, rather than stepping though prvPortStartFirstTask? Which debugger interface are you using (for example, is it a J-Link?).

Regards.

alainm3 wrote on Monday, August 24, 2015:

What I can tell you is about sincronysing clocks, the short version is:
don’t even try.
You will be better off if you treat them as assinchronous clocks and use
methods to leave with that.

The RTOS (any RTOS) needs a steady monotonous clock, whereas an RTC can
get adjusted by the GPs annd can have gaps or even be adjusted backwards.

So, unless you are on one of the rare cases where this is mandatory by
the system definitions, you can probably live better with two
assynchronous clocks.

Alain

Em 24-08-2015 08:23, KiviE escreveu:

I need to schedule and run tasks at certain intervals each hour. To
get correct calendar time the clock is synchronized with GPS. I am
using Giant Gecko from Sililabs and need to use tickless mode. I’m
using the FreeRTOS version (v7.4.2) that comes with Simplicity Studio.
I need millisecond precision.

My first idea was to use the vTaskDelay function with a calculated
value when to run the task. The problem with this method was that the
time drifted. I just couldn’t get it right with the RTC. It worked
quite well (within approx 10ms) when I only got one task and I
redefined portTICK_PERIOD_MS to 9.94875.

Currently the application is running without FreeRTOS and the wake-ups
for the tasks is done with the BURTC and this works really good (but
it seemed simplier to use a RTOS to enable multitasking then extend
current application). The way the calender time is kept on the mcu is
by letting the BURTC count 1024 ticks per second. So I thought I could
use the BURTC, but to be able to keep the calendar time I could not
reset the the tick counter. The tick counter is reset by the GPS
synchronization (each hour, no overflow). The problem here was that I
had to set ISR to run each tick and this made the same task run
multiple times for some reason.

So my third idea was to rewrite some parts of the FreeRTOS to get
things working. The idea is to make some changes to tasks.c.

Redefine xTickCount to BURTC->CNT. Also remove everything that updates
xTickCount. This way the xTickCount is always correct.

define xTickCount BURTC->CNT

Whenever the BURTC->CNT is reset a loop goes through the list with
tasks and reduces the time for each task.

vTaskDelay (chould be renamed) is supplied with a calculated value
from BURTC->CNT and the value supplied is not subracted with xTickCount.

With these changes the vPortSuppressTicksAndSleep (there are changes
in this function as well, e.g. the vTaskSetTick is not called since
task.c get the tick count directly from BURTC->CNT) function sleeps to
exactly the correct time. When it wakes up it starts to tick again but
the task does not get executed.
The xTaskResumeAll is called when it is woken up and xYieldPending is
set to pdTRUE.

I’m sure it can be unsafe to define xTickCount as I have done but I
still think the task should be running after the cup have slept.

For some reason I can’t debug after the prvPortStartFirstTask is
executed which makes it hard to see what goes wrong. I’m using eclipse
and gdb for debugging.

Anyone have any suggestion why my Task isn’t running after sleep?
How I can use the RTC with a resolution of 1ms and no drift?
How I can use the BURTC with a resolution of 1ms and no drift (without
reset the counter)?
Any idea why I can’t debug after prvPortStartFirstTask?


FreeRTOS with calendar time
https://sourceforge.net/p/freertos/discussion/382005/thread/b9669e64/?limit=25#243a


Sent from sourceforge.net because you indicated interest in
SourceForge.net: Log In to SourceForge.net

To unsubscribe from further messages, please visit
SourceForge.net: Log In to SourceForge.net

kivie wrote on Wednesday, August 26, 2015:

Thank you for your answers!

To make things easier I have downloaded the current version V8.2.2.

Since I, as Alain Mouette said, most of all want to keep the clocks seperate I have runned the program with the RTC without syncronizing the clock with calendar time.

So the RTC is updating the tick with a frequency of 1024 ticks per second. The RTC uses external LFXO. The RTC counts to 16 to trigger a tick.

The calender time is keept by the BURTC. This is called backup RTC. As the RTC it uses the same external LFXO but with a different prescale (32 instead of 2). This clock is prescaled to give 1024 ticks per second. It is reset each sync. by the GPS.

In main you can see the two different tasks that are scheduled. There is in total 19 tasks + idle task. The time for the schedule is also given in the main function. http://pastebin.com/jWdMyH6r All task is busy-waiting, this is going to be rewritten in the future.

The FreeRTOSConfig.h I have taken from the Simplicity Studio but it seems to be taken from FreeRTOS V7.4.2. http://pastebin.com/J30ecgn5

The tickless implementation is also taken from Simplicity Studio but seems to be taken original from FreeRTOS V7.4.2. http://pastebin.com/nigTHShc

I have left the program running all night and you can see the timing issues here http://pastebin.com/hJM3LrkR You can see that after each sync. the BURTC have slipped 6-8 millisecond. This is not compensated for right now so tasks can be off for up to 8 ms is not a problem. But you can see that the first time T19 is executed it is delay 17 ms. And you can see that from T11, which is the first task to be executed the delay is increasing.

kivie wrote on Wednesday, August 26, 2015:

I did a simple test. I skipped the code sync. the time. Instead, in that task I added a busy loop for 2 minutes.

The result is this:
00:00:00:182 182 T1 00:00:00:118
00:02:00:186 02:00:186 T1 ms: 3479932 tickCount 115783, burtcdiff: 123020, freediff: 115783
00:03:07:184 03:07:184 T2 00:03:00:117

And with a busy-loop of only 2ms to ensure the log is written
00:00:00:182 182 T1 00:00:00:118
00:00:00:188 188 T1 ms: 3599930 tickCount 133, burtcdiff: 142, freediff: 133
00:03:00:125 03:00:125 T2 00:03:00:117

As you can see is that T2 is fired incorrectly in both cases but over 7 seconds off when the task busy-looped. It seems that the freertos tick isn’t update correctly all the time.

I have added that it prints the time it have calculated to wake-up. And also the difference for the burtc-counter and freertos-tick. It drifts in both cases.

davedoors wrote on Wednesday, August 26, 2015:

You are using tickless mode? The code comments tell you to expect drift as the clock is stopped when it is reprogrammed. Some time is removed to compensate for that and you can update the compensation value but it is never going to be 100% right.

kivie wrote on Wednesday, August 26, 2015:

Yes I use tickless mode and yes some drift is expected. But not as much as this. I mean 7 second drift is not small.

I have however discovered that I need to set the RTC to count to 15 instead of 16 and the problem is almost solved. I’m running some tests and hopefully that and finetuning the compensation for sleeping will solve it. That I should count to 15 is obvious, I don’t understand why I didn’t see that from the beginning. I had to much faith in that the files I got from Simplicy Studio was correct.

Thank you all for your time.

davedoors wrote on Wednesday, August 26, 2015:

I am confused by what you are doing. 7 seconds over what time? What are these numbers?

The result is this:
00:00:00:182 182 T1 00:00:00:118
00:02:00:186 02:00:186 T1 ms: 3479932 tickCount 115783, burtcdiff: 123020, freediff: 115783
00:03:07:184 03:07:184 T2 00:03:00:117
And with a busy-loop of only 2ms to ensure the log is written
00:00:00:182 182 T1 00:00:00:118
00:00:00:188 188 T1 ms: 3599930 tickCount 133, burtcdiff: 142, freediff: 133
00:03:00:125 03:00:125 T2 00:03:00:117

kivie wrote on Thursday, August 27, 2015:

00:00:00:182 is the time the task T1 is executed and 00:00:00:118 is the time the task should have been executed. But this is fine since setting up all tasks etc made it miss this time. T1 executes a busy-loop for 2 minutes.

00:03:07:184 is the time task T2 is executed and it should have been executed 00:03:00:117. That is 7 seconds later then expected.

If I change the busy-loop time form 2 minutes to 2 ms the time for the task is as:

00:00:00:182 is the time task T1 is executed and 00:00:00:118 is the expected executed time. Still fine to miss this time.

00:03:00:125 is the time task T2 is executed and it should have been executed 00:03:00:117. Now only 8 ms later then expected.

By changing the alarm time for the RTC to 15 instead of 16 solves this issue. Since it should count 16 ticks. The only problem I have right now is to minimize the drift due to the clock is stopped.

kivie wrote on Wednesday, October 07, 2015:

Any idea why I can’t debug after prvPortStartFirstTask?

I have never experienced that on any of the many many platforms I have used. Have you tried putting a break point actually within a task, rather than stepping though prvPortStartFirstTask? Which debugger interface are you using (for example, is it a J-Link?).

Thank you for your reply. Some stuff came up that made me postpone the debugging problem.

I am using arm-none-eabi-gdb as compiler and Segger J-link gdb server.

I can set a breakpoint inside a task and it will break on it. But I can’t step or resume execution. It just starts output Read 4 bytes @ address 0x0001DB8C (Data = 0x4B05B508). Complete log is found at pastebin J-link log msg - Pastebin.com

There is no problem what I have experienced debugging without FreeRTOS.

Edit: Of cource I found the solution directly after posting… Here is a link to the solution if anyone else looking for a solution https://community.freescale.com/thread/327560