TCP/IP in Embedded Systems - Linux

Before TCP/IP came to be widely used in embedded systems, it was common for embedded applications to run in systems without any OS at all. Sometimes embedded engineers would use a minimal OS containing no interface to integrate a networking stack, and most embedded engineers would use in-house designed operating systems if they had any OS at all. However, as the cost of hardware and memory decreased, computers for embedded applications needed to support software with increased complexity, so commercial embedded OS vendors moved into the market. The first commercial or outside operating systems consisted of small multitasking kernels that advertised high efficiency and low memory requirements. These OSs, however, didn’t have any standard IO interfaces, and didn’t support file systems, TCP/IP, or any other networking interfaces. In the meantime, embedded systems became more and more widely used and they were incorporated in just about any machine or device that is controllable, configurable, or programmable. As the complexity of embedded applications increased, there was an increasing need for more features in the operating systems such as file systems and TCP/IP networking. Commercial vendors filled the need, selling operating system software that included TCP/IP as a built-in component. These vendors collected royalties on each target system. As hardware became cheaper, the royalty became a more significant factor in the cost of the end product. Therefore, more and more embedded systems engineers are now looking for an open source solution for their embedded OS and TCP/IP networking stack.

Originally, Unix was too big and complex for most embedded applications. Now with cheaper memory and faster cheaper processors, the memory requirements of the OS is a less significant factor in the overall design. Therefore, Linux becomes increasingly practical for embedded systems. Along with Linux, embedded systems designers get a robust implementation of TCP/IP along with all the source code. In addition, as the popularity of Linux increases, it gets used more widely for desktop and server applications, which makes it easier to find components, tools, information, and support. The combination of the Linux OS with a stable TCP/IP stack has become the primary choice for many embedded systems used in many diverse applications.

Specific Requirements for Embedded OSs

The later of this book illustrate the Linux implementation of TCP/IP in detail. An important focus of this book is embedded systems; therefore, we should take the time to discuss the requirements for a generic embedded system that seeks to host a TCP/IP stack. We can compare these requirements with specific Linux capabilities to see how Linux compares with its competitors as a choice for an embedded OS, and how well it is suited to support an embedded system’s networking needs. The TCP/IP stack, like all networking protocols, is asynchronous. The stack implementation is event oriented where processing is invoked when a packet becomes available at a given layer. Each packet travels through the stack as a separate thread. In addition, there are concurrent activities needed to keep track of time- related events specified by the protocols. In the light of these general requirements, the following is a brief list of specific facilities that every embedded OS should have.

Timer facility: All protocols require timers for retransmissions and timeouts. Some of the simple OSs used for embedded systems either lack this simple facility or do not have a consistent interface. For example, will discuss the use of timers in the TCP protocol.

Concurrency and multitasking: The socket API should allow for multiple simultaneous users. The TCP/IP stack should be multithreaded. At the simplest level, buffer contention should be avoided by having semaphore protection at the buffer level. “The Linux TCP/IP Stack,” discusses Linux kernel threading and how these threads are used within TCP/IP.

Buffer management: TCP/IP and most communication protocols are most efficient when they are provided with a fixed-length buffer system. In earlier TCP/IP implementations and those commonly used in embedded systems, the buffer pool was pre-allocated at boot-up time. This system avoids problems with heap fragmentation but is limited because the maximum number of buffers is fixed. Buffers are assigned dynamically from the pool when a new incoming packet arrives at the network interface device or a new outgoing packet is created at the socket layer. As we will see in “Linux Socket Buffers and Linux Memory Allocation,” Linux networking buffers are called socket buffers. Socket buffers are allocated from a slab cache, which solves the fragmentation problem. Another advantage of the slab cache is scalability and that there is no preconfigured upper bound.

Link layer facility: Complex protocol implementation requires a way to layer protocols below IP and above the network interface driver. It is desirable to have a generalized facility to add protocols such as Network Address Translation (NAT), Point-to-Point Protocol (PPP), or other software-implemented bridging or switching capability without having to alter either the IP sources or network interface driver source code. As shown in, Linux provides a network interface device. These devices can be “real” devices with interrupt capability or pseudo-devices that can interface TCP/IP with an underlying protocol stack. In addition, as discussed in later, Linux provides a queuing layer between the network interface drivers to the network layer to handle specific requirements for multiple traffic classes. There are also a few other facilities where Linux can be differentiated from other real-time Oss used for embedded applications. Standard Linux like other earlier Unix implementations is a nonpreemptible implementation of the OS kernel. However, since TCP/IP is part of the Linux kernel, it can make use of the softirq kernel threading facility. We will see how this works in "The Linux TCP/IP Stack." Linux has the capability of deferring interrupt-level work to kernel threads to decrease latency problems.

Low latency: The operating system should not add any more latency than necessary to the minimum amount of processing required at interrupt time for the physical reception and transmission of a frame. The goal of the OS should be to minimize context switches while a packet is processed by the stack. Linux uses softirqs to handle most of the internal processing. In addition, as we will see in later chapters, fast paths are provided for packet transmission and reception to reduce the amount of overhead.

Minimal data copying: It is advantageous for embedded systems to minimize the amount of copying necessary to move a packet of data from the application, down through the stack to the transmission media. Embedded applications are performance sensitive and should have a TCP/IP stack implementation that has no buffer copying at the device driver level and allows for the option of eliminating buffer copying at the socket level. Typically, the Ethernet chip or hardware networking PHY device places the packet directly in memory via DMA. Linux provides scattergather DMA support where the socket buffers are set up to allow for the direct transmission of lists of TCP segments. In addition, at the user level, when data is transferred through a socket, copying can be avoided and data can be mapped directly into the user space from the kernel space.

All rights reserved © 2020 Wisdom IT Services India Pvt. Ltd Protection Status

Linux Topics