Sign Up Sign In

When to use RTOS?


When should I consider using RTOS in my application? Every microcontroller has a good number of interrupts then what is the need of it?

Why should this post be closed?

1 comment

This is quite opinion-based. Basically, you may benefit from a RTOS if you have numerous different, complex processes that happen simultaneously. We are talking mid- to high end microcontrollers where you are well beyond 50kb program space and probably beyond 100k LoC. Or when you find yourself constructing your own scheduler abstraction layer, basically a simplistic OS but without separate stacks per process. Where to draw the line exactly is a subjective program design decision. Lundin 5 days ago

1 answer



A RTOS (Real Time Operating System) is much more than a bunch of interrupts. Most true dedicated microcontroller applications don't need any RTOS or any other kind of operating system.

General OS (operating system)

An OS adds a layer of abstraction between your application and the hardware. That's useful on large systems that run many processes and threads, handle lots of asynchronous events, have to assume processes are hostile, etc. Operating systems provide services like presenting large mass storage as a file system, processes, threads, virtual memory, procedural interfaces to common communications means, and more.

On small micros performing dedicated tasks, the services an OS provides are usually not necessary, and the abstraction layer is serious overhead. A dedicated controller runs fixed code. You don't want flexibility of loading other programs, automatically going out on the net to check the time, see what other nodes are on the LAN, etc. You don't have mass storage, a screen, a keyboard, mouse, etc. The system is in a "black box", and has to do one thing reliably every time, all the time.

Real Time

One common problem with arbitrary operating systems in embedded applications is that timing becomes unpredictable. I've seen cases where a Windows program stops responding for a few 100 ms at a time when the mouse was wiggled the right way. That would be really bad if the program's job was to update a control output every 1 ms.

In some cases of larger embedded systems, some OS features were desired, but hard timing was still important. This is what an RTOS addresses. It has means to guarantee tasks are run on hard schedules, as long as overall processor resources are not exceeded.

Cooperative tasking

A full RTOS is usually overkill for true embedded control applications that run on microcontrollers. The most I've done in such cases is used a cooperative task manager. Various tasks are simplified if they can be coded as infinite loops. A task scheduler allows multiple apparent infinite loops on one processor.

A good example where an infinite loop is useful is processing an incoming communication stream. The loop gets the next input, processes it, and goes back to get the next input again. This presents the abstraction of going and getting input, when in reality the input comes at you. The call that gets the next piece of input data appears to be blocking (it waits indefinitely for the new input to be available), but actually calls TASK_YIELD in a loop checking for the new input.

TASK_YIELD is part of the task manager. It saves the state of the current task, loads the state of the next task, and runs it. That task eventually calls TASK_YIELD, which runs the next task, etc. In this scheme, tasks have to explicitly let other tasks run by calling TASK_YIELD. That is why this method is called cooperative task management.

I wouldn't call just a task manager an RTOS, but it's as far towards an RTOS that I've ever used in a real dedicated controller application on a microcontroller.

Cooperative task manager code

I do frequently use a cooperative tasks on Microchip dsPIC controllers. To see the application interface, look at the comments in qqq_task.ins.dspic in the Git repository That file is meant to be copied into a project and customized. The actual code is in task.ins.dspic, which is included from the template file.

You won't be able to build these without using other parts of my PIC development environment (too much to get into here), but you can see how the code works. Note that this code is written in assembler. You really don't want a compiler in there making assumptions when you're performing unnatural acts on the stack.

Similar code for the PIC18 family is at