Have microcontroller operating systems

Selection and use of an operating system for microcontrollers

Author: Frank Benkert, FRB Computersysteme GmbH

Contribution - Embedded Software Engineering Congress 2017

Development projects for new embedded products are usually confronted with the same, fundamental question at the beginning:With or without an operating system? If without, how then? If with, which one? Of course, there is no one-size-fits-all answer to this question. However, if you take a closer look at the requirements for the new product, the answer often arises automatically. But which facts really help in the decision? How do you get this information? What questions do you have to ask? Who can answer this? In the following, a practical project is intended to show how this selection process and the subsequent integration can be successful.

The project

A real project is used as a template for the explanations below, the aim of which was to develop a new family of devices for controlling large engines. After almost two years of development, the project came to a successful conclusion a few months ago (within the planned budget). Some versions of the devices are already running productively, others are still in the certification or approval process.

An Arm Cortex-M7 from ATMEL (automotive variant) was used as the platform. This document is intended to serve as a general basis, which is why the wording (wherever possible) does not relate directly to the project. Direct references to the development project described are in italics.

What is an operating system?

In order to be able to ask the question of "with or without" at all, it must be clear what the individual participants understand by the term operating system.

The deeper a developer works in the system, the more differentiated his view of the "thing" between hardware and application. Whichever definition you ultimately agree on, it is extremely important to have the same understanding of the term.

In the project, an agreement was reached on the formulation: "An operating system consists of a task scheduler with a connected driver architecture". The size or completeness of the "driver architecture" was not decisive.

With or without an operating system

Answering this question is a lot easier than many think. Only a few important points serve as a basis for decision-making:

  • Does the product require several concurrent execution threads (tasks)?
  • Are these tasks active (or do they only react to external events)?
  • Are there any time-critical requirements for mutual processing?

If at least one of these questions is answered with "yes", then you are well advised to at least use a scheduler.

The question of active or reactive points in the direction of interrupts. A purely reactive system can, for example, also have more than one execution thread with several interrupt routines. However, these are then (usually) sequential. Systems with "interrupt priorities" and "nested interrupts" are an exception. Such a technique can already be referred to as a pseudo-scheduler.

If you decide against a scheduler despite a "Yes", the project will with absolute certainty deliver a scheduler as output in addition to the actual product.

To answer the question about the need for a driver architecture, however, there is actually only one point:

  • Is there any hardware that should (or should) be abstracted from the application?

A "yes" means that at least one driver is required. Together with the answer to the question about the scheduler, the most basic question about "with or without" can now be answered very easily.

The project decided on the "with".

Operating system requirements

In order to later be able to make a selection between the hundreds of operating systems represented on the market, it is important to collect the requirements in a kind of matrix. The following list is intended to give an introduction to the question. Depending on the product, this must of course be extended, changed or shortened.

Is the processor core supported?

Processors now support operating systems with a large number of integrated functions. What used to have to be implemented manually in the scheduler is now done directly by the processor using just a few assembler commands. Many functions have now been integrated into the processors, from automatisms for task switching to stack management and the checking of authorizations. For this, however, it is necessary that the core of the scheduler knows and controls these special features. This is the only way to get the best performance out of the processor.

Does the scheduler support the necessary scheduler strategies?

A real-time scheduler has become an indispensable part of the development of embedded products. He has to ensure that deadlines are adhered to and that predictability is guaranteed. For its implementation, only a strictly priority-driven implementation is initially sufficient. But what if several tasks have to work on the same priority? Which of these is then preferred?

There are additional strategies for this, such as "Round Robin" or "First In, First Out". Schedulers are also available which guarantee fairness in one way or another. However, these are rarely required in embedded systems.

What granularity does the scheduler have to offer?

An embedded system must sometimes be able to make decisions or trigger actions in a microsecond grid. Depending on the desired system architecture, it is important to ask whether, for example, an external message can be processed every 2 milliseconds or an actuator value is rewritten within a deadline of 300 microseconds. If you then have a scheduler with a fixed 20ms grid, this is quick, but useless.

Are synchronization and signaling supported?

As soon as several tasks run within a system, it is inevitable that they have to share resources. Atomic mechanisms are required to synchronize access to these resources. These are usually mapped in the form of "counting semaphores" on which various other synchronization mechanisms can be built.

