📄 main.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"><title>uIP 1.0: The uIP TCP/IP stack</title><link href="doxygen.css" rel="stylesheet" type="text/css"><link href="tabs.css" rel="stylesheet" type="text/css"></head><body><!-- Generated by Doxygen 1.4.6 --><div class="tabs"> <ul> <li id="current"><a href="main.html"><span>Main Page</span></a></li> <li><a href="modules.html"><span>Modules</span></a></li> <li><a href="classes.html"><span>Data Structures</span></a></li> <li><a href="files.html"><span>Files</span></a></li> <li><a href="examples.html"><span>Examples</span></a></li> </ul></div><h1>The uIP TCP/IP stack</h1><p><dl compact><dt><b>Author:</b></dt><dd>Adam Dunkels, <a href="http://www.sics.se/~adam/">http://www.sics.se/~adam/</a></dd></dl>The uIP TCP/IP stack is intended to make it possible to communicate using the TCP/IP protocol suite even on small 8-bit micro-controllers. Despite being small and simple, uIP do not require their peers to have complex, full-size stacks, but can communicate with peers running a similarly light-weight stack. The code size is on the order of a few kilobytes and RAM usage can be configured to be as low as a few hundred bytes.<p>uIP can be found at the uIP web page: <a href="http://www.sics.se/~adam/uip/">http://www.sics.se/~adam/uip/</a><p><dl compact><dt><b>See also:</b></dt><dd><a class="el" href="a00143.html">Application programs</a> <p><a class="el" href="a00153.html">Compile-time configuration options</a> <p><a class="el" href="a00144.html">Run-time configuration functions</a> <p><a class="el" href="a00145.html">Initialization functions</a> <p><a class="el" href="a00146.html">Device driver interface</a> and <a class="el" href="a00149.html">variables used by device drivers</a> <p><a class="el" href="a00147.html">uIP functions called from application programs</a> (see below) and the <a class="el" href="a00158.html">protosockets API</a> and their underlying <a class="el" href="a00142.html">protothreads</a></dd></dl><h2><a class="anchor" name="uIPIntroduction">Introduction</a></h2>With the success of the Internet, the TCP/IP protocol suite has become a global standard for communication. TCP/IP is the underlying protocol used for web page transfers, e-mail transmissions, file transfers, and peer-to-peer networking over the Internet. For embedded systems, being able to run native TCP/IP makes it possible to connect the system directly to an intranet or even the global Internet. Embedded devices with full TCP/IP support will be first-class network citizens, thus being able to fully communicate with other hosts in the network.<p>Traditional TCP/IP implementations have required far too much resources both in terms of code size and memory usage to be useful in small 8 or 16-bit systems. Code size of a few hundred kilobytes and RAM requirements of several hundreds of kilobytes have made it impossible to fit the full TCP/IP stack into systems with a few tens of kilobytes of RAM and room for less than 100 kilobytes of code.<p>The uIP implementation is designed to have only the absolute minimal set of features needed for a full TCP/IP stack. It can only handle a single network interface and contains the IP, ICMP, UDP and TCP protocols. uIP is written in the C programming language.<p>Many other TCP/IP implementations for small systems assume that the embedded device always will communicate with a full-scale TCP/IP implementation running on a workstation-class machine. Under this assumption, it is possible to remove certain TCP/IP mechanisms that are very rarely used in such situations. Many of those mechanisms are essential, however, if the embedded device is to communicate with another equally limited device, e.g., when running distributed peer-to-peer services and protocols. uIP is designed to be RFC compliant in order to let the embedded devices to act as first-class network citizens. The uIP TCP/IP implementation that is not tailored for any specific application.<h2><a class="anchor" name="tcpip">TCP/IP Communication</a></h2>The full TCP/IP suite consists of numerous protocols, ranging from low level protocols such as ARP which translates IP addresses to MAC addresses, to application level protocols such as SMTP that is used to transfer e-mail. The uIP is mostly concerned with the TCP and IP protocols and upper layer protocols will be referred to as "the application". Lower layer protocols are often implemented in hardware or firmware and will be referred to as "the network device" that are controlled by the network device driver.<p>TCP provides a reliable byte stream to the upper layer protocols. It breaks the byte stream into appropriately sized segments and each segment is sent in its own IP packet. The IP packets are sent out on the network by the network device driver. If the destination is not on the physically connected network, the IP packet is forwarded onto another network by a router that is situated between the two networks. If the maximum packet size of the other network is smaller than the size of the IP packet, the packet is fragmented into smaller packets by the router. If possible, the size of the TCP segments are chosen so that fragmentation is minimized. The final recipient of the packet will have to reassemble any fragmented IP packets before they can be passed to higher layers.<p>The formal requirements for the protocols in the TCP/IP stack is specified in a number of RFC documents published by the Internet Engineering Task Force, IETF. Each of the protocols in the stack is defined in one more RFC documents and RFC1122 collects all requirements and updates the previous RFCs.<p>The RFC1122 requirements can be divided into two categories; those that deal with the host to host communication and those that deal with communication between the application and the networking stack. An example of the first kind is "A TCP MUST be able to receive a TCP option in any segment" and an example of the second kind is "There MUST be a mechanism for reporting soft TCP error conditions to the application." A TCP/IP implementation that violates requirements of the first kind may not be able to communicate with other TCP/IP implementations and may even lead to network failures. Violation of the second kind of requirements will only affect the communication within the system and will not affect host-to-host communication.<p>In uIP, all RFC requirements that affect host-to-host communication are implemented. However, in order to reduce code size, we have removed certain mechanisms in the interface between the application and the stack, such as the soft error reporting mechanism and dynamically configurable type-of-service bits for TCP connections. Since there are only very few applications that make use of those features they can be removed without loss of generality.<h2><a class="anchor" name="mainloop">Main Control Loop</a></h2>The uIP stack can be run either as a task in a multitasking system, or as the main program in a singletasking system. In both cases, the main control loop does two things repeatedly:<p><ul><li>Check if a packet has arrived from the network.</li><li>Check if a periodic timeout has occurred.</li></ul><p>If a packet has arrived, the input handler function, <a class="el" href="a00146.html#ga4360412ee9350fba725f98a137169fe">uip_input()</a>, should be invoked by the main control loop. The input handler function will never block, but will return at once. When it returns, the stack or the application for which the incoming packet was intended may have produced one or more reply packets which should be sent out. If so, the network device driver should be called to send out these packets.<p>Periodic timeouts are used to drive TCP mechanisms that depend on timers, such as delayed acknowledgments, retransmissions and round-trip time estimations. When the main control loop infers that the periodic timer should fire, it should invoke the timer handler function <a class="el" href="a00146.html#g1024f8a5fa65e82bf848b2e6590d9628">uip_periodic()</a>. Because the TCP/IP stack may perform retransmissions when dealing with a timer event, the network device driver should called to send out the packets that may have been produced.<h2><a class="anchor" name="arch">Architecture Specific Functions</a></h2>uIP requires a few functions to be implemented specifically for the architecture on which uIP is intended to run. These functions should be hand-tuned for the particular architecture, but generic C implementations are given as part of the uIP distribution.<h3><a class="anchor" name="checksums">Checksum Calculation</a></h3>The TCP and IP protocols implement a checksum that covers the data and header portions of the TCP and IP packets. Since the calculation of this checksum is made over all bytes in every packet being sent and received it is important that the function that calculates the checksum is efficient. Most often, this means that the checksum calculation must be fine-tuned for the particular architecture on which the uIP stack runs.<p>While uIP includes a generic checksum function, it also leaves it open for an architecture specific implementation of the two functions <a class="el" href="a00150.html#g2addf34c7d457c1a7899a7e2171ef1e9">uip_ipchksum()</a> and <a class="el" href="a00150.html#g85b65e38aa74eba18979156f97a94a87">uip_tcpchksum()</a>. The checksum calculations in those functions can be written in highly optimized assembler rather than generic C code.<h3><a class="anchor" name="longarith">32-bit Arithmetic</a></h3>The TCP protocol uses 32-bit sequence numbers, and a TCP implementation will have to do a number of 32-bit additions as part of the normal protocol processing. Since 32-bit arithmetic is not natively available on many of the platforms for which uIP is intended, uIP leaves the 32-bit additions to be implemented by the architecture specific module and does not make use of any 32-bit arithmetic in the main code base.<p>While uIP implements a generic 32-bit addition, there is support for having an architecture specific implementation of the <a class="el" href="a00150.html#g6832e4d2d046536b6472f7ac92340f68">uip_add32()</a> function.<h2><a class="anchor" name="memory">Memory Management</a></h2>In the architectures for which uIP is intended, RAM is the most scarce resource. With only a few kilobytes of RAM available for the TCP/IP stack to use, mechanisms used in traditional TCP/IP cannot be directly applied.<p>The uIP stack does not use explicit dynamic memory allocation. Instead, it uses a single global buffer for holding packets and has a fixed table for holding connection state. The global packet buffer is large enough to contain one packet of maximum size. When a packet arrives from the network, the device driver places it in the global buffer and calls the TCP/IP stack. If the packet contains data, the TCP/IP stack will notify the corresponding application. Because the data in the buffer will be overwritten by the next incoming packet, the application will either have to act immediately on the data or copy the data into a secondary buffer for later processing. The packet buffer will not be overwritten by new packets before the application has processed the data. Packets that arrive when the application is processing the data must be queued, either by the network device or by the device driver. Most single-chip Ethernet controllers have on-chip buffers that are large enough to contain at least 4 maximum sized Ethernet frames. Devices that are handled by the processor, such as RS-232 ports, can copy incoming bytes to a separate buffer during application processing. If the buffers are full, the incoming packet is dropped. This will cause performance degradation, but only when multiple connections are running in parallel. This is because uIP advertises a very small receiver window, which means that only a single TCP segment will be in the network per connection.<p>In uIP, the same global packet buffer that is used for incoming packets is also used for the TCP/IP headers of outgoing data. If the application sends dynamic data, it may use the parts of the global packet buffer that are not used for headers as a temporary storage buffer. To send the data, the application passes a pointer to the data as well as the length of the data to the stack. The TCP/IP headers are written into the global buffer and once the headers have been produced, the device driver sends the headers and the application data out on the network. The data is not queued for retransmissions. Instead, the application will have to reproduce the data if a retransmission is necessary.<p>The total amount of memory usage for uIP depends heavily on the applications of the particular device in which the implementations are to be run. The memory configuration determines both the amount of traffic the system should be able to handle and the maximum amount of simultaneous connections. A device that will be sending large e-mails while at the same time running a web server with highly dynamic web pages and multiple simultaneous clients, will require more RAM than a simple Telnet server. It is possible to run the uIP implementation with as little as 200 bytes of RAM, but such a configuration will provide extremely low throughput and will only allow a small number of simultaneous connections.<h2><a class="anchor" name="api">Application Program Interface (API)</a></h2>The Application Program Interface (API) defines the way the application program interacts with the TCP/IP stack. The most commonly used API for TCP/IP is the BSD socket API which is used in most Unix systems and has heavily influenced the Microsoft Windows WinSock API. Because the socket API uses stop-and-wait semantics, it requires support from an underlying multitasking operating system. Since the overhead of task management, context switching and allocation of stack space for the tasks might be too high in the intended uIP target architectures, the BSD socket interface is not suitable for our purposes.<p>uIP provides two APIs to programmers: protosockets, a BSD socket-like API without the overhead of full multi-threading, and a "raw" event-based API that is nore low-level than protosockets but uses less memory.<p><dl compact><dt><b>See also:</b></dt><dd><a class="el" href="a00158.html">Protosockets library</a> <p><a class="el" href="a00142.html">Protothreads</a></dd></dl><h3><a class="anchor" name="rawapi">The uIP raw API</a></h3>The "raw" uIP API uses an event driven interface where the application is invoked in response to certain events. An application running on top of uIP is implemented as a C function that is called by uIP in response to certain events. uIP calls the application when data is received, when data has been successfully delivered to the other end of the connection, when a new connection has been set up, or when data has to be retransmitted. The application is also periodically polled for new data. The application program provides only one callback function; it is up to the application to deal with mapping different network services to different ports and connections. Because the application is able to act on incoming data and connection requests as soon as the TCP/IP stack receives the packet, low response times can be achieved even in low-end systems.<p>uIP is different from other TCP/IP stacks in that it requires help from the application when doing retransmissions. Other TCP/IP stacks buffer the transmitted data in memory until the data is known to be successfully delivered to the remote end of the connection. If the data needs to be retransmitted, the stack takes care of the retransmission without notifying the application. With this approach, the data has to be buffered in memory while waiting for an acknowledgment even if the application might be able to quickly regenerate the data if a retransmission has to be made.<p>In order to reduce memory usage, uIP utilizes the fact that the application may be able to regenerate sent data and lets the application take part in retransmissions. uIP does not keep track of packet contents after they have been sent by the device driver, and uIP requires that the application takes an active part in performing the retransmission. When uIP decides that a segment should be retransmitted, it calls the application with a flag set indicating that a retransmission is required. The application checks the retransmission flag and produces the same data that was previously sent. From the application's standpoint, performing a retransmission is not different from how the data originally was sent. Therefore the application can be written in such a way that the same code is used both for sending data and retransmitting data. Also, it is important to note that even though the actual retransmission operation is carried out by the application, it is the responsibility of the stack to know when the retransmission should be made. Thus the complexity of the application does not necessarily increase because it takes an active part in doing retransmissions.<h4><a class="anchor" name="appevents">Application Events</a></h4>The application must be implemented as a C function, <a class="el" href="a00153.html#g41aa744caa46913b3b3aedb2a4e78546">UIP_APPCALL()</a>, that uIP calls whenever an event occurs. Each event has a corresponding test function that is used to distinguish between different events. The functions are implemented as C macros that will evaluate to either zero or non-zero. Note that certain events can happen in conjunction with each other (i.e., new data can arrive at the same time as data is acknowledged).<h4><a class="anchor" name="connstate">The Connection Pointer</a></h4>When the application is called by uIP, the global variable <a class="el" href="a00088.html">uip_conn</a> is set to point to the <a class="el" href="a00088.html">uip_conn</a> structure for the connection that currently is handled, and is called the "current connection". The fields in the <a class="el" href="a00088.html">uip_conn</a> structure for the current connection can be used, e.g., to distinguish between different services, or to check to which IP address the connection is connected. One typical use would be to inspect the uip_conn->lport (the local TCP port number) to decide which service the connection should provide. For instance, an application might decide to act as an HTTP server if the value of uip_conn->lport is equal to 80 and act as a TELNET server if the value is 23.<h4><a class="anchor" name="recvdata">Receiving Data</a></h4>If the uIP test function <a class="el" href="a00147.html#g26a14b8dae3f861830af9e7cf1e03725">uip_newdata()</a> is non-zero, the remote host of the connection has sent new data. The uip_appdata pointer point to the actual data. The size of the data is obtained through the uIP function <a class="el" href="a00147.html#g1a1bc437c09ddef238abab41d77c3177">uip_datalen()</a>. The data is not buffered by uIP, but will be overwritten after the application function returns, and the application will therefor have to either act directly on the incoming data, or by itself copy the incoming data into a buffer for later processing.<h4><a class="anchor" name="senddata">Sending Data</a></h4>When sending data, uIP adjusts the length of the data sent by the application according to the available buffer space and the current TCP window advertised by the receiver. The amount of buffer space is dictated by the memory configuration. It is therefore possible that all data sent from the application does not arrive at the receiver, and the application may use the <a class="el" href="a00147.html#gb5fecbc62edd128012cea0f47b57ab9f">uip_mss()</a> function to see how much data that actually will be sent by the stack.<p>The application sends data by using the uIP function <a class="el" href="a00147.html#g04b053a623aac7cd4195157d470661b3">uip_send()</a>. The <a class="el" href="a00147.html#g04b053a623aac7cd4195157d470661b3">uip_send()</a> function takes two arguments; a pointer to the data to be sent and the length of the data. If the application needs RAM space for producing the actual data that should be sent, the packet buffer (pointed to by the uip_appdata pointer) can be used for this purpose.<p>The application can send only one chunk of data at a time on a connection and it is not possible to call <a class="el" href="a00147.html#g04b053a623aac7cd4195157d470661b3">uip_send()</a> more than once per application invocation; only the data from the last call will be sent.<h4><a class="anchor" name="rexmitdata">Retransmitting Data</a></h4>Retransmissions are driven by the periodic TCP timer. Every time the periodic timer is invoked, the retransmission timer for each connection is decremented. If the timer reaches zero, a retransmission should be made. As uIP does not keep track of packet contents after they have been sent by the device driver, uIP requires that the application takes an active part in performing the retransmission. When uIP decides that a segment should be retransmitted, the application function is called with the <a class="el" href="a00147.html#ga8933ad15a2e2947dae4a5cff50e6007">uip_rexmit()</a> flag set, indicating that a retransmission is required.<p>The application must check the <a class="el" href="a00147.html#ga8933ad15a2e2947dae4a5cff50e6007">uip_rexmit()</a> flag and produce the same data that was previously sent. From the application's standpoint, performing a retransmission is not different from how the data originally was sent. Therefor, the application can be written in such a way that the same code is used both for sending data and retransmitting data. Also, it is important to note that even though the actual retransmission operation is carried out by the application, it is the responsibility of the stack to know when the retransmission should be made. Thus the complexity of the application does not necessarily increase because it takes an active part in doing retransmissions.<h4><a class="anchor" name="closing">Closing Connections</a></h4>The application closes the current connection by calling the <a class="el" href="a00147.html#g61db1dcb7c760e4dd5d60bf4e5576dca">uip_close()</a> during an application call. This will cause the connection to be cleanly closed. In order to indicate a fatal error, the application might want to abort the connection and does so by calling the <a class="el" href="a00147.html#g88d2ccf7cd821f89d9a8df7e3948b56c">uip_abort()</a> function.<p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -