FreeRTOS High Tick Rate for Machine Control?

I am writing a machine controller from scratch in order to learn how machine controllers work. The goal is to produce a machine controller similar in capablility as LinuxCNC for mid-range (80-200 MIPS) microcontrollers, because I am not quite satisfied with rigor of Smoothie or Repetier. I have a functional machine controller prototype here, using a non-preemptive RTOS I wrote myself: I want to migrate to FreeRTOS because it’s preemptive and would eliminate a lot of state machines from my source code. My machine controller generates stepper pulses in software, requiring a tick rate of around 32 KHz. There are four threads that need to run at this rate, one for the interpolators, one for the servos, one for the step pulse generator and one for the stepper chip driver. The maximum supported tick rate for FreeRTOS looks to be 1 KHz. It would greatly simplify my HAL if I didn’t have run these threads in an interrupt outside of FreeRTOS. What is the best practices sort of way to handle this? Could I use an interrupt to wake the thread (and trigger a context switch)? Thanks!

FreeRTOS High Tick Rate for Machine Control?

FreeRTOS doesn’t impose a maximum tick rate, but it is advised not to go over 1Khz if you are using time slicing, otherwise too much time will be spent switching between tasks. That advisory really depends on the CPU you are using and what your application is doing though, so don’t treat is as any more than a rule of thumb. Note however that the pdMSTOTICKS() macro will not work with a tick rate over 1KHz as we cannot represent fractions of milliseconds in an unsigned integer. pdMSTOTICKS() is only used for convenience in the demos though, it is not used in the FreeRTOS kernel itself. The answer to how to keep interrupts outside of FreeRTOS depends on the chip you are using. If you are using a Cortex-M3, M4, M4F or M7 then just keep the priority of the interrupt above configMAXSYSCALLINTERRUPT_PRIORITY – noting that you cannot call any FreeRTOS API calls from the interrupt’s service routine. https://www.freertos.org/a00110.html#kernel_priority https://www.freertos.org/RTOS-Cortex-M3-M4.html

FreeRTOS High Tick Rate for Machine Control?

It would greatly simplify my HAL if I didn’t have run these threads in an interrupt outside of FreeRTOS
I can imagine that the code will look cleaner, simpler, when you use a higher clock-tick rate. But as you will use a pre-emptive OS, isn’t it possible to have interrupts just wake-up some task? The lightest way of waking up a task is the Task-Notify mechanism. Or you may want to send some messages to a task, using the queue mechanism. So even if the system clock runs at a 1000 Hz, the actual number of switches per second can be much higher, and the response time will be far shorter that 1 ms.

FreeRTOS High Tick Rate for Machine Control?

Hein Tibosch, that’s brilliant- so let me make sure I understand. I can send a message to a task from an interrupt (triggered by a timer), essentially waking it, while keeping the Tick at 1 KHz?

FreeRTOS High Tick Rate for Machine Control?

How I do it: I have a very high interrupt rate from a timer (in fact more than one) doing a lot of things (motor control) and no task has any knowledge of that. Once it is started by a task, it runs completly in “background” only notifying some task if somethin happens or when it ends, these notifications are sent using a queue and wakeup a task that waits for an event that doesn’t happen so often. In other words: somethings are better done using timers and interrupts without FreeRTOS at all. Those interrupts can have a higher priority so that they go completely undisturbed.

FreeRTOS High Tick Rate for Machine Control?

Joshua wrote:
I can send a message to a task from an interrupt (triggered by a timer), essentially waking it, while keeping the Tick at 1 KHz?
Yes you can. This is sometimes referred to as “deferred interrupt handling”: the ISR code is kept as short as possible. The more lengthy processing is done by a task. Two things must be remembered:
  • From an ISR, you can only use API calls that end with ...FromISR()
  • The interrupt that calls an API may not have a priority higher than configMAX_SYSCALL_INTERRUPT_PRIORITY
( interrupt priorities for ARM processors: the lower the value, the higher the priority, check that out ). Alain wrote:
some things are better done using timers and interrupts without FreeRTOS at all
I think that Alain refers to Timer-Counters, that are available in every CPU. They can be programmed to issue an interrupt at any speed. Alain is describing a mix of 1) fast processing is interrupt driven and 2) waking up, notifying tasks.

FreeRTOS High Tick Rate for Machine Control?

OK thanks, I really appreciate you guys giving me some direction to go on! Going to attempt some experiments this week.