Does the project require interprocess communication (IPC)?

If information is processed in several tasks, it may be necessary to exchange messages between the system parts. This can be done e.g. via pipes or queues. If the product has this problem, an operating system candidate should also be tested against this requirement.

Does the system include support for MMUs?

More and more embedded systems are equipped with memory management units (MMUs). Depending on the size of the system, these MMUs contain a different number of functions - from simple cache management (which memory area is mapped by the CPU cache?) To access control to complex mapping tasks within a virtual address space. Depending on the requirements of the product and the hardware conditions, this represents a helpful function of the operating system.

Does the system include support for storage management?

The standard interfaces for dynamic memory allocation are well known to every programmer: "malloc" and "free". However, behind this very simple interface there are complex strategies, e.g. to reduce memory fragmentation. If the product requires such a function, it is important to find tried and tested mechanisms for this in the operating system.

Support for peripherals and interfaces

Even if the connection of peripherals is often already provided by the manufacturer as a reference implementation, it still saves a lot of work if a similar module or the required interface already exists as a ready-made driver for precisely this operating system. Preferably, of course, it is already "hung up" and tested, but at least with a set of test functions that can be processed on your own hardware.

Support IDE and debugging

It is irrelevant whether an operating system is supplied with its own "full featured IDE", in which the compiler is already integrated, or whether you can assemble the components yourself. When evaluating this point, it is important that a closed cycle is possible from programming in a comfortable editor to compilation and application of the compilation to the target to debugging at line level. The latter can of course only be achieved with some products using emulators. If in doubt, these options should be tested before deciding on a solution.

Is the source code of the operating system available?

On embedded systems, the dovetailing between application, drivers and scheduler is naturally very close. This often means that external functions have to be run through during debugging for a better understanding. Many commercial providers therefore grant limited insight into their source codes under certain contractual conditions in order to support this procedure. Naturally, this question does not arise with open source systems.

Which license is the operating system subject to?

A question that worries not only the technicians, but also those responsible for the product. As many licensing models as there are in the open source world, there are just as many in the world of commercial products. What exactly which license means must be checked in detail on the respective product. For example, a commercial license per development site for distributed teams is just as harmful as a license that requires the author to be named in the manual for a product without customer documentation.

Support and Community

Often neglected, but still important, is the question of the community. Even the manufacturer's commercial support can hardly replace a lively discussion group on the Internet. A place where questions are answered unbureaucratically, code snippets are posted or errors are reported is often worth more than a support contract. For some time now, commercial providers have also started hosting mailing lists in which both users and support staff can exchange information.

In addition to this general list, many other aspects played a role in the real project, e.g. support for the I2C, SPI, QSPI and USB interfaces, as well as file systems and fieldbuses. Furthermore, soft factors such as future security, license risk, testability and training effort were included in the evaluation.

Selection process

The selection process should be limited to a few promising candidates. In addition to (unfortunately often outdated) lists from the Internet and information from the providers, e.g. experiences of developers involved can also serve as an aid for preselection. The selection process itself is not as trivial as one might think, which is why it is good to sift through as few alternatives as possible. It is advisable to accept a maximum of five applicants.

Contrary to what was assumed, the process does not simply consist of ticking features, but primarily researching existing documentation on the Internet as well as inquiries to support. Whether the feature XY mentioned in the hit list is actually the required X and Y together or whether the manufacturer only understands this as a subset is often difficult to understand and requires extensive research.

A reasonable deadline should be set for the selection process. It is easy to get bogged down when analyzing features. It is also advisable to allow "very likely" or "to XX percent" as answers in addition to yes and no in order to save time.

If the evaluation matrix is ​​almost complete, further parameters are added depending on the answer to the feature questions:

  • What effort is incurred due to insufficient / non-existent support of a feature?
  • What is the risk of uncertainty as to whether a feature is (only partially) supported?
  • What is the risk of a lack of support or a missing or only very small community?

After a selection process lasting several weeks, in which many aspects had to be evaluated not only through documentation and support inquiries, but also through tests, the project decided on the open source operating system NuttX [1].

What is NuttX [1] - and why this decision?

