Rtos Blocks Module5
Rtos Blocks Module5
9.1 Introduction
A good real-time embedded operating system avoids implementing the kernel as a large,
monolithic program. The kernel is developed instead as a micro-kernel. The goal of the micro-
kernel design approach is to reduce essential kernel services into a small set and to provide a
framework in which other optional kernel services can be implemented as independent modules.
These modules can be placed outside the kernel. Some of these modules are part of special
server tasks. This structured approach makes it possible to extend the kernel by adding additional
services or to modify existing services without affecting users. This level of implementation
flexibility is highly desirable. The resulting benefit is increased system configurability because
each embedded application requires a specific set of system services with respect to its
characteristics. This combination can be quite different from application to application.
The micro-kernel provides core services, including task-related services, the scheduler service,
and synchronization primitives. This chapter discusses other common building blocks, as shown
in Figure 9.1.
The RPC client in turn invokes remote procedure calls residing in the RPC server on behalf of the
calling application. The primary goal of RPC is to make remote procedure calls transparent to
applications invoking the local call stubs. To the client application, calling a stub appears no
different from calling a local procedure. The RPC client and server can run on top of different
operating systems, as well as different types of hardware. As an example of such transparency,
note that NFS relies directly upon RPC calls to support the illusion that all files are local to the
client machine.
To hide both the server remoteness, as well as platform differences from the client application,
data that flows between the two computing systems in the RPC call must be translated to and
from a common format. External data representation (XDR) is a method that represents data in
an OS- and machine-independent manner. The RPC client translates data passed in as
procedure parameters into XDR format before making the remote procedure call. The RPC server
translates the XDR data into machine-specific data format upon receipt of the procedure call
request. The decoded data is then passed to the actual procedure to be invoked on the server
machine. This procedure's output data is formatted into XDR when returning it to the RPC client.
The RPC concept is illustrated in Figure 9.4.
Figure 9.4: Remote procedure calls.
The first level of configuration is done in a component inclusion header file. For example, call it
sys_comp.h , as shown in Listing 9.1.
Listing 9.1: The sys_comp.h inclusion header file.
#define INCLUDE_TCPIP 1
#define INCLUDE_FILE_SYS 0
#define INCLUDE_SHELL 1
#define INCLUDE_DBG_AGENT 1
In this example, the target image includes the TCP/IP protocol stack, the command shell, and the
debug agent. The file system is excluded because the sample target system does not have a
mass storage device. The programmer selects the desired components through sys_comp.h.
In this example, four user-configurable parameters are present: the number of packet buffers to
be allocated for transmitting and receiving network packets; the number of sockets to be allocated
for the applications; the number of routing entries to be created in the routing table used for
forwarding packets; and the number of network interface data structures to be allocated for
installing network devices. Each parameter contains a default value, and the programmer is
allowed to change the value of any parameter present in the configuration file. These parameters
are applicable only to the TCP/IP protocol stack component.
Component-specific parameters must be passed to the component during the initialization phase.
The component parameters are set into a data structure called the component configuration
table. The configuration table is passed into the component initialization routine. This level is the
third configuration level. Listing 9.3 shows the configuration file named net_conf.c , which
continues to use the network component as the example.
Listing 9.3: The net_conf.c configuration file.
#include "sys_comp.h"
#include "net_conf.h"
#if (INCLUDE_TCPIP)
struct net_conf_parms params;
params.num_pkt_bufs = NUM_PKT_BUFS;
params.num_sockets = NUM_SOCKETS;
params.num_routes = NUM_ROUTES;
params.num_NICS = NUM_NICS;
tcpip_init(¶ms);
#endif
The components are pre-built and archived. The function tcpip_init is part of the component.
If INCLUDE_TCPIP is defined as 1 at the time the application is built, the call to this function
triggers the linker to link the component into the final executable image. At this point, the TCP/IP
protocol stack is included and fully configured.
Obviously, the examples presented here are simple, but the concepts vary little in real systems.
Manual configuration, however, can be tedious when it is required to wading through directories
and files to get to the configuration files. When the configuration file does not offer enough or
clear documentation on the configuration parameters, the process is even harder. Some host
development tools offer an interactive and visual alternative to manual component configuration.
The visual component configuration tool allows the programmer to select the offered components
visually. The configurable parameters are also laid out visually and are easily editable. The
outputs of the configuration tool are automatically generated files similar to sys_comp.h and
net_conf.h. Any modification completed through the configuration tool regenerates these files.
Many real-time operating systems provide wrapper functions to handle exceptions and interrupts
in order to shield the embedded systems programmer from the low-level details. This application-
programming layer allows the programmer to focus on high-level exception processing rather
than on the necessary, but tedious, prologue and epilogue system-level processing for that
exception. This isolation, however, can create misunderstanding and become an obstacle when
the programmer is transformed from an embedded applications programmer into an embedded
systems programmer.
Understanding the inner workings of the processor exception facility aids the programmer in
making better decisions about when to best use this powerful mechanism, as well as in designing
software that handles exceptions correctly. The aim of this chapter is to arm the programmer with
this knowledge.
Exceptions raised by internal events, such as events generated by the execution of processor
instructions, are called synchronous exceptions. Examples of synchronous exceptions include the
following:
§ On some processor architectures, the read and the write operations must start at an even
memory address for certain data sizes. Read or write operations that begin at an odd
memory address cause a memory access error event and raise an exception (called an
alignment exception ).
§ An arithmetic operation that results in a division by zero raises an exception.
Exceptions raised by external events, which are events that do not relate to the execution of
processor instructions, are called asynchronous exception s. In general, these external events
are associated with hardware signals. The sources of these hardware signals are typically
external hardware devices. Examples of asynchronous exceptions include the following:
§ Pushing the reset button on the embedded board triggers an asynchronous exception
(called the system reset exception ).
§ The communications processor module that has become an integral part of many
embedded designs is another example of an external device that can raise asynchronous
exceptions when it receives data packets.