Execute task every 10 ms


I am having an issue with task delay. I have two tasks with the same priority. One task is dealing with the transmitting of CAN messages cyclically. This task updates the tick of each message object and when tick reaches cycle time, it sends the message. This task is delayed using vTaskDelay(10).
Another task has to read data from the internal ADC which will be later send through CAN. This task uses while loop to check if the conversion is complete:

while ((adcIsConversionComplete(adcREG1, adcGROUP1)) == 0);

Everything is fine when the ADC is enabled but when the ADC is disabled, MCU is stuck inside while loop. This causes some deviations in my other task that sends CAN messages. Cycle times are messed up.

Since I don’t have much experience in FreeRTOS, I would like to know how should I solve this problem. Of course, I can enable ADC and everything is fine. But, I would like that my task that sends messages is executed every 10 ms, no matter what. What is the strategy for long busy-wait loops like the one above? Should I replace it with an if and switch the context?

I thought that task will be preempted and switched to another task because task delay is used but as I see the while loop is messing execution time.

Thank you in advance :slight_smile:


Basic rule, NEVER sit in a polling loop waiting for hardware in an RTOS unless you KNOW this will be a very short wait (like sub-microsecond). You ADC routine needs to wait on a notification from an ISR that gets an interrupt when the ADC Is ready.

Agreed with Richard, interrupt driven I/O will always beat polling.

If you can’t do without polling, you could either temporarily decrease your task’s priority so that it does not interfere with other tasks or put a vTaskDelay() into the body of your polling loop. Then again, if your hardware should require fast response after the flag is set, this may not work either.

Bottom line is if your MCU does support event driven I/O notifications (usually accomplished via ISRs), use it.