POSIX-compliant systems

All the embedded systems analyzed so far represent the ideal solutions for classic embedded systems designed with a single set of tasks in mind, where features such as memory protection and task separation are not interesting enough to invest system resources in. Riot OS provides a subset of POSIX API calls, mostly to access the TCP/IP features, with the purpose of smoothing the learning curve experienced by developers when taking their first steps in developing software for embedded platforms.

Due to the remarkable progress in the last decade of microcontroller-based embedded systems, we have seen that it is not impossible to develop general-purpose, universal, software development platforms, offering standard APIs to run standalone, self-contained applications. Models for this kind of approach to multithreading systems exist in other worlds, and are applied to build operating systems for types of devices other than microcontroller-based embedded systems. Despite the amount of resources being still very far from those of mobile phones or personal computers, and the absence of memory virtualization, it is still possible to implement kernels that provide memory segmentation, privilege separation, and proper kernel-user space communication based exclusively on supervisor calls. As we saw in Chapter 10Parallel Tasks and Scheduling, 32-bit microcontrollers are capable of providing techniques implemented in hardware for privilege separation, context switches and, in some cases, memory segmentation.

The POSIX standard provides the guidelines to integrate these kinds of tools into universal operating systems, offering a standard API for the application to interact with the kernel and request specific operations that require supervision according to the planned safety strategy of the system.

Implementing the POSIX interface has several advantages for the system. The first one is the benefit for developers who can recognize the similarities of the standard C library interface to access the resources available to other environments they might be familiar with, such as GNU/Linux or other popular UNIX-like systems. When writing an operating system, this can be achieved by providing the same signatures for the API calls as those available on a mobile device or a desktop system to build user applications. However, writing a POSIX-compliant system means including many other features related to process and thread management, interactions with the filesystem, and some kind of separation among the processes, and between each process and the kernel.

A POSIX system must be able to create both processes and threads, with standard interfaces to organize and manage them in precise hierarchical parent-child structures. POSIX indicates the implementation strategy of instruments for thread synchronization and inter-process communication, through standard calls implemented in kernel space. The full POSIX specification is often too big to fit the needs of a generic, yet small, operating system that still has to cope with the limited resources and the lack of virtual memory pages. Some subsets of the features recommended by POSIX regulating user accounts and permissions would be overkill for a system that is not designed for multiple users, while other things are impossible to implement due to the lack of features.

An example of the limitations of embedded platforms, when it comes to POSIX implementation, is the fork system call, which is described as the default mechanism to create a new process on the system. Due to its intrinsic characteristic, the implementation of the fork in the kernel requires virtual memory mapping, in order to coordinate the parent and child process from the moment of creation to the separation of the address spaces. According to POSIX, the fork system call can be replaced by vfork, which has the same purpose, but does not allow the scheduler to return the control to the parent task, until the child has called exec, which resets all the local references in the child task and allows us to complete the separation of the address spaces.

One of the interfaces that is likely to change the approach to designing multitask applications is poll. A system implementing poll, and providing all the resources as file descriptors as recommended by POSIX, can provide a blocking system call, supervising multiple heterogeneous resources at the same time. In a UNIX-like system, every I/O resource can be accessed from a process using the file abstraction, which means that all share the same handle, the file descriptor, used as a reference in input and output operations. A single poll call is often used as the central blocking point of applications, because it is capable of managing TCP/IP sockets, input sensor devices, inter-process communication mechanisms, serial ports, and other resources, at the same time. While a process or a thread is suspended, polling multiple file descriptors, any related event, among those enabled with poll, would wake up the calling process, which is otherwise not being scheduled while there is no activity on any of them. For an embedded application managing multiple interfaces at the same time, a single poll can often replace multiple threads that a classic RTOS design would require, due to the lack of mechanisms for efficiently multiplexing the management of input and output operations.

The flexibility of a POSIX system allows us to integrate software that is written for other platforms in the easiest way possible, even though it requires an intermediate layer of standard C libraries, distributed along with the system to compile portable applications to run on the system. POSIX-compliant embedded systems are able to run software that is designed for UNIX-like platforms, given it is not using excessive resources or any subset of system calls not implemented by the target platform. This feature in particular allows us to directly integrate a wide range of software, including small daemons and libraries, facilitating the integration of existing software, including application protocols and transport security for IoT applications.

Besides supporting standard C applications, compilers, and interpreters, high-level languages other than C can be integrated, as long as they are built against a standard libc, shorthand for the C library. Supporting multiple languages and paradigms at system level expands even further the possibilities of creating general-purpose platforms.

Probably the most important benefit of adopting the POSIX specifications in embedded systems comes from the isolations of the tasks and the definition of the interface between kernel and user space as a set of system calls, with a standardized contract. The kernel can be designed to supervise all the operations that may have any impact on the integrity of the systems or the other tasks running, and react to any misbehavior before any consequence.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.97.157