Introduction to Real-Time Operating Systems: Part 2

Call: +44 (0)23 8098 8890
E-mail:

Posted 12th October 2017, By James H
Starting line

Introduction

In the embedded world, the use of a real-time operating system (RTOS) is commonplace, and with the advent of the Internet of Things (IoT) they are becoming more so. You may be deciding to use an RTOS for the first time, or perhaps you are thinking of moving to a new one. This is the second article in our series on RTOSes to help you to get started.

The previous article talked about the basics of real-time systems and about the "spectrum" of real-time, from "soft" to "hard". This article begins to answer the questions "how do we get real-time?" and "why isn't a general OS real-time?"

Firstly remember that "real-time" is not about performance but predictability. The better question might be, why isn't my normal desktop operating system real-time?

Pre-emption

The answer to this lies in something called "pre-emption". The standard dictionary definition goes something like "pre-empt: to acquire, to replace with something considered to be of greater value or priority" [1]. This isn't far off the RTOS definition: pre-emption is the ability to take a task off the CPU at any time and schedule in another, more important task, with as little delay as possible.

What causes a lack of ability for one task to pre-empt another?

  • Lack of pre-emption support;
  • Interrupts being disabled (for long periods);
  • Locks and issues like priority inversion

This article will define & discuss the concept of pre-emption. Interrupt disabling and priority inversion will be discussed in following articles.

In the early days of Linux and Microsoft, for example, when a system call was made, as soon as the kernel code was executing, the kernel task in progress would not relinquish the processor until it had completed. This would mean that had the "car collision detect" event, talked about in the previous article, occurred whilst our MP3 player was running some filesystem API code in the kernel, we might have run someone over!

So why on earth was it designed like this in the first place, you may ask? Mostly for simplicity, but also because a desktop operating system is designed for a different purpose. To be pre-emptive a kernel has to add decision points into its code, where it can decide whether or not another task should be put on the CPU. As such, the kernel becomes more complex.

There is also more work to be done on a more frequent basis. Each time a task is pre-empted, the OS must save the task's state so that it can be restored later. Because the kernel has become more pre-emptible, this could potentially happen more often, hence a greater need for optimisation in this respect. The OS must also decide whether there are more important tasks than the one currently running. The scheduling algorithm will thus become more complex, requiring additional data structures, and checking algorithms, etc., to keep track of everything.

It must also decide if the system is in a state where pre-emption can occur. For example, if a task is holding a lock, perhaps it shouldn't be pre-empted. In this instance, the operating system is no longer completely pre-emptive. To get over this constraint, even if a task holds a lock, the OS could allow it to be pre-empted. But then how does the system account for effects like priority inversion (discussed in following articles) which could make the scheduling and other OS primitives like semaphores yet more complex to implement?

There would also be times when a process simply should not be pre-empted: for example, a process writing to an I2C device must never be interrupted by a process writing to another I2C device on the same bus. Now the driver developer needs to pay more attention to the locking primitives they are using. Do they use a pre-emptible lock or one that cannot be pre-empted? This leads to further complexity, and worse, complexity that is outside of the control of the core kernel developers. A third party driver that is written badly could still cripple a system's ability to pre-empt it by, for example, disabling pre-emption, holding a lock that cannot be pre-empted during a very long running operation, or even worse, doing the unthinkable: disabling interrupts.

So, one reason we started off with kernels that were not pre-emptible was simplicity. As hardware and software complexities grew, and the complexity of what was required of the system grew, most kernels moved towards a pre-emptible model. However, some are more so than others depending on how "fine grained" their pre-emption points are. For example, the Linux 2.6 kernel introduced more pre-emption points, but it could not be considered fully pre-emptible in the same way a true RTOS is, at least without the PREEMPT-RT patch applied:

"PREEMPT.RT reworks the kernel "spinlock" locking primitives to maximize the pre-emptible sections inside the Linux kernel. (PREEMPT.RT was originally called the Sleeping Spinlocks Patch.)"[2]

It is worth noting that the real-time aspect of Linux has been managed by the Linux Foundation since 2015, and over 80% of the patch has been now integrated directly into the mainline kernel with the remaining code being steadily maintained. 

Another reason is that there is often a trade-off to be made between throughput and responsiveness. If the system wants to focus on high throughput, it is desirable that tasks are not taken on and off the CPU too often, otherwise the OS could be spending more time and effort context switching rather than getting actual work done, thus reducing throughput. However, if tasks are not switched often enough there will be a responsiveness issue. This is another reason why your average desktop OS is not an RTOS: it is trying to accomplish a different goal.

Now we know about the basics of pre-emption, what it is and why a general OS will not be as responsive as an RTOS. The next article will talk about why disabling interrupts is also a barrier to pre-emption and general system responsiveness. It will also demonstrate how RTOSes deal with this.

To receive an update when the next blog in this series is available please follow us on LinkedIn, Facebook or Twitter.

References

  1. https://www.merriam-webster.com/dictionary/preempt
  2. E. Brown, "Real-time Linux explained, and contrasted with Xenomai and RTAI", 10 02 2017. [Online]. Available: http://linuxgizmos.com/real-time-linux-explained/.

James

Senior Software Engineer

MEng - Computer Science, University of Warwick

James has been a software engineer for ITDev since late 2016 and brings with him over a decade of software development experience, mainly in embedded systems.

He enjoys the friendly, fun and collaborative work atmosphere within ITDev.

Outside of ITDev James spends his time on mini home software projects, socialising and going to salsa lessons.

View all posts by James    |    View all ITDev team members

Latest News

Mentor - the missing piece of the puzzle.
Posted 13th November 2017
As a business, we are committed to the future of engineering in the UK. As part of this commitment, we look to engage with local universities at various levels ...more
Southampton Careers Fair
Posted 26th October 2017
Having reviewed our strategic plans we are pleased to have published our vacancies for graduates and summer internships for 2018. As a company, we invest time ...more
Photo of IBC
Posted 13th September 2017
ITDev is excited to announce that its specialist video technology division, Imicast, is presenting Imicast Impulse™ in the Ruby Lounge, between Hall 8 and Hall ...more
Cyclists
Posted 6th July 2017
The fitness, performance and health of athletes has never been of greater interest to sports fans as it is today. With the range of sports statistics currently ...more

Latest Blog Posts

Posted 26th October 2017, By James H
Even in the most expertly designed critical, real time operating systems have some “gotchas”. The most infamous is “priority inversion”. This article outlines ...more
Posted 19th October 2017, By James H
Disabling interrupts can cripple system responsiveness. This article discusses how RTOSes minimise interrupt disabling to give the best possible response time ...more
Starting line
Posted 12th October 2017, By James H
In the embedded world, the use of a real-time operating system (RTOS) is commonplace, and with the advent of the Internet of Things (IoT) they are becoming ...more
A Google self-driving car at the intersection of Junction Ave and North Rengstorff Ave in Mountain View.
Posted 4th October 2017, By James H
Critical systems must meet deadlines reliably. A driverless car must stop in time to avoid collisions, so how does it try to ensure this? This blog is the ...more