In short, NuttX is a real-time operating system with a POSIX-compatible driver and interface architecture under a BSD license. It was first published by Gregory Nutt in 2007 and has been actively developed under his leadership ever since. Since NuttX is under a BSD license, no user has to announce (except in his manual) that he is using NuttX. So it was very quiet around the system for a long time. Few publications referred to the system, such as the open hardware project PX4 [2] - a (quadrocoper) autopilot hardware in cooperation with the ETH Zurich.

However, the number of processor types supported shows that there was much more interest than public perception suggested. This list currently includes over 150 processor families from ARM to ZiLOG Z80. Plus a Linux / Cygwin simulation platform.

The decision in favor of NuttX was extremely close in the project, as not all of the functions and features required by the project were integrated at the time. Now they are - by upstreaming the source code.

The download figures [3] on the NuttX homepage show that Europe only ranks third behind China and the USA. That may also be one reason why we have so far heard so little from NuttX in Europe. In recent years, however, the interest in NuttX has grown, which can be seen, for example, from the increasing number of posts on the mailing list. Furthermore, the LinkedIn group, which was only launched this year, now has over 1000 users. Companies are now also publicly committed to NuttX. E.g. at the beginning of the year the company SONY brought a family of digital voice recorders (e.g. ICD-SX2000) onto the market and published their further developments to NuttX in connection with these products for reintegration into the mainline under their company name.

We can be curious to see how the growth will continue.


In addition to many "normal" features, NuttX also offers highlights that make it stand out from the crowd of embedded systems.

C ++ 11 support

While the rudimentary C ++ support had been provided for several years via µClibC ++, in 2016 the C ++ 11 compatible "libc ++" from the LLVM project was integrated.

"Is like Linux"

The programming of NuttX hardly differs from that of Linux - from "pthreads" to "everything is a file" within a virtual file system to a shell that can be accessed via the serial interface.

Diagnostic commands such as "free" or "ps" can be activated in the same way as "dd" or "hexdump".

This means that the training effort for programmers of (usually larger) embedded Linux systems is very low. Existing source codes from your own function libraries can also be transferred almost seamlessly to NuttX.

Tickless scheduler

Standard schedulers use the cyclical cycle of a timer module to handle their scheduler processing. With each tick, a function is jumped to, which takes care of the administration of the tasks. As a result, a very high interrupt load occurs from a certain frequency (tick speed), which particularly affects embedded systems. NuttX offers the "Tickless Scheduler" feature, in which the scheduler calculates when it has to carry out the next action and programs the timer module (quasi as a dynamic alarm clock) for this point in time. This enables higher accuracies at a lower frequency and thus a lower interrupt load.

Dynamic composite USB device

NuttX not only offers host USB drivers, but also device USB. A fairly new feature is the composite USB device that can be configured at runtime. With this it is possible, for example, to activate additional serial interfaces for maintenance mode or debugging within a composite device, which are not active in the standard settings.

Visual Studio with VisualGDB [4] as IDE

Since NuttX is open source, the task management can be viewed in its entirety. Configurable debugger plugins can read out the task structures and stack frames accordingly and thus enable convenient debugging.

An Atmel Cortex-M7 processor was used in the project. The connection to the hardware debugger was made via the SWD interface. The processing of the information was implemented via a debugger plug-in, so that the display in Visual Studio could not be distinguished from the debugging of a local (Windows) process.


Selecting an operating system for a microcontroller is a complex process and should not be underestimated. For projects that run for months or years, it is essential to invest a considerable amount of time in the evaluation of various systems.

Looking back, the decision was made for the development project for NuttX correct, even if (as already stated) the facts were not entirely clear.


[1] http://www.nuttx.org/

[2] https://pixhawk.org/

[3] unfortunately only available until 2015

[4] https://visualgdb.com/

Download the article as a PDF file

Real-time - MicroConsult training & coaching

Do you want to bring yourself up to date with the latest technology?

Then find out more herefor courses / seminars / trainings / workshops and individual coaching from MircoConsult on the subject of embedded and real-time software development.

Training & coaching on other topics in our portfolios can be found here.

Real-time expertise

Valuable specialist knowledge on the subject of embedded and real-time software development is available hereready for you to download free of charge.

To the specialist information

You can find specialist knowledge on other topics in our portfolios here.