I have a 10kHz motor control task that needs to have sub-microsecond latency (it is synchronized with a PWM waveform). The forum gods tell me that this is too fast to be a FreeRTOS “task”, and should instead be computation done directly in the ISR.
However, I have another task (lets call it hi_prio_task) that needs to run immediately “in lockstep” with the 10kHz ISR (e.g. every third 10kHz ISR should immediately trigger the task to run on exit from the ISR). The hi_prio_task produces data for the ISR to consume (new motor control setpoints), as well as act upon the ISR outputs (motor control outputs are used as inputs to a slower control loop, made available for query over a network, used for fault checks, etc.). The compute time for the hi_prio_task is not small enough to fit into a 100us window, but should not overflow the 300us window if it runs every 3 motor contol ISRs.
Is it appropriate for the motor control ISR to be at a higher priority than FreeRTOS such that it can never be delayed?
It seems that the answer is “yes, but you can’t use any FreeRTOS APIs”. This makes getting data into and out of the ISR a bit difficult, but I have some thread-safe abstractions available to do so if needed (atomic double buffer)
I have seen it suggested that in scenarios like this, you should do the fast computation in the ISR (motor control), and then unblock a higher priority FreeRTOS task to consume the outputs of said computation.
But how is this possible if I can’t use any FreeRTOS APIs in the motor control ISR? Isn’t the act of unblocking a task an API call? Is there any other way to unblock a task from an ISR at a priority level such that it can’t be delayed by internal operations?
Ideally, I would want to use two stream buffers (to/from ISR versions) to manage getting setpoints and results in/out of the ISR, and then unblock the hi_prio_task every third ISR to drain/populate the stream buffers for the next cycle.
Can FreeRTOS support a use case like this?
Any and all help greatly appreciated.
Edit: This is using the NXP MIMXRT1051xxx port (cortex M7)