So I see no other option than to do a std::this_thread::sleep_for instead of the yield(). However, times less than 1 ms result in the same behavior as the yield() call as I also wrote above. I take it this is due to the scheduler never getting around to starting the lower priority tasks?
Is there a way that I can calculate the minimum time a high priority task must sleep to guarantee lower priority tasks gets a chance to run, preferably at compile time? There's the setting for the tick frequency in FreeRTOS (CONFIG_FREERTOS_HZ). It's currently set att 1000Hz, so 1ms ticks - coincidence? Also, it is currently limited to max 1000Hz, is there a reason for that or could it be increased further?
You're right this is not a coincidence. The scheduler works in ticks as its timebase, so when a task is delayed it must be for an integer number of ticks.
Delaying for less than the tick length rounds down to delaying for zero ticks and becomes the same as a yield.
The tick length is limited to 1000Hz for two reasons:
- A lot of code converts (integer) milliseconds to ticks by dividing by "ms per tick", which doesn't cleanly work for fractional values of ticks per ms.
- Scheduler tick interrupts take some amount of CPU time to process, and having more than 1000 of them per second starts to get up to a sizeable overhead just processing ticks.
Would second Ivan's recommendation of a loopback "event" socket, if you're able to refactor to use one. Or you might be interested in the asio C++ library
, for which support was recently added on the IDF master branch.