For small MCUs an RTOS may be an unbearable burden and can’t be used. State machines and similar methods can work well. Even when an RTOS fits, using it is often entails some customization. Whether an RTOS is an appropriate solution for a microcontroller depends on many factors. The first thing most people ask about an RTOS is the code and memory footprint. In a recent survey made by EETimes, source code availability was one of the top requirements for engineers selecting an RTOS. A few reasons for this are obvious:
- Find and resolve bugs faster – a closed source RTOS means finding bugs will be done via disassembly, a very difficult approach. Fixing it is very difficult in that case and usually requires a new release from the vendor. With the source code, bugs can be found more quickly and fixed by the developer.
- Documentation – API manuals from RTOS vendors can be often lacking. The source code is the best documentation. The actual way a certain a parameter is used can’t be disputed.
- Customization – With the source code, parameters and configuration can be changed and recompiled, meaning you can remove parts of the OS that you don’t need. Even better, you may be able to do something better than the OS designer. One engineer improved the event latency in an RTOS, making interrupt processing much faster. Doing so without source code is practically impossible.
The last bullet is critical. The size of an RTOS is composed of a static cost of the Task Control Block, as well as a dynamic cost that depends on the number of tasks and objects (queues, semaphores, mutexes, etc). Reducing the footprint of an RTOS involves an intimate understanding of the RTOS and the space allocated to these elements, as well as an understanding of the CPU. The source code makes this much easier to do.
On a recent customer project we used FreeRTOS on a microcontroller. It fit well and the source code is readily available. But as more and more features were added, the amount of RAM needed to buffer data meant we ran out of RAM. Since this data size is fixed, the only thing we could do without sacrificing our data depth was to optimize the RTOS and reduce its memory size. This meant understanding how many bytes are allocated to each task, especially the stack. Optimizing a task’s stack is not a trivial affair. Reduce it too much and you risk getting a stack overflow. This might not show up until it’s too late.
There’s no alternative to understanding the details of an RTOS in microcontrollers. Abstraction works well when resources such as memory or Flash are plentiful. But in most cases, knowing what is happening under the hood can make the difference between a working system and one that sacrificed features that are needed to sell the product.