It is critical to address these items to successfully exploit the benefits of using a real-time operating system (RTOS) in embedded applications.

Jacob Beningo

March 15, 2021

5 Min Read
AdobeStock_RTOS.jpeg
Adobe Stock

Real-time operating systems (RTOS) are now included in many embedded applications. They can dramatically simplify time and task management in a system and help improve scalability and maintainability (if the application is designed correctly).

I’ve found that there are several common challenges that face RTOS application developers. Let’s examine these challenges and discuss a few potential solutions.  

Challenge #1 – Selecting Task Priorities

Strangely enough, the most common challenge I see and am asked about is a fairly fundamental one; how to select the right priorities for tasks. It turns out that there are several different ways to select task priority. First, there is the shortest response time.

In this method, a developer examines the response time requirements for each task and assigns the highest priority to the task with the shortest response time requirement.

Next, there is the shortest job first method. In this method, a developer examines the execution times for the tasks and the task that has the shortest execution time is the highest priority (obviously followed by the next highest and so forth).

Finally, there is the method that is used most often in real-time embedded systems, shortest period first or more commonly "rate monotonic scheduling (RMS)." In this method, the task with the shortest period has the highest priority.

Related:3 Mistakes Businesses Make During a Crisis

Following RMS will get you 95 percent of the way there and then there is usually an oddball task or so that is aperiodic that needs a priority assignment. These aperiodic tasks can either be assigned a worst-case period or they can be assigned based on their importance, execution time, or whether it needs to run prior to another task that may need its data. (Remember, there is no right or wrong answer to task priorities, just systems that may run better or be more efficient than others).

Challenge #2 – Seeing the Big Picture with a Dataflow Diagram

While consulting and mentoring development teams, I often encounter developers who are implementing their RTOS application without really understanding where data is being produced, where it is going, and how it is getting there. As you can imagine, this results in software that is a bit spaghetti code-like and often requires constant rework as more application pieces are put in place. The way to minimize this rework and understand the whole application is to develop a simple data flow diagram. This diagram contains several key components:

  • The data producers

  • The data consumers

  • Data transfer mechanisms

  • Storage mechanisms

  • Task coordination mechanisms

Related:3 Keys to Engineering Success

For example, below is a simple data flow diagram for a smart thermostat:

Beningo RTOS Picture1.png

This diagram provides a developer will an understanding of the data flow but also the major RTOS components that are required for the application:

  • Tasks (in gray)

  • Shared memory resources (green)

  • RTOS mechanisms (in blue: queues (q), mutexes (m), semaphores (s), etc)

  • Input and output devices (dark blue)

Having this dataflow diagram can answer many questions about the application design and prevent a lot of time from being wasted reworking the implementation or debugging.

Challenge #3 – Properly Protecting Shared Memory

In the previous section, I pointed out that the section in green is a shared memory region. This memory region is accessed by both the Process Inputs task and the Application task.

A mutex is used to protect the shared memory resource but in the implementation, I often see developers create the mutex separately from the data that is being protected. While this may seem okay at first glance, the problem is that if the mutex is created separate from the data structure, and someone goes to use the data structure, they may not realize that it is a shared and protected resource. (Yes documentation, design, and many other things should make this obvious, but if it is declared separately it is so easy to overlook).

The solution is to look at shared memory as an object and include the mutex as part of the data structure for the shared memory. For example, the shared memory may have data from humidity, temperature, and current sensors. We might normally declare the structure for the data as follows:

typedef struct

{

    uint16_t Humidity;

    uint16_t Temperature;

    uint16_t Current;

}SensorData_t;

Again, the mutex declared separately may make it less obvious that the data would be shared. Instead, we can define the structure as follows:

typedef struct

{

    mutex_t SensorDataMutex;

    uint16_t Humidity;

    uint16_t Temperature;

    uint16_t Current;

}SensorData_t

Now every time a developer looks at the data structure, tries to do an autocomplete and so forth, they are reminded that this is protected data. When they see it is protected, it should remind them that before they access the data, they need to acquire the mutex.

Developers often forget that just because a mutex is created to protect data, there are no assurances that the mutex will be used to access the data. (This is also why it can be useful to view the data structure as an object and create functions that limit access and control to the data resource that abstracts out the mutex at the application level).

Conclusions

Real-time operating systems can simplify the time and resource management of embedded systems. Unfortunately, the RTOS does add complexity to the system that can create unexpected challenges that affect development schedules and code quality. In today’s post, we have examined several common challenges that developers often encounter and that I often see when working with development teams. As we have seen, these challenges can be overcome quite easily by following a few best practices.

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 200 articles on embedded software development techniques, is a sought-after speaker and technical trainer, and holds three degrees which include a Master of Engineering from the University of Michigan. Feel free to contact him at [email protected], at his website www.beningo.com, and sign-up for his monthly Embedded Bytes Newsletter.

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