One of my projects seem to be quite complex from the beginning, so I decided to finally learn about real-time operating systems (RTOS) in use on microcontrollers. I have selected FreeRTOS as a candidate, for it is openly licensed (MIT) and widely popular with quite a few examples and support available. In this series of articles you are welcome to follow on this journey with me.
When dealing with general-purpose computers, such as PCs, we are used to having an operating system, which performs all kinds of magic in the background - displays data on screen, reads mouse movements and key presses, reads and writes data to the hard drive and network and a whole lot of other stuff. It does all of this seemingly flawlessly in parallel, even if all we have is a single-core processor. Operating system (OS) is what enables this seeming parallelism, by using tasks or threads (terminology is somewhat fuzzy on this matter, each engineering discipline calls it somewhat differently).
So, what OS does, is it organizes resource sharing between different tasks. Resources might include, but are not limited to CPU cycles, disk access, network access and such. It does so primarily by splitting all the available processor time into chunks, which get allocated to tasks according to their priority so that each of the tasks get to use CPU for some time, before suspending and allowing some other task to use it:
|Multitasking (Source: FreeRTOS docs)|
Simplest embedded projects usually do not use an OS, because they are intended to do one thing, say, measure temperature, send it away and go back to sleep until next measurement is required. Waking is done either on timer interrupt or external signal interrupt. So, embedded systems use interrupts extensively, for they allow simplified task entry/exit control.
Although easy to write and easy to understand in its simplest form, an interrupt-driven application can get convoluted pretty quickly, if a couple other requirements are introduced. Say, your application is done measuring temperature, and while sending it away (which we'll assume is a relatively slow process), it gets an external request to do something else urgently. As a developer, you could either delay execution of the new urgent task until sending is done or stop sending and get to the new task right away and just live with the lost data. Or you could start to deal with storing the data for later sending, cleaning up, freeing used resources, performing the new task and then restoring the state as it was before the interrupt.
As we add more and more interrupts to the pile, it gets harder and harder to follow the process - what is being done when and why. OS with its parallelism is intended to help with that, for it allows temporary suspending of running task and performing other actions instead with following resume of suspended task, once CPU is available for grabs.
Another issue are interdependent processes. Or, rather, processes which share the same data for whatever purpose. One has to prepare the data, process it and then send it away. If any of the previous steps fails, the whole thing has to be aborted or restarted. This adds an extra net of asserts and program flow logic, which sometimes is hard to follow. OS instead allows for multiple sleeping tasks, which just wait for their turn at the data and CPU time. Each of them can have data from the same source, but from different measurements. OS provides a messaging system between tasks, which put data on queue for other tasks to deal with. Queues can contain multiple sets of data and one set can be in processing, while other is still being collected and third set being sent away.
In following articles I'll document all my learning process step by step, from setup to advanced features. I'll use STM32F4 series microcontroller (particularly STM32F429I on a Discovery board) just because I have the dev-board and some degree of experience with it.
To get started on FreeRTOS concepts there is a wonderful PDF book available on their website, which explains both the basics and advanced features.