Author Topic: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS  (Read 7518 times)

0 Members and 1 Guest are viewing this topic.

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« on: August 13, 2020, 06:17:30 pm »
Hi, I am trying to understand the RTOS in general. However, I couldn't find good reference for a beginner.

I want to use FreeRTOS as Hard Real Time schedular. I have a high priority task which needs to be fired evey 2.5ms. However, as default FreeRTOS in STM32 uses Systick as timer which is set to 1kHz.

Since each tick is 1ms how can I set my task to periodically called every 2.5ms?

Also can anyone suggest a good reference/source for RTOS/FreeRTOS for beginners?
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1842
  • Country: se
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #1 on: August 13, 2020, 07:17:36 pm »
First, the resource:
It might seem an obvious suggestion, but did you go through Mastering the FreeRTOS™ Real Time Kernel, available at the FreeRTOS site?
It is not updated to the latest version (10.x - the book covers 8.x) but it's nonetheless a very good introduction (not only to FreeRTOS).

Then, the question:
If you only rely on the FreeRTOS tick, you can't, as you might have imagined.
The scheduling granularity goes with the tick - in general.
That said, there's a way: you can use an HW timer set to generate a periodic interrupt, and in the interrupt handler use e.g. vTaskNotifyGiveFromISR() to wake up your task, waiting on a ulTaskNotifyTake().
Note the fromISR part, that allows the API to be called from an ISR, and forces a reschedule.
If the sleeping task has a high enough priority, it will be immediately scheduled.

I'm suggesting to use a direct notification since they have much smaller overhead with respect to queues or semaphores.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 22101
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #2 on: August 13, 2020, 07:36:20 pm »
You will need to consider how much jitter in the interval your system can tolerate.

Depending on that it may or may not be possible to achieve it in software. Don't forget that caches introduce timing variability, as do interrupts, and higher priority tasks.

If you are going to use a system call, check the documentation carefully, looking for phrases like "at least Xms".

Consider how you are going to verify that your implementation actually exceeds your requirements,  ensuring worst case behaviour. That is not trivial.

In the limit you might have to use external hardware such as FPGA technology, or a close approximation like the xCORE processors where the RTOS is implemented in hardware and guarantees timing to a 10ns resolution.
« Last Edit: August 13, 2020, 07:52:11 pm by tggzzz »
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9987
  • Country: us
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #3 on: August 13, 2020, 07:57:45 pm »
How would one of the dual core PSOC 6 chips play into this?  The absolute real time process could run all by itself in the M0 core.  Let FreeRTOS deal with the M4 core.

If the CPU must be a STM32 then the suggestions above should work.
« Last Edit: August 13, 2020, 08:01:27 pm by rstofer »
 

Offline jnz

  • Frequent Contributor
  • **
  • Posts: 593
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #4 on: August 13, 2020, 08:10:41 pm »
First, the resource:
It might seem an obvious suggestion, but did you go through Mastering the FreeRTOS™ Real Time Kernel, available at the FreeRTOS site?
It is not updated to the latest version (10.x - the book covers 8.x) but it's nonetheless a very good introduction (not only to FreeRTOS).

Then, the question:
If you only rely on the FreeRTOS tick, you can't, as you might have imagined.
The scheduling granularity goes with the tick - in general.
That said, there's a way: you can use an HW timer set to generate a periodic interrupt, and in the interrupt handler use e.g. vTaskNotifyGiveFromISR() to wake up your task, waiting on a ulTaskNotifyTake().
Note the fromISR part, that allows the API to be called from an ISR, and forces a reschedule.
If the sleeping task has a high enough priority, it will be immediately scheduled.

I'm suggesting to use a direct notification since they have much smaller overhead with respect to queues or semaphores.

