running a Task every 2.5ms with 1ms Tick Timer with FreeRTOS - Page 1
Forum section: electronics / general

author: syntax333
author_rank: Regular Contributor
timestamp: August 13, 2020, 06:17:30 pm
content: 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?

author: newbrain
author_rank: Super Contributor
timestamp: August 13, 2020, 07:17:36 pm
content: First, the resource:It might seem an obvious suggestion, but did you go throughMastering 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 aulTaskNotifyTake().Note thefromISRpart, 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.

author: tggzzz
author_rank: Super Contributor
timestamp: August 13, 2020, 07:36:20 pm
content: 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.

author: rstofer
author_rank: Super Contributor
timestamp: August 13, 2020, 07:57:45 pm
content: 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.

author: jnz
author_rank: Frequent Contributor
timestamp: August 13, 2020, 08:10:41 pm
content: Quote from: newbrain on August 13, 2020, 07:17:36 pmThis 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.

author: syntax333
author_rank: Regular Contributor
timestamp: August 13, 2020, 08:30:31 pm
content: Quote from: jnz on August 13, 2020, 08:10:41 pmwhat do you mean by the safe buffer?Quote from: rstofer on August 13, 2020, 07:57:45 pmOf course dual core or a FPGA could solve my problems. However, I want to utilize the single core STM32 as much as I can.

author: hans
author_rank: Super Contributor
timestamp: August 13, 2020, 08:48:16 pm
content: 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_HZYou 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.

author: newbrain
author_rank: Super Contributor
timestamp: August 13, 2020, 08:56:38 pm
content: Now tggzzz has done it.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 neverplayed with a real one...

author: syntax333
author_rank: Regular Contributor
timestamp: August 13, 2020, 09:18:04 pm
content: Quote from: hans on August 13, 2020, 08:48:16 pmI was just thinking that. So there is no problem setting the systick period fractional right? Like 1.25ms.

author: tggzzz
author_rank: Super Contributor
timestamp: August 13, 2020, 09:28:20 pm
content: Quote from: newbrain on August 13, 2020, 08:56:38 pmI have several dev boards that cost £10 each.Unfortunately they are now unavailableIt 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.

author: jnz
author_rank: Frequent Contributor
timestamp: August 13, 2020, 09:38:02 pm
content: Quote from: syntax333 on August 13, 2020, 08:30:31 pmWhat 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.

author: newbrain
author_rank: Super Contributor
timestamp: August 13, 2020, 10:11:00 pm
content: Quote from: jnz on August 13, 2020, 09:38:02 pmIt'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...).

author: tggzzz
author_rank: Super Contributor
timestamp: August 13, 2020, 10:18:05 pm
content: Quote from: syntax333 on August 13, 2020, 08:30:31 pmThe first interesting issue here is how much you can predictwithoutbuilding something and sucking it and seeing. To put it another way, you can get it right by design or by inspection.If you opt for inspection, the question in ahardrealtime 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 easierif the utilisation is low, but that's wasteful and boring. Old and unfashionable (but correct) engineering motto: you can't inspect quality into a product.

author: newbrain
author_rank: Super Contributor
timestamp: August 13, 2020, 10:23:29 pm
content: Quote from: syntax333 on August 13, 2020, 09:18:04 pmNo 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).

author: mikerj
author_rank: Super Contributor
timestamp: August 14, 2020, 10:00:20 am
content: 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.

author: tggzzz
author_rank: Super Contributor
timestamp: August 14, 2020, 10:50:21 am
content: Quote from: mikerj on August 14, 2020, 10:00:20 am... 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.