This page aims to provide a brief introduction to the concepts and terminology of
UDP/IP networks, and how they relate to the FreeRTOS+UDP implementation.
The page contents do nothing more than provide a top level overview of
subjects that are otherwise comprehensive topics in their own rights. For
this reason references are provided to more in-depth discussions in the form
of hyperlinks to external web pages.
Do not be put off by the apparent
complexity of the topic. FreeRTOS+UDP takes care of the underlying
protocols. FreeRTOS+UDP users only need to know the meaning of the configuration
options, and how to use the
standard Berkeley sockets
"like" interface to send and receive data. Simple worked examples and an API
reference are provided on this website.
FreeRTOS+UDP is designed specifically for small embedded systems. Such
systems are normally, but by no means exclusively, connected via Ethernet.
On this page (topics best read in the order they appear):
FreeRTOS+UDP allows your embedded device to use the
Internet Protocol (IP)
to send data to, and receive data from, remote network nodes. The remote
nodes can be on the same local network, or on remote networks that are
accessible over the Internet.
User Datagram Protocol
(UDP) data is sent in connectionless packets. That means the
UDP and IP protocols do not guarantee delivery. Just like in RS232 or
RS485 communications, the node sending data cannot assume the intended
recipient received the data just because the data was sent onto the
network. This is where TCP/IP differs from UDP/IP. The TCP protocol
has a built in acknowledgement and re-transmission mechanism, UDP does not.
Therefore, UDP packets that require acknowledgement of receipt must be
manually acknowledged by the receiving application.
UDP is smaller, faster, and more suitable to fast embedded network
communication than TCP.
Different nodes on the same network are identified by their IP address. For example, each
network interface on the computer on which you are reading this text will
have a different IP address, as will every computer on the network to which
your computer is connected.
Each single network node can run multiple applications that use the
same network interface, and therefore use the same IP address. For example,
a FreeRTOS application can run a TFTP server, an echo server and a Nabto
client at the same time - all of which make use of the UDP/IP stack.
Different applications running on the same network node, and therefore
at the same IP address, are identified by their port number.
The source and destination address of each UDP packet is therefore a
combination of an IP address and a port number.
Each socket needs a unique address. As already stated, an address is
the combination of an IP address and a port number.
When a socket is
created it assumes the IP address of the network node that created it.
If a socket has an IP address but not a port number it is said to be
'unbound'. An unbound socket cannot receive data because it
does not have a complete address.
When a socket has both an IP address and a port number it is
said to be 'bound to a port', or 'bound to an address'. A bound socket
can receive data because it has a complete address.
The process of
allocating a port number to a socket is called 'binding'.
The API function FreeRTOS_bind()
is used to bind a FreeRTOS+UDP socket to a port number.
If ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 in FreeRTOSIPConfig.h
then FreeRTOS_bind() must be used to bind a socket to a port number before
the socket can be used to either send or receive data. If
ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 in FreeRTOSIPConfig.h
then an unbound socket will be automatically bound to a port number the
first time it attempts to send data, but can still only receive data after it
has been bound.
Servers are applications that wait for and then reply to incoming requests.
Clients are applications that send requests to servers. In this context,
the requests and replies go over the network.
Clients need to locate servers, and the simplest way to achieve this is by
having the server bind to a pre-agreed address (other more complex methods
Servers do not need to know the client's address in advance, they just
send their replies to the address from which the client's request originated.
Therefore clients can (normally) bind to nearly any port number, although high port
numbers in the range 0xC000 to 0xFFFF are reserved for use by FreeRTOS+UDP
itself, and many low port numbers are (by convention only)
reserved for common network services.
The standard echo service
provides a convenient example, and is the subject of the worked FreeRTOS+UDP demo application
available from this website. Echo servers simply echo back the data
sent to them by clients. Echo servers use port 7 by convention. The
sequence diagram below shows a socket being created and bound on both
an echo client and an echo server, and then a single echo transaction between
the client and the server (it should be noted that the sockets only need
to be created and bound once, not for each transaction).
A simple transaction between an echo client and an echo server
It has already been noted that each network node has an IP address.
If the IP address is 'static' then it is pre-assigned and never changed.
The FreeRTOS+UDP API function
takes a default IP address (among other addresses) as one of it's parameters.
The default IP address
is used as a static IP address if ipconfigUSE_DHCP is set to 0, or if
ipconfigUSE_DHCP is set to 1 but a DHCP server cannot be contacted.
See the description of DHCP below.
Static IP addresses are useful during application development, but they
are impractical for product deployment because:
They need to be hard coded either in the executable binary
or external flash memory.
IP addresses cannot be pre-assigned to products without prior knowledge of
the network environment in which the products will be deployed.
There is no prior knowledge of how many nodes will exist on the
network, or indeed how many of the possible total number of
nodes will be active at any one time.
DHCP provides an alternative to static IP address assignment. DHCP servers
exist on local networks to dynamically allocate IP addresses to nodes
on the same network. When a network enabled product boots up it contacts
the DHCP server to request its IP address, removing the need for each node to be
If ipconfigUSE_DHCP is set to 1 in FreeRTOSIPConfig.h
then FreeRTOS+UDP will attempt to obtain its IP address from a DHCP server,
and only revert to using a static IP address if a DHCP server cannot be
Sub-netting is a moderately complex topic, but for the purpose of writing
FreeRTOS+UDP applications, it can be thought of simply as a way of determining
whether a destination IP address exists on the local network or a remote
Like the IP address, the subnet mask can be configured either statically
as a parameter to FreeRTOS_IPInit(), or dynamically from a DHCP server.
If a destination IP address bitwise ANDed with the subnet mask matches
the local IP address bitwise ANDed with the subnet mask then the two
IP addresses exist on the same network.
If a destination IP address bitwise ANDed with the subnet mask does
not match the local IP address bitwise ANDed with the subnet
mask then the two IP addresses do not exist on the same network.
In this case the packet being sent to the destination address cannot
be sent directly, and must instead be sent to a gateway for intelligent
FreeRTOS+UDP determines whether a UDP packet can be sent directly, or if
it needs to be routed through a gateway. FreeRTOS+UDP users only need
to provide a gateway address. Like the IP address, the IP address of a
gateway can be configured either statically as a parameter to
FreeRTOS_IPInit(), or dynamically from a DHCP server.
Using raw IP addresses is not always practical because:
IP addresses can change.
The IP address of a remote computer might not be known.
IP addresses are not very memorable.
Domain Name System (DNS)
provides a solution to this problem by mapping static and easily human
readable textual (rather than numerical) names to IP addresses.
A domain name server resolves the text domain name to the appropriate IP address.
For example, entering "ping www.freertos.org" in the command console of a
desktop computer will show a ping request being sent to the IP address
22.214.171.124 (today, anyway) because a DNS server resolved the string
"www.freertos.org" to the IP address 126.96.36.199.
Assuming a conventional wired network is used, UDP messages are sent in
Ethernet frames. UDP messages are sent between IP addresses, but
Ethernet frames are sent between MAC (hardware) addresses. Therefore the
MAC address of the destination IP address must be known before an
Ethernet frame can be created.
The Address Resolution Protocol
(ARP) is used to obtain MAC address information. FreeRTOS+UDP
(like most if not all IP stacks) stores IP address to MAC address mappings
in an ARP table (sometimes called the ARP cache).
Different microcontrollers store multi byte values, such as a two byte
uint16_t or a four byte uint32_t, in different ways. Microcontrollers that
store the most significant byte first are called big endian. Microcontrollers
that store the least significant byte first are called little endian.
The way bytes are stored on the microcontroller on which FreeRTOS+UDP is running
is called the host byte order.
It is rare for the writer of a non connected application to need to concern
themselves with how their target microcontroller stores data internally.
If data is written to memory in little endian order, it will be read back
from memory in little endian order - and so the value read back will
match the value originally written.
It is more complicated when microcontrollers are connected, because there
are no guarantees that all the microcontrollers on a connected network
will have the same byte order. All the microcontrollers on the network
have to agree the byte order used to send and receive data in advance.
The byte order used for data in transit is called the network byte
In UDP/IP networks data is sent most significant byte first,
making UDP/IP networks effectively big endian. Therefore,
a little endian microcontroller sending to a UDP/IP network must swap the
order in which bytes appear within multi byte values before the values
are sent onto the network, and must swap the order in which bytes
appear in multi byte values received from the network before the values
are used. A big endian microcontrollers does not need to perform any
byte swapping because the endian of the microcontroller (the host byte
order) matches the agreed endian of the network (the network byte order).