This was my thought as well. Since it's an STM32, you can probably assume that you even have time to interupt, and defer processing. Depends how exact to 2.5ms we're talking here. You could get very close to exact by playing around a little with task priority and notify... And if those weren't exact enough, set the timer for a safe buffer ahead of 2.5ms and hang out in the high priority task until it's exactly time to trigger whatever. These seem as close as possible with an RTOS and fine resolution timing.
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #5 on: August 13, 2020, 08:30:31 pm »
First, the resource:
It might seem an obvious suggestion, but did you go through Mastering the FreeRTOS™ Real Time Kernel, available at the FreeRTOS site?
It is not updated to the latest version (10.x - the book covers 8.x) but it's nonetheless a very good introduction (not only to FreeRTOS).

Then, the question:
If you only rely on the FreeRTOS tick, you can't, as you might have imagined.
The scheduling granularity goes with the tick - in general.
That said, there's a way: you can use an HW timer set to generate a periodic interrupt, and in the interrupt handler use e.g. vTaskNotifyGiveFromISR() to wake up your task, waiting on a ulTaskNotifyTake().
Note the fromISR part, that allows the API to be called from an ISR, and forces a reschedule.
If the sleeping task has a high enough priority, it will be immediately scheduled.

I'm suggesting to use a direct notification since they have much smaller overhead with respect to queues or semaphores.

This was my thought as well. Since it's an STM32, you can probably assume that you even have time to interupt, and defer processing. Depends how exact to 2.5ms we're talking here. You could get very close to exact by playing around a little with task priority and notify... And if those weren't exact enough, set the timer for a safe buffer ahead of 2.5ms and hang out in the high priority task until it's exactly time to trigger whatever. These seem as close as possible with an RTOS and fine resolution timing.

what do you mean by the safe buffer?

How would one of the dual core PSOC 6 chips play into this?  The absolute real time process could run all by itself in the M0 core.  Let FreeRTOS deal with the M4 core.

If the CPU must be a STM32 then the suggestions above should work.


Of course dual core or a FPGA could solve my problems. However, I want to utilize the single core STM32 as much as I can.
« Last Edit: August 13, 2020, 08:33:02 pm by syntax333 »
 

Offline hans

  • Super Contributor
  • ***
  • Posts: 1726
  • Country: 00
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #6 on: August 13, 2020, 08:48:16 pm »
You could change the SysTick frequency to create a 800Hz or 400Hz timebase (instead of 1kHz). Then a tick is not 1ms long, but 1.25ms or 2.5ms respectively, which is an integer multiple. Most OS'es have the systick rate as a configuration in a header file, or perhaps in the CMSIS library sometimes as well.

https://www.freertos.org/a00110.html#configTICK_RATE_HZ

You will probably still need an OS (software) timer to handle the task activation though.

You could also activate the task from a hardware timer, assuming that the OS is smart enough to directly run a context switch the moment the task is activated. I think this is the case with FreeRTOS though.
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1842
  • Country: se
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #7 on: August 13, 2020, 08:56:38 pm »
Now tggzzz has done it.  :rant:

Next time he mentions xcores I'm going to...





...check if a cheap dev board is available.  ;)
After all, they are somehow genealogically related to the Transputer, and I have never played with a real one...
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #8 on: August 13, 2020, 09:18:04 pm »
You could change the SysTick frequency to create a 800Hz or 400Hz timebase (instead of 1kHz). Then a tick is not 1ms long, but 1.25ms or 2.5ms respectively, which is an integer multiple. Most OS'es have the systick rate as a configuration in a header file, or perhaps in the CMSIS library sometimes as well.

https://www.freertos.org/a00110.html#configTICK_RATE_HZ

You will probably still need an OS (software) timer to handle the task activation though.

You could also activate the task from a hardware timer, assuming that the OS is smart enough to directly run a context switch the moment the task is activated. I think this is the case with FreeRTOS though.

I was just thinking that. So there is no problem setting the systick period fractional right? Like 1.25ms.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 22101
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #9 on: August 13, 2020, 09:28:20 pm »
Now tggzzz has done it.  :rant:

Next time he mentions xcores I'm going to...





...check if a cheap dev board is available.  ;)
After all, they are somehow genealogically related to the Transputer, and I have never played with a real one...

