5 Tips for Creating an RTOS Abstraction Layer (OSAL)

An operating system abstraction layer (OSAL) can remove dependencies on a real-time operating system (RTOS). Here's how to create an RTOS Abstraction Layer for your embedded applications.

Jacob Beningo

October 27, 2023

5 Min Read
operating-system-abstraction-layer-GettyImages-1130990010.jpg
Guillaume/iStock/Getty Images Plus via Getty Images

Electronic products that use a microcontroller have become so complex today that they commonly use a real-time operating system (RTOS). An RTOS can manage low-level resources and time, improving the real-time performance of the system and simplifying the application.

A problem that teams might encounter is that there are more than 100 different RTOSs available to select from! It’s not uncommon for a team to start with one only to decide 6 months later that they really should be using a different one. When this occurs, developers must go back and change a lot of code if they’ve directly used the RTOS in their application.

An alternative approach is to use an operating system abstraction layer (OSAL). An OSAL creates a set of APIs corresponding to common features in every RTOS. An OSAL allows the application to break the dependencies on the RTOS by moving them to the abstraction layer. The application no longer cares about the RTOS you use, just the abstraction.

In today’s post, we will explore five tips for creating an RTOS Abstraction Layer for your embedded applications.

Tip #1: Standardize Your Operating System Abstraction Layer (OSAL) APIs Across OSs

The goal of an OSAL is not to reduce an RTOS to its least common denominator. Instead, the goal is to make the common parts available through a single standard API to remove dependencies on the RTOS and improve testing and portability. You’ll need to examine popular RTOSs and identify common features.

For example, if you were to look at popular RTOSs like FreeRTOS, Azure RTOS, and Zephyr, you might find they have standard features like:

  • Thread creation

  • Semaphore creation, getting, and putting

  • Mutex creation, locking, and unlocking

  • Etc.

You want to identify these standard features and then create an interface that can encapsulate the creation details for any RTOS you might use while decoupling the application from the RTOS.

Tip #2: Choose the Right Abstraction Level

When you start to develop an OSAL for your application, it can be tempting to create the ultimate abstraction. Don’t get caught up in this trap! Every RTOS has unique features you’ll want to leverage, and if you cordon them off, you’ll be causing more problems than you are doing good. You have to pick the right level of abstraction.

The right level of abstraction is going to be an essential standard feature. A good example is to examine the CMSIS RTOSv2 OSAL. You’ll notice that the only features they’ve abstracted are the standard features. You don’t see them implementing custom low-power settings or anything like that. Instead, they are looking to abstract standard features that every RTOS provides.

Tip #3: Use Wrappers for OS-Specific Features

Once you have your common APIs, you might be tempted to think that you’ve reduced the RTOS to its common features and that you’ll only use those features. That is not accurate thinking. As I mentioned, there will be uncommon features that may be useful to your application. The problem is that if you directly call these features, you’ll be tightly coupling your application to RTOS, which is precisely what we are trying to avoid!

The solution to using RTOS-specific features is to wrap these features. You may have an OSAL covering common features, but you’ll end up with wrappers covering RTOS-specific features as well. The wrappers will give the application access to custom features while maintaining a dependency tree that allows off-target testing and simulation.

You can’t ignore the RTOS differentiators, but you also can’t abstract them. That’s why the use of a wrapper is a good alternative. If you change RTOSs, if the new RTOS doesn’t have the feature, you can remove the wrapper and write whatever gap code is needed to cover the missing functionality.

Tip #4: Handle OS-Specific Limitations Gracefully

When you are developing an OSAL, you’ll need to realize that there will be limitations that you must manage. For example, one RTOS may have a maximum number of threads that is different than another. How priorities are ordered may differ from one RTOS to the next. (FreeRTOS tasks have higher priorities as the value of a number gets further from 0. ThreadX sets 0 has the highest priority, and the higher the number, the lower the priority!)

You’ll need to ensure that your abstraction layer can successfully manage these differences without affecting the performance of your application. You’ll also want to ensure you don’t end up with system crashes or errors caused by these minor differences in RTOS implementation.

Tip #5: Leverage a Unit Test Harness to Verify Implementation

One of the best practices you can adopt when writing your own OSAL is to use Test-Driven Development (TDD). Part of TDD will be that you write your test case, make it fail, and then make it pass. What does this have to do with an OSAL? If you write test cases to verify your OSAL, then when you connect an RTOS to your OSAL, you can verify that it was done correctly and successfully!

If you make an implementation mistake, the unit tests should catch it! You’ll know immediately that you have a problem and can go about fixing it before it becomes a bug waiting to bite you. It certainly is a little bit more work to do it this way, but you’ll find at the end of the day that you’ll end up with a much more robust OSAL.

Conclusions

All applications don’t need to have an OSAL for their RTOS. However, if you are developing an application framework or platform that will be used for five years or more, it’s a good idea to have one. Embedded technology changes rapidly, and you want to ensure you aren’t designing a framework around software that may change or not exist in five years. Reworking software can be time consuming and introduce bugs. Using an OSAL can ensure that you break that dependency and can drop in any RTOS behind the abstraction.

About the Author(s)

Jacob Beningo

Jacob Beningo is an embedded software consultant who currently works with clients in more than a dozen countries to dramatically transform their businesses by improving product quality, cost and time to market. He has published more than 300 articles on embedded software development techniques, has published several books, is a sought-after speaker and technical trainer and holds three degrees which include a Masters of Engineering from the University of Michigan.

Sign up for the Design News Daily newsletter.

You May Also Like