The whole truth about RTOS. Article # 6. Other RTOS services
In previous articles, we discussed the functionality of the kernel in terms of tasks performed and the interactions between them. In this article we will look at what else the kernel can do, which is largely manifested in a number of other available API calls. We will also answer the question, what turns the kernel into an operating system?
Previous articles in the series:
Article # 5. Interaction between tasks and synchronization
Article # 4. Tasks, Context Switching and Interrupts
Article # 3. Tasks and planning
Article # 2. RTOS: Structure and Real-time Mode
Article # 1. RTOS: introduction.
In addition to task scheduling and interaction between them, the RTOS will include functionality (API calls) for managing tasks in various ways. Consider some of the features.
Creating and deleting tasks
The “dynamic” RTOS has function calls that allow you to create tasks (and other objects of the RTOS) when they are required. Such calls include a wide range of parameters that define a task, such as an entry point, stack size, and priority. The corresponding API delete task call allows you to release resources after the task is completed.
In the “static” RTOS, the task defining parameters are configured in a kind of configuration file during the build.
Suspending and Resuming a Task
As we have seen, most RTOSs have the concept of a “suspended” task state. This can be achieved in various ways. One of them is an explicit call to the Suspend Task API function. It can be caused by itself or another task. The corresponding “Resume Task” call allows the task to be queued for planning again.
Sleep status tasks
For a real-time system, time control is an important requirement and can take many forms. A simple view is the ability of the task to “fall asleep”, that is, the task is suspended for a certain period of time. When time runs out, the task “wakes up” and is again queued for planning. An API call will usually be available for this purpose. Of course, this functionality depends on the availability of the timer.
When using the Round Robin scheduler (task), the task may refuse to control the processor for the next task in the chain. For this, the task release API function will be available. The task is not suspended, it will be available for planning when its turn comes. When using the Time slice scheduler, it is possible that a task can release part of its time interval if it does not have important work to be performed immediately. The release of the task has no logical meaning when running the schedulers Run to completion ("completion to completion") or Priority ("priority planning").
Completing the task
In a previous article, we found out that in addition to the states “Ready” (“Ready to continue”) or “Suspended” (RTOS), the RTOS can support other task states. The task can be “Finished”, which means that its main function is simply exited: no special API call is required. The task may be “Terminated”, which means that it is not available for planning and must be reset in order to become available for launch again, see “Resetting the Task” below. This requires a special API call. The availability of these additional task states, the terminology used, and their precise definitions will differ depending on the RTOS.
Many RTOSs offer a call to the Task Reset API function, which allows you to return the task to its original state. It may be in a suspended state and require the “Resume Task” function to be queued for planning.
Priority of tasks, etc.
In the “dynamic” RTOS, API calls may be available to configure several parameters of the task at run time. Examples include the priority and duration of the time interval.
The RTOS is a series of API-calls for the problem of system information, including
the tasks of information . How many tasks in the system, their configurations and current statuses.
Information about other kernel objects. How many objects of each type are in the system, their configurations and information about the current state. For example:
- What is the current capacity of the queue, can I add more messages?
- How many tasks are suspended on a specific mailbox?
In many applications, it is important that the program can dynamically capture some memory when it is required, and free it when it is no longer needed. The same happens in the embedded software. However, conventional approaches are subject to problems that are unlikely or inconvenient in desktop applications, but for an embedded system they can be catastrophic. However, there are ways to implement such services, even in a static RTOS.
Problems with malloc () and free () functions
In a C desktop program, a function can call malloc () , indicating how much memory is required, and get a pointer back to the storage area. Using memory, it can be freed by calling free (). Memory is allocated from an area called "heap." The problem with this approach is that with an uncoordinated sequence of calls to these functions, the “heap” area can easily become fragmented, and then the memory allocation will fail even if enough memory is available, because adjacent areas are not large enough. Some systems (for example, Java and Visual Basic) use complex “garbage collection” schemes to implement defragmentation. The problem is that these schemes can lead to significant unpredictable delays in execution time and the need to use indirect pointers (which does not work in C).
If malloc () and free ()they were implemented in a reentrant way (usually not) and used by RTOS tasks, fragmentation will occur very quickly, and a system failure will be almost inevitable. In C ++, there are new and delete operators that generally perform the same functions as malloc () and free (). They are subject to the same limitations and problems.
To provide a real-time system with dynamically available memory, you can use a block approach to memory management. Such blocks are usually called “partitions” (partitions); partitions can be allocated from the "partition pool".
A partition pool contains a specific number of blocks, each of which has the same size. The number and size of blocks in a partition are determined when creating a pool of partitions. This may be dynamic if the system itself allows it, or statically during assembly. As a rule, an application can include several pools of sections offering blocks of different sizes.
If a task needs memory, it calls an API requesting a block from a specific pool. If this call is successful, the task will receive a pointer to the selected block. If the call fails, because there are no partitions in the specified pool; the task may receive an error response. Alternatively, a task can be blocked (suspended) until another task releases a block in a section.
Usually, a task simply transfers a pointer to a block of memory to any code that the block uses. This causes a problem when the block is no longer needed. If the code has only a pointer to the block, how can it tell the RTOS via an API call, from which partition pool does it want to free the memory? The answer is that most RTOSs support additional data in a dedicated block (usually a negative offset from the pointer), which provide the required information. Thus, to call an API to release a block, only its address is required.
The next article will have more information about the sections of memory.
The functionality associated with the use and control of time is likely to be available in a real-time OS. Opportunities will vary depending on the RTOS, but we will look publicly available. In any case, a real-time timer is an essential element for the operation of any of these services.
A simple system time, or “clock timer,” is almost always available. It is simply a counter (typically 32 bits), which is incremented using a real-time interrupt service routine and can be set and read through API calls.
Service call timeouts
Usually, the RTOS allows blocking API calls, that is, the calling task pauses (blocks) until the requested service is provided. Typically, this blocking is uncertain, but some RTOS offer a timeout during which the call returns when the waiting time expires if the service remains unavailable. API call timeouts are not supported by all RTOS.
Sleep status of a task
Usually tasks have the ability to suspend themselves for a fixed period of time. This was discussed earlier in the “Task Management” section.
In order for software tasks to perform timing functions, most RTOSs offer timer objects. These are independent timers updated by the real-time timer interrupt handler that can be controlled by API calls. Such calls set up, monitor and track the timer. As a rule, they can be set for one-time operation or automatic restart. An expiration routine is also typically supported, a function that is executed each time a timer completes a cycle. In the next article there will be more information about software timers and a description of their implementation.
Interrupts, drivers and I / O
The extent to which RTOS is associated with interrupts and I / O is very different. Similarly, some RTOSs have a very clear structure for device drivers, which can add problems when choosing a particular product.
Interrupts are a problem for a RTOS for two reasons.
- Without any precautions, the interrupt handler (ISR) will “steal” processor time, thereby disrupting real-time RTOS behavior.
- If an ISR makes API calls that affect task scheduling, this should be monitored, and the RTOS should be able to run its scheduling algorithm.
Some RTOSs fully control all interrupts. A series of API calls are available, allowing you to “register” ISR programs. This approach allows the scheduler to determine exactly when interrupts are enabled, and facilitates the use of most API calls from an ISR.
For example, Nucleus RTOS implements the concept of “low priority” and “high priority” interrupt handlers, which provides reliable interrupt handling without unnecessary overhead (i.e., increasing interrupt latency).
Other RTOSs can use an automatic “hands off” mode for interrupts, which gives developers more options to ensure that interrupt handlers work correctly. As a rule, additional prefix (prologue) and suffix (epilogue) ISR are provided to protect the API calls made in it.
Nucleus SE uses lightweight interrupt handling tools, which will be described in the next article.
Most RTOSs determine the structure of a device driver. Details may differ depending on the RTOS, but the driver usually consists of two interacting components: embedded code (API calls) and ISR. Normally, other API calls will be available for managing and registering drivers.
Currently, most RTOSs in the market do not care about higher-level I / O, but some of them define I / O flow, which basically establishes the connection between the corresponding device drivers and standard C language functions, such as printf ().
Historically, RTOSs often supported a “console”, a user interface to an RTOS via a serial channel. It was mainly used for diagnostics and debugging. The use of modern debuggers that support debugging of applications with RTOS eliminates the need for such objects.
Usually, an RTOS is required for maximum performance with a minimum amount of memory. Therefore, integrity checking is not a top priority. With the help of modern debugging technologies that take into account the characteristics of the RTOS, most of the checks can be performed outside the RTOS itself.
Checking API Call Parameters
API calls can have many complex parameters. This can lead to errors. Many RTOSs provide verification of runtime parameters with the return of an error code in case of an incorrect parameter. Since this requires additional code, and the checks themselves have a negative impact on performance, it is better to perform parameter checks during assembly or configuration.
For most types of scheduler (except Run to Completion), each task has its own stack, the size of which is determined individually. In some RTOSs, the core has a separate stack; in others, the task stack is “borrowed” during an API call. Obviously, the integrity of the stack is important to the overall reliability of the system. Therefore, RTOSs often offer tools to check the integrity of stacks at run time. There are several options:
- An API call that returns the amount of free stack space for the current or specified task.
- Limiting stack options. They are assigned a unique (usually odd and non-zero) value, which is periodically checked for rewriting.
Despite the fact that this function is not directly supported in the RTOS, the application task can be allocated for checking the integrity of the entire system. Such a task may be responsible for resetting the watchdog timer. A task can receive periodic input data (for example, signal parameters) from each critical task. The watchdog timer reset (which will not allow the system to reboot) will be performed only after the data from all tasks arrive.
RTOS is more than just the core we have focused on so far. This is where the desktop operating system differs significantly from an embedded RTOS. Usually, in the desktop OS, all additional components are bundled or can be installed (all desktops have a graphical user interface, and only a few of them do not have access to the network). The desktop PC has no real resource limitations: there is always free memory, hard disk space and unused CPU resources. In the world of embedded systems with limited resources, additional components such as video cards, network components and file systems may be necessary, but they must be switchable and scalable to minimize the memory footprint.
Most embedded systems somehow relate to networks. Thus, it is expected that there is considerable interest in networking solutions for embedded systems, thanks to which there are a large number of products on the market.
TCP / IP is a standard protocol, widely used and is the obvious choice for many applications. Typically, TCP / IP is used for the Ethernet protocol (IEEE802.3), which on average provides a speed of 10 Mb / s. Today, 100 MB / s are quite common, and on the approach of 1 Gb / s. In addition, TCP / IP can be used for other protocols. For example, PPP (Point-to-Point Protocol) is a TCP / IP implementation for serial data transmission that has been adapted for broadband Internet connections.
Until recently, the v4 version of the IP protocol (IPv4) was used. However, it becomes outdated, as free addresses end. The solution is IPv6, which significantly increases the number of possible addresses and provides more efficient maintenance and security tools. IPv6 is widely available and used in the equipment of many countries, as well as military systems all over the world.
An alternative is the User Datagram Protocol (UDP). This protocol is used for maximum performance. UDP does not provide the same reliability and consistency as TCP, but is lightweight and highly efficient.
USB- “Universal Serial Bus” (Universal Serial Bus), is widely used in devices for connecting to desktop computers. It provides a very easy-to-use interface like “plug & play”, which hides behind itself rather complicated software. An embedded device that must be connected to a PC must be implemented as a USB function, which requires a specific set of software components. If the device needs to control other devices connected via USB (like a normal PC), it needs a set of host-type software.
IEEE1394 , another serial interface standard that is used to quickly transfer large amounts of data between devices (for example, to transmit video data), is also known as FireWire and i.Link.
Wireless protocols - the convenience and prevalence of various wireless technologies among consumers has led to a high demand for wireless capabilities in embedded devices. Wi-Fi (a set of IEEE802.11 standards) provides a complete set of network capabilities, allowing you to implement both peer and infrastructure topologies at a sufficient distance. Interest in data security in such networks is growing, which means that this should affect the software. Other radio technologies, such as Bluetooth and ZigBee, provide short-range point-to-point wireless.
Since networking capabilities are in high demand, there are many vendors offering their solutions. Customers face the challenge of checking the quality of available products. Unlike the RTOS core, a complete check of the functionality and performance of the protocol stack is not an easy task. Fortunately, toolkits are available for checking protocols (albeit at a considerable price), and a potential buyer can check with the supplier what kit they used during the checkout.
Graphical user interface is becoming increasingly common among embedded devices. It can be a very simple, small monochromatic LCD (as on older phones, MP3 players, alarms, etc.). On the other hand, a digital television receiver may have its own high-resolution HDTV screen. Such a screen requires software support, which is fully integrated into the core RTOS.
Since the screen usually has an input device, support for such devices is often included in the graphics package. Such a package can support pointing devices (for example, a mouse), touchscreens, keypads, and full-fledged keyboards.
Graphics can be used in various ways. It can simply provide information output (for example, as an electronic scoreboard). Or, the display may be part of a graphical user interface along with menus, windows, icons, and similar elements. In any case, a fairly specific set of software is required, and the graphics package that comes with the RTOS should provide the necessary flexibility without significantly increasing the memory footprint.
When an embedded application has to store and process large amounts of data, it is obvious that it makes sense to organize this data into some kind of file system. The data can be in RAM, in the built-in flash memory, on a flash drive, a regular hard disk or on an optical disk (CD-ROM or DVD-ROM). Again, this capability should have fully integrated software support in the RTOS. The file system must be carefully designed to meet the reentrancy requirements of the multitasking system.
Compliance with standards is especially important for file systems. For example, using an MS-DOS compatible disk format allows developers to use a well-proven architecture and offers full data exchange with desktop systems.