I have several dev boards that cost £10 each. :) Unfortunately they are now unavailable :(

It is useful to mention the xCORE devices, since the design choices unambiguously highlight the limitations of bog-standard MCUs in hard realtime applications. Understanding that cuts through a lot of wooly "I haven't seen a problem" type statements.

Do they have limitations? Of course, but they are different limitations.

I was gobsmacked at how easy they were to use, compared to other MCUs - and fun, which is all too rare nowadays.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: newbrain

Offline jnz

  • Frequent Contributor
  • **
  • Posts: 593
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #10 on: August 13, 2020, 09:38:02 pm »
what do you mean by the safe buffer?

What I was talking about was if you need ultimate accuracy, don't leave it up with FreeRTOS's notify which may or MAY NOT be perfectly deterministic.

So, set a time up to roll at 2.500ms, ISR at 2.490ms, get to your priority function with a notify or deferred ISR processing (assuming your normal loops will get you here in time), then hang out in your high priority function looping over for that time rollover at exactly 2.500ms. It's a little wasteful to kill cycles blocking in a while(polling your timer) but, if you need the ultimate in accuracy you can do this and trigger whatever highly tuned assembly commands you needed.

My guess is that pretty good will work for you, and just notify your thread from ISR.
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1842
  • Country: se
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #11 on: August 13, 2020, 10:11:00 pm »
What I was talking about was if you need ultimate accuracy, don't leave it up with FreeRTOS's notify which may or MAY NOT be perfectly deterministic.
It's not, of course, but I was honestly surprised by how little jitter I had.

I did this to collect and process buffers buffer at the end of a DMA (from I2S), with a direct notification from DMA ISR and higher-than-the-rest priority for the audio processing task (and DMA again to the I2S out).
Each frame is 2kB (512 samples × 2 channel × 16 bits), at 192 kSmpl/s, ~2.6 ms interval, time slicing is disabled.

(but yes, I'm using a 500 MHz iMX.RT... ;D).
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 22101
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #12 on: August 13, 2020, 10:18:05 pm »
Of course dual core or a FPGA could solve my problems. However, I want to utilize the single core STM32 as much as I can.

The first interesting issue here is how much you can predict without building something and sucking it and seeing. To put it another way, you can get it right by design or by inspection.[1]

If you opt for inspection, the question in a hard realtime system is what you have to do to ensure you have encountered the worst case. If a cache is effective, the worst case behaviour must be much worse than the average behaviour. Even without caches and interrupts, ensuring worst case behaviour is acceptable is a surprisingly difficult task, and many techniques have been developed, each with their own characteristics.

Obviously it is easier if the utilisation is low, but that's wasteful and boring.

[1] Old and unfashionable (but correct) engineering motto: you can't inspect quality into a product.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1842
  • Country: se
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #13 on: August 13, 2020, 10:23:29 pm »
So there is no problem setting the systick period fractional right? Like 1.25ms.
No there's not, it can be set to anything reasonable.
Do not use macro pdMS_TO_TICKS() to translate a time from ms to ticks: the way it's written will not work correctly with a non integer argument.

If you are using the HAL, the HAL tick should be moved to a separate timer (and CubeMX will do that for you, if you are using it).
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3440
  • Country: gb
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #14 on: August 14, 2020, 10:00:20 am »
You could use a hardware timer interrupt every 2.5ms and issue a task notification or semaphore to your task.  Provided you configure your task priorities appropriately this would allow you to run your task at the desired rate.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 22101
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS
« Reply #15 on: August 14, 2020, 10:50:21 am »
You could use a hardware timer interrupt every 2.5ms and issue a task notification or semaphore to your task.  Provided you configure your task priorities appropriately this would allow you to run your task at the desired rate.

... on average.

Predicting the worst case and RMS jitter magnitude is "difficult", even measuring the worst case is haphazard.

Of course there's no statement of how much jitter would be tolerable, and that in itself can be difficult to specify.

Hard realtime systems require a different mindset to soft realtime systems, let alone application-level systems.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf