📄 uip-doc.txt
字号:
/**
\mainpage The uIP TCP/IP stack
\author Adam Dunkels, http://www.sics.se/~adam/
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.
uIP can be found at the uIP web page: http://www.sics.se/~adam/uip/
\sa \ref apps "Application programs"
\sa \ref uipopt "Compile-time configuration options"
\sa \ref uipconffunc "Run-time configuration functions"
\sa \ref uipinit "Initialization functions"
\sa \ref uipdevfunc "Device driver interface" and
\ref uipdrivervars "variables used by device drivers"
\sa \ref uipappfunc "uIP functions called from application programs"
(see below) and the \ref psock "protosockets API" and their underlying
\ref pt "protothreads"
\section uIPIntroduction Introduction
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.
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.
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.
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.
\section tcpip TCP/IP Communication
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.
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.
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.
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.
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.
\section mainloop Main Control Loop
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:
- Check if a packet has arrived from the network.
- Check if a periodic timeout has occurred.
If a packet has arrived, the input handler function, uip_input(),
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.
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 uip_periodic(). 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.
\section arch Architecture Specific Functions
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.
\subsection checksums Checksum Calculation
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.
While uIP includes a generic checksum function, it also leaves it open
for an architecture specific implementation of the two functions
uip_ipchksum() and uip_tcpchksum(). The checksum calculations in those
functions can be written in highly optimized assembler rather than
generic C code.
\subsection longarith 32-bit Arithmetic
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.
While uIP implements a generic 32-bit addition, there is support for
having an architecture specific implementation of the uip_add32()
function.
\section memory Memory Management
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.
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.
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.
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.
\section api Application Program Interface (API)
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.
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.
\sa \ref psock
\sa \ref pt
\subsection rawapi The uIP raw API
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.
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.
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -