What to Consider When Using RTOS?

Follow “Embedded Miscellany” and select “Star the Official Account” to progress together!

What to Consider When Using RTOS?

Source | CSDN

For many embedded projects, system designers tend to choose a Real-Time Operating System (RTOS). But is an RTOS always necessary? The answer depends on the specific application, so understanding what goals we aim to achieve is key to determining whether an RTOS is essential or merely decorative.

Generally speaking, an RTOS can be adopted in any scenario where a non-real-time operating system (non-RTOS) is used. However, finding an RTOS with a fully matching Application Programming Interface (API) is quite challenging. Therefore, many traditional operating systems (OS) have embedded an RTOS within them. For example, Lynux-Works LynxOS and Bluecat Linux share a Linux API. LynxOS is a hard RTOS, while Bluecat is a derivative of Linux.

Linux continues to work on improving its real-time performance, but its longest interrupt latency still fails to meet the hard real-time requirements that are crucial for an RTOS. These issues ultimately boil down to Quality of Service (QoS). Platforms like RTLinux Free supplement Linux because they can provide hard real-time levels of QoS.

It is important to note that such supplements often integrate an RTOS programming environment into the original OS. Compared to traditional desktop or server OS, RTOS is usually much smaller. RTOS is often designed for smaller and resource-constrained MCUs. For example, CMX’s CMX-RTX and CMX-Tiny+ can run on 8-bit MCUs to 64-bit processors.

Core of RTOS: Scheduling and Partitioning

Most programmers are not familiar with the limitations and requirements of RTOS. Most choose RTOS for its performance. Most RTOS products have less code and faster speeds, and now RTOS has also improved consistency. RTOS not only completes tasks quickly but also ensures they are done well.

In many applications, a delayed result can be catastrophic. Therefore, people prefer to obtain poorer results within a required deadline. These applications are often referred to as hard real-time systems. Hard real-time does not refer to how fast a system responds or how quickly a system can respond, but rather how reliably the system can meet specific requirements.

A hard real-time system may have a fixed cycle time of one minute, requiring a response time of one second. Theoretically, such requirements can be met by almost any operating system. But this is not always the case, as anyone can attest to how long it takes for a desktop application to respond within a minute.

Hard real-time systems typically have shorter cycle times and stricter response requirements. Faster processor speeds are always helpful, and multi-core platforms can also improve response times. The trick for developers is to match system requirements with hardware and software, and then the importance of RTOS in embedded applications becomes clear.

An RTOS can implement a range of scheduling strategies, but applications often constrain a programmer’s choices (see table). The implementation of non-preemptive scheduling is not critical but can be useful in some applications. On the other hand, non-preemptive scheduling within tasks can be implemented on top of preemptive systems.

Non-preemptive scheduling should not be overlooked, especially with the emergence of new multi-core processors. Here, hardware can be adjusted to handle event-based operations, where threads will wait for external events to occur. This approach is generally not applicable to single-core processors handling multi-threading. However, in multi-core systems with many cores, it is typical to assign a core to a peripheral. Thus, it makes sense to keep that core idle while waiting for events to occur.

The result is that preemptive, interrupt-driven RTOS architectures occupy most of the deployed platforms. Although hardware means (multiple register combinations, hardware scheduling, task switching, and layered interrupt priority systems, etc.) can significantly reduce interrupt latency, that latency will always be an issue.

Preemptive processing brings several problems. Most of them are timing-related, such as race conditions, deadlocks, busy waiting, and priority inversion, which occur when a lower-priority task A has synchronized resources with a higher-priority task B, while a task C with a priority higher than A is running.

Without features like priority ceilings, task C can block tasks A and C from running. The priority ceiling feature can change the priority of task A to match that of task C, allowing task A to run and eventually release the resources needed by task C. At this point, task A’s priority is restored, and task C can continue running.

Other timing-related issues that programmers must resolve are often difficult to locate and correct the source of defects. Tracking tools become very valuable in locating these defects, as symptoms such as blocked tasks are the only manifestation of these problems.

Regarding the features required by the operating system, reentrant library characteristics are optional in an RTOS environment. However, in a typical operating system, since tasks and programs are often random and variable, and often share libraries, reentrant libraries are a necessary feature.

In embedded environments, there are generally more control requirements for the programs and tasks running in the system. Typically, apart from the operating system interface (which can be reentrant or non-reentrant), tasks never share any code. Programmers (especially those responsible for device drivers) need to pay attention to this reentrancy issue.

There are now many task synchronization mechanisms in the industry, from mutexes to messaging systems. From the perspective of RTOS, these mechanisms do not differ much in synchronizing issues such as race conditions.

Timers are common in MCUs and operating systems. At least, a timer can be used as a clock. However, because timers are so useful, they are often implemented in a special way. The POSIX standard even defines timers as components. Timers can also be used as watchdogs.

In many MCUs, a timer can be set to wake up a system in sleep mode. Some implementations allow the operating system to use it as a general-purpose timer, although this wake-up feature is independent of the operating system.

Some systems have multiple timers with different characteristics to meet different requirements. Some timers can be synchronized to provide simultaneous pulse-width modulation (PWM) streams for motor control applications. For RTOS, a timer is often used to implement clocks and provide time-slicing support.

Timers also support time slicing. Time slicing is common in time-sharing systems, giving each application a reasonable time slice to execute. This polling scheduling can be implemented at any interrupt level.

Typically, the time slices provided by the clock are of fixed length, and each task is given the same length of time slice to execute before gaining priority. Of course, this strategy is random and can have various implementations. For example, variable time slice widths will allow time to be allocated on a per-task basis, where some tasks receive longer time than others; while using a task priority method may result in low-priority tasks not getting a response.

Many RTOS adopt fixed schedulers. Other RTOS allow replacement or customization, but another part of the RTOS supports various strategies. This flexible approach allows operating systems like Linux to provide real-time support while also running various applications in a time-slicing environment. Real-time tasks have high priority and are executed before general user tasks.

Linux actually has a more complex scheduling system, which specifies whether tasks are handed over to other tasks of the same priority through polling or run until completion. Platforms like Open Kernel Labs’ OKL4 virtualization RTOS address this issue.

Basic Communication

Some literature separates task synchronization and communication, but overall, they are one and the same. It is essentially about how information is exchanged. Message-passing-based RTOS exemplifies this point most clearly. Here, the messaging system handles all communication without distinguishing between communication and synchronization.

At a minimum, an RTOS must provide a mutual exclusion primitive, such as a mutex. Other things can be built on this primitive. In many cases, such as messaging systems, support for mutual exclusion is hidden within the operating system. Only higher-level messaging functions are exposed externally.

Messaging systems have various names, from pipes to queues. Their implementations can span from single-processor, single-memory models to multi-core clustered systems. Enea’s OSE RTOS and QNX’s Neutrino are two mainstream RTOS based on message passing.

Regardless of the method or API chosen, the communication system must be integrated into the operating system to some extent. Therefore, if a task in an active queue must wait for an event, that task can be removed. Similarly, a task that triggers an event causing another task to become active will generate a scheduling behavior.

Communication, events, and scheduling can be associated with hardware, which are other matters that RTOS must handle. TI’s DSP/BIOS is an RTOS designed to run on DSPs like TI’s DaVinci dual-core systems. A major function of DSP/BIOS is to handle communication between ARM cores and DSP cores.

The trend towards larger cores will likely retain RTOS or OS. However, small cores hinder or limit the adoption of RTOS. Intellasys’ SEAforth 40C18 chip features 40 small 18-bit cores running Forth. The instruction set is minimal, with each word containing four instructions.

Each core has 64 words of ROM and RAM, and the chip can only accommodate 10,000 instructions. Of course, this is only enough to fit one program, and installing an RTOS is impossible. However, there is enough space across the chip to install specific parts of an operating environment. Similarly, applications suitable for that platform are often specific. Thus, since the hardware can handle communication and task scheduling between cores, RTOS-like support is not required.

Resource Management

What sets RTOS apart is its ability to manage resources (including time and memory). Timing issues are related to interrupt response times, but resource management timing issues can also arise. While interrupts solve a range of timing issues, applications still need to utilize resources.

Consider memory allocation. Many real-time applications do not use dynamic memory allocation to ensure that the differences generated during memory allocation and deallocation do not become a problem. Applications requiring dynamic memory allocation often divide memory into real-time and non-real-time. The latter handles dynamic memory allocation. Typically, the real-time portion must be allocated sufficient memory before use.

Using C and C++ in real-time embedded applications is because the usage of memory and other resources is explicit. Real-time tasks need to avoid using C and C++. Especially when memory allocation and deallocation are more easily hidden, using C++ becomes very difficult.

Languages like Java and C# pose even greater challenges, as they inherently use dynamic memory allocation. Programmers can control memory allocation and deallocation. In some cases, the programming environment can reinforce memory allocation and deallocation.

The Real-Time Specification for Java (RTSJ) defines a way to create Java applications that do not require garbage collection. RTSJ does this within the Java framework, allowing programmers to enjoy the benefits of Java without being constrained by memory allocation.

Both Sun and DDC-I have implemented RTSJ. DDC-I’s implementation supports x86 and PowerPC platforms. Aonix has a similar platform called PERC. These platforms are characterized by real-time, concurrent garbage collection, making it possible to write real-time applications in Java without being constrained by memory allocation.

However, since the system must allow threads to convert for the garbage collector, real-time requirements are not as urgent. On the other hand, garbage collectors will consume timing resources, so only real-time tasks can guarantee meeting certain deadline requirements. Speed is good, but timeliness is the law of RTOS.

When considering real-time platforms, one consideration is the overall impact of memory allocation on the system. Many systems can operate in a static allocation environment that never changes, but more dynamic systems can benefit from real-time garbage collection. Studies have shown that the benefits of garbage collection are comparable to deterministic memory allocation.

Another issue surrounding virtual machine-type platforms like Java and C# is the limitations of using just-in-time (JIT) compilers. Real-time systems based on these systems must use ahead-of-time (AOT) compilers like those used with C and C++.

Designers often choose Java or C# for their higher productivity, lower error rates, and safety features. Therefore, it is not surprising that a specification called JSR-302 was developed for Java applications with the highest safety requirements.

Protecting RTOS

RTOS is limited by the hardware platform it runs on. Protection can be applied to hardware lacking memory protection, but the level of security will be limited. However, memory and virtual machines can support higher levels of security. Security policies within SE Linux, Green Hills Integrity, LynuxWorks LynxSecure Embedded Hypervisor, and LynxOS-SE RTOS can provide much more reliable protection than typical RTOS. However, the costs are high, so developers need to weigh this.

Real-time system developers must deal with policy implementation and boundary issues. Depending on the source and destination of information, security support can take a long time. This is precisely why partitioning systems were introduced, allowing security measures to be taken at the boundary and placing the non-real-time parts of applications within that space.

OS-Aware Scheduler

When considering the choice of an operating system, support for debuggers is key. This support manifests in two aspects: kernel and device driver debugging, as well as OS awareness.

Kernel debugging is crucial for creating and supporting device drivers and enhancing the kernel. In many cases, a dedicated debugger is required to handle the kernel of an RTOS. It also requires an understanding of both the kernel environment and the application environment.

OS awareness allows for a deeper understanding of the operating system. Support can range from providing information about the OS service status to adjusting task scheduling. Similarly, OS-aware debuggers can allow other applications or threads to run while stopping other applications or threads.

Source: https://blog.csdn.net/refine19/article/details/5975592

This article is sourced from the internet, and the copyright belongs to the original author. If there are any copyright issues, please contact me for deletion.

You may also like:

Previous Recommendations

A Step-by-Step Guide to Creating a Jlink-OB Debugger

What are the Current Mainstream Small Embedded GUIs?

How Does a Program Check Its Own Integrity?

Essentials | Analyzing Program Auto-Start on Boot

Reply “1024” in the official account chat interface to obtain embedded resources; reply “m” to view article summaries

Leave a Comment