Even in high level code this isn't a necessity. I wrote a simulation engine for processing blocks and since I have almost no experience in writing threads or callback function or using interrupts on a PC, I simply wrote a scheduler that did a round robin call for each block. The block processed one chunk of input and produced one chunk of output, if it could (it might not have the input needed or it might have no place to put the output because the bridging FIFOs might be full). If it couldn't, it returned without doing anything. If it could, it processed just the one chunk, no matter how much data was available, and returned.I said: RTOS or interrupt driven task switcher for asynchronous code execution (a timer callback for example) for main task events.
https://www.bisque.com/products/orc...COM/Synchronous_vs_Asynchronous_Execution.htm
This is nothing more than cooperative multitasking. The key to cooperative multitasking is that each task has to play nice. It can either be designed so that it does just a small amount of work and returns, or it can abide by a time limit set either globally or told to it by the scheduler and it agrees to return control when the time expires. The big thing it can't do is block waiting for some resource that will now never become available because the only process running -- in the case of MCU code running without an OS -- has blocked.
