emNet
User Guide & Reference Manual
Document: UM07001
Software Version: 3.42.3
Document revision: 0
Introduction to emNet
This chapter provides an introduction to using emNet. It explains the basic concepts behind emNet.
What is emNet
emNet is a CPU-independent TCP/IP stack.
emNet is a high-performance library that has been optimized for speed, versatility and small memory footprint.
Features
emNet is written in ANSI C and can be used on virtually any CPU.
Some features of emNet:
- Standard socket interface.
- High performance.
- Small footprint.
- No configuration required.
- Runs “out-of-the-box”.
- Very simple network interface driver structure.
- Works seamlessly with embOS in multitasking environment.
- Zero data copy for ultra fast performance.
- Non-blocking versions of all functions.
- Connections limited only by memory availability.
- Delayed ACKs.
- Handling gratuitous ARP packets
- Support for VLAN
- BSD style “keep-alive” option.
- Support for messages and warnings in debug build.
- Drivers for most common Ethernet controllers available.
- Support for driver side (hardware) checksum computation.
- Royalty-free.
Basic concepts
emNet structure
emNet is organized in different layers, as shown in the following illustration.
A short description of each layer’s functionality follows below.
Application layer
The application layer is the interface between emNet and the user application. It
uses the emNet API to transmit data over an TCP/IP network. The emNet API
provides functions in BSD (Berkeley Software Distribution) socket style, such as
connect(), bind(), listen(), etc.
Transport layer
The transport layer provides end-to-end communication services for applications. The
two relevant protocols of the Transport layer protocol are the Transmission Control
Protocol (TCP) and the User Datagram Protocol (UDP). TCP is a reliable connection-oriented
transport service. It provides end-to-end reliability, resequencing, and flow
control. UDP is a connectionless transport service.
Internet layer
All protocols of the transport layer use the Internet Protocol (IP) to carry data from
source host to destination host. IP is a connectionless service, providing no end-to-end
delivery guarantees. IP datagrams may arrive at the destination host damaged,
duplicated, out of order, or not at all. The transport layer is responsible for reliable
delivery of the datagrams when it is required. The IP protocol includes provision for
addressing, type-of-service specification, fragmentation and reassembly, and
security information.
Link layer
The link layer provides the implementation of the communication protocol used to
interface to the directly-connected network. A variety of communication protocols
have been developed and standardized. The most commonly used protocol is Ethernet
(IEEE 802.3). In this version of emNet only Ethernet is supported.
Encapsulation
The four layers structure is defined in [RFC 1122]. The data flow starts at the application
layer and goes over the transport layer, the network layer, and the link layer.
Every protocol adds a protocol-specific header and encapsulates the data and header from the
layer above as data. On the receiving side, the data will be extracted in the complementary direction.
The opposed protocols do not know which protocol on the above and below layers are used.
The following illustration shows the encapsulation of data within an UDP datagram
within an IP packet.
Tasks and interrupt usage
emNet can be used in an application in three different ways.
- One task dedicated to the stack (IP_Task)
- Two tasks dedicated to the stack (IP_Task, IP_RxTask)
- Zero tasks dedicated to the stack (Superloop)
The default task structure is one task dedicated to the stack. The priority of the
management task IP_Task should be higher then the priority of all application tasks that
use the stack to allow optimal performance. The IP_RxTask (if available) should
run at the highest single task priority of all IP related task as it is an interrupt moved
into a task.
Task priorities
IP task priorities are independent from other (non IP) task priorities. However as soon as a task
calls an IP API it should follow these priority rules for the best performance of the stack:
- The IP_RxTask (if used at all) should have the highest single priority of all
tasks that make use of the IP API, having a higher priority than the IP_Task .
- The IP_Task should have a higher task priority than any other task that makes
use of the IP API. It should have a lower priority than the IP_RxTask (if used at all).
- All tasks that make use of the IP API should use a task priority below the IP_Task
to allow optimal performance.
Task priorities for tasks not using the IP API can be freely chosen.
One task dedicated to the stack
Using one task dedicated to the stack is the simplest way to use the TCP/IP stack. It
is called IP_Task and handles housekeeping operations, resending and handling of
incoming packets. The “Read packet” operation is performed from within the ISR.
Because the “Read packet” operation is called directly from the ISR, no additional
task is required. The length of the interrupt latency will be extended for the time
period which is required to process the “Read packet” operation. Refer to IP_Task
for more information and an example about how to include the IP_Task
into your project.
Two tasks dedicated to the stack
The first task is called the IP_Task and handles
housekeeping operations, resends, and handling of incoming packets. The second is
called IP_RxTask and handles the “Read packet” operation. IP_RxTask is woken up
from the interrupt service routine if new packets are available. The interrupt latency
is not extended, because the “Read packet” operation has been moved from the
interrupt service routine to IP_RxTask. Refer to IP_Task and
IP_RxTask for more information. IP_RxTask should have a higher priority
than IP_Task as it is treated as interrupt in task form and should not be interrupted
by IP_Task or any other IP task.

Note
Initializing the IP stack with two task concept from main()
Packets might receive as soon as Ethernet is initialized by IP_Init() and the (receive) interrupt
is enabled. The internal switch between the single task and two task concept gets set automatically
upon the first execution of IP_RxTask() . Initializing the stack from main() typically means to
initialize it before a task scheduler is active.
If a packet is received between IP_Init() and the first run of IP_RxTask() the packet will be processed
like in the single task concept. This should typically cause no problem to the application and the mode
is automatically switched to the two task concept as soon as IP_RxTask() has run for the first time.
If it is desired to completely avoid this to happen, the following steps need to be taken care of:
- Call IP_SetUseRxTask() manually (best placed after calling IP_Init() and adding the two tasks)
to switch to the two task concept early.
- The Ethernet interrupt enable (typically in BSP_IP.c) needs to be manually moved to after
calling IP_Init() and IP_SetUseRxTask() .
Zero tasks dedicated to the stack (Superloop)
emNet can also be used without any additional task for the stack if an application
task calls IP_Exec() periodically. The “Read packet” operation is performed from
within the ISR. Because the “Read packet” operation is called directly from the ISR,
no additional task is required. The length of the interrupt latency will be extended for
the time period which is required to process the “Read packet” operation.
Components of an Ethernet system
Main parts of an Ethernet system are the Media Access Controller (MAC) and the
Physical device (PHY). The MAC handles generating and parsing physical frames and
the PHY handles how this data is actually moved to or from the wire.
MCUs with integrated MAC
Some modern MCUs (for example, the ATMEL SAM7X or the ST STR912) include the
MAC and use the internal RAM to store the Ethernet data. The following block
diagram illustrates such a configuration.
External Ethernet controllers with MAC and PHY
Chips without integrated MAC can use fully integrated single chip Ethernet MAC
controller with integrated PHY and a general processor interface. The following
schematic illustrates such a configuration.
MII / RMII: Interface between MAC and PHY
The MAC communicates with the PHY via the Media Independent Interface (MII) or
the Reduced Media Independent Interface (RMII). The MII is defined in IEEE 802.3u.
The RMII is a subset of the MII and is defined in the RMI specification. The MII/RMII
can handle control over the PHY which allows for selection of such transmission criteria
as line speed, duplex mode, etc.
In theory, up to 32 PHYs can be connected to a single MAC. In praxis, this is never
done; only one PHY is connected. In order to allow multiple PHYs to be connected to
a single MAC, individual 5-bit addresses have to be assigned to the different PHYs. If
only one PHY is connected, the emNet driver automatically finds the address of it.
The standard defines 32 16-bit PHY registers. The first 6 are defined by the standard.
Register | Description |
BMCR | Basic Mode Control Register |
BSR | Basic Mode Status Register |
PHYSID1 | PHYS ID 1 |
PHYSID2 | PHYS ID 2 |
ANAR | Auto-Negotiation Advertisement Register |
LPAR | Link Partner Ability register |
The drivers automatically recognize any PHY connected, no manual configuration of
PHY address is required.
The MII and RMII interface are capable of both 10Mb/s and 100Mb/s data rates as
described in the IEEE 802.3u standard.
The intent of the RMII is to provide a reduced pin count alternative to the IEEE
802.3u MII. It uses 2 bits for transmit (TXD0 and TXD1) and two bits for receive
(RXD0 and RXD1). There is a Transmit Enable (TX_EN), a Receive Error (RX_ER), a
Carrier Sense (CRS), and a 50 MHz Reference Clock (TX_CLK) for 100Mb/s data rate.
The pins used by the MII and RMII interfaces are described in the following table.
Signal | MII | RMII |
TX_CLK | Transmit Clock (25 MHz) | Reference Clock (50 MHz) |
TX_EN | Transmit Enable | Transmit Enable |
TXD[0:1] | 4-bit Transmit Data | 2-bit Transmit Data |
TXD[2:3] | 4-bit Transmit Data (cont’d) | N/A |
PHYCLK | PHY Clock Output | PHY Clock Output |
CRS | Carrier Sense | N/A |
COL | Collision Detect | N/A |
MDIO | Management data I/O | Management data I/O |
MDC | Data Transfer Timing Reference Clock | Data Transfer Timing Reference Clock |
RX_CLK | Receive Clock | N/A |
RXD[0:1] | 4-bit Receive Data | 2-bit Receive Data |
RXD[2:3] | 4-bit Receive Data (cont’d) | N/A |
RX_DV | Data Valid | Carrier Sense/Data Valid |
RX_ER | Receive Error | Receive Error |
Further reading
This guide explains the usage of the emNet protocol stack. It describes all
functions which are required to build a network application. For a deeper understanding
about how the protocols of the Internet protocol suite works use the following
references.
The following Request for Comments (RFC) define the relevant protocols of the Internet
protocol suite and have been used to build the protocol stack. They contain all
required technical specifications. The listed books are simpler to read as the RFCs
and give a general survey about the interconnection of the different protocols.
RFC# | Description |
[RFC 768] | UDP - User Datagram Protocol
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc768.txt
|
[RFC 791] | IP - Internet Protocol
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc791.txt
|
[RFC 792] | ICMP - Internet Control Message Protocol
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc792.txt
|
[RFC 793] | TCP - Transmission Control Protocol
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc793.txt
|
[RFC 821] | SMTP - Simple Mail Transfer Protocol
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc826.txt
|
[RFC 826] | ARP - Ethernet Address Resolution Protocol
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc826.txt
|
[RFC 951] | BOOTP - Bootstrap Protocol
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc951.txt
|
[RFC 959] | FTP - File Transfer Protocol
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc959.txt
|
[RFC 1034] | DNS - Domain names - concepts and facilities
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc1034.txt
|
[RFC 1035] | DNS - Domain names - implementation and specification
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc1035.txt
|
[RFC 1042] | IE-EEE - Transmission of IP datagrams over IEEE 802 networks
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc1042.txt
|
[RFC 1122] | Requirements for Internet Hosts - Communication Layers
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc1122.txt
|
[RFC 1123] | Requirements for Internet Hosts - Application and Support
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc1123.txt
|
[RFC 1661] | PPP - Point-to-Point Protocol
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc1661.txt
|
[RFC 1939] | POP3 - Post Office Protocol - Version 3
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc1939.txt
|
[RFC 2131] | DHCP - Dynamic Host Configuration Protocol
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc2131.txt
|
[RFC 2616] | HTTP - Hypertext Transfer Protocol -- HTTP/1.1
Direct download: ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt
|
- [Comer] - Computer Networks and Internets, Douglas E Comer and Ralph E.
Droms - ISBN: 978-0131433519
- [Tannenbaum] - Computer Networks, Andrew S. Tannenbaum
ISBN: 978-0130661029
- [StevensV1] - TCP/IP Illustrated, Volume 1, W. Richard Stevens
ISBN: 978-0201633467.
- [StevensV2] - TCP/IP Illustrated, Volume 2, W. Richard Stevens and Gary R.
Wright - ISBN: 978-0201633542.
- [StevensV3] - TCP/IP Illustrated, Volume 3, W. Richard Stevens
ISBN: 978-0201634952.
Development environment (compiler)
The CPU used is of no importance; only an ANSI-compliant C compiler complying with
at least one of the following international standard is required:
- ISO/IEC/ANSI 9899:1990 (C90) with support for C++ style comments (//)
- ISO/IEC 9899:1999 (C99)
- ISO/IEC 14882:1998 (C++)
If your compiler has some limitations, let us know and we will inform you if these will
be a problem when compiling the software. Any compiler for 16/32/64-bit CPUs or
DSPs that we know of can be used; most 8-bit compilers can be used as well.
A C++ compiler is not required, but can be used. The application program can therefore
also be programmed in C++ if desired.
Running emNet on target hardware
This chapter explains how to integrate and run emNet on your target hardware.
It explains this process step-by-step.
Integrating emNet
The emNet default configuration is preconfigured with valid values, which
matches the requirements of the most applications. emNet is designed to be used
with embOS, SEGGER’s real-time operating system. We recommend to start with an
embOS sample project and include emNet into this project.
We assume that you are familiar with the tools you have selected for your project
(compiler, project manager, linker, etc.). You should therefore be able to add files,
add directories to the include search path, and so on. In this document the
SEGGER Embedded Studio
is used for all examples and screenshots, but every other
ANSI C toolchain can also be used. It is also possible to use make files; in this case,
when we say “add to the project”, this translates into “add to the make file”.
Procedure to follow
Integration of emNet is a relatively simple process, which consists of the following steps:
- Step 1: Open an embOS project and compile it.
- Step 2: Add emNet to the start project
- Step 3: Compile the project
Step 1: Open an embOS start project
We recommend that you use one of the supplied embOS start projects for your target
system. Compile the project and run it on your target hardware.
Step 2: Adding emNet to the start project
Add all IP source files as in the IP release delivery to your project.
The Config folder includes all configuration files of emNet. The configuration files
are preconfigured with valid values, which match the requirements of most applications.
Add the hardware configuration IP_Config_<TargetName>.c supplied with the
driver shipment.
If your hardware is currently not supported, use the example configuration file and
the driver template to write your own driver. The example configuration file and the
driver template is located in the Sample folder.
The IP\ASM folder contains files for various CPUs and toolchains with routines optimized
in assembler code. Typically only one of these files needs to be added to your
project and the rest should be excluded. The optimized routines are used by overwriting
a specific macro that typically can be found in Config\IP_Conf.h.
The SEGGER folder is an optional component of the emNet shipment. It contains
optimized MCU and/or compiler specific files, for example a special memcopy function.
BSP support
IP drivers need hardware setting from the BSP file (like port settings for example).
Some older driver are supplied with BSP.c and BSP.h that need to replace the one
supplied with embOS shipment.
Newer and updated drivers have a separate BSP_IP.c file instead.
Depending on your case, either
replace BSP.c and BSP.h of your embOS start project or add BSP_IP.c.
Configuring the include path
The include path is the path in which the compiler looks for include files. In cases
where the included files (typically header files, .h ) do not reside in the same directory
as the C file to compile, an include path needs to be set. In order to build the
project with all added files, you will need to add the IP directories to your
include path.
Select the start application
For quick and easy testing of your emNet integration, start with the code found in
the folder Application. Add one of the applications to your project (for example
IP_SimpleServer.c).
Step 3: Build the project and test it
Build the project. It should compile without errors and warnings. If you encounter
any problem during the build process, check your include path and your project configuration
settings. To test the project, download the output into your target and
start the application.
By default, ICMP is activated. This means that you could ping your target. Open the
command line interface of your operating system and enter ping <TargetAddress>,
to check if the stack runs on your target. The target should answer all pings without
any error.
Example applications
In this chapter, you will find a description of each emNet example application.
Overview
Various example applications for emNet are supplied. These can be used for testing
the correct installation and proper function of the device running emNet.
The following start application files are provided:
File | Description |
IP_DNSClient.c | Demonstrates the use of the integrated DNS client. |
IP_NonBlockingConnect.c | Demonstrates how to connect to a server using non-blocking sockets. |
IP_Ping.c | Demonstrates how to send ICMP echo requests and how to process ICMP
replies in application. |
IP_SHELL_Start.c | Demonstrates using the IP-shell to diagnose the IP stack. |
IP_SimpleServer.c | Demonstrates setup of a simple server which simply sends back the
target system tick for every character received. |
IP_SpeedClient_TCP.c | Demonstrates the TCP send and receive performance of the device
running emNet. |
IP_Start.c | Demonstrates use of the IP stack without any server or client program.
To ping the target, use the command line: ping <target-ip> where
<target-ip> represents the IP address of the target, which depends
on the configuration and is usually 192.168.2.252 if the DHCP client
is not enabled. |
IP_UDPDiscover.c | Demonstrates setup of a simple UDP application which replies to UDP
broadcasts. The application sends an answer for every received discover
packet. The related host application sends discover packets as UDP
broadcasts and waits for the feedback of the targets which are available
in the subnet. |
IP_UDPDiscover_ZeroCopy.c | Demonstrates setup of a simple UDP application which replies to UDP
broadcasts. The application uses the the emNet zero-copy interface. It
sends an answer for every received discover packet. The related host
application sends discover packets as UDP broadcasts and waits for
the feedback of the targets which are available in the subnet. |
The example applications for the target-side are supplied in source code in the
Application directory.
emNet DNS client (IP_DNSClient.c)
The emNet DNS client resolves a hostname (for example, segger.com) to an IP
address and outputs the resolved address via terminal I/O.
emNet non-blocking connect (IP_NonBlockingConnect.c)
The emNet non-blocking connect sample demonstrates how to connect to a
server using non-blocking sockets. The target tries to connect to TCP server with an
non-blocking socket. The sample can be used with any TCP server independent of the
application which is listening on the port. The client only opens a TCP connection to
the server and closes it without any further communication. The terminal I/O output
in your debugger should be similar to the following out:
Connecting using non-blocking socket...
Successfully connected after 2ms!
1 of 1 tries were successful.
Connecting using non-blocking socket...
Successfully connected after 1ms!
2 of 2 tries were successful.
emNet ping (IP_Ping.c)
The emNet ping sample demonstrates how to send ICMP echo requests and how
to process received ICMP packets in your application. A callback function is
implemented which outputs a message if an ICMP echo reply or an ICMP echo request has
been received.
To test the emNet ICMP implementation, you have to perform the following steps:
- Customize the Local defines, configurable section of IP_Ping.c.
Change the macro HOST_TO_PING according to your configuration. For example, if
the Windows host PC which you want to ping use the IP address 192.168.5.15,
change the HOST_TO_PING macro to 0xC0A8050F.
- Open the command line interface and enter:
ping [IP_ADDRESS _OF_YOUR_TARGET_RUNNING_EMNET]
The terminal I/O output in your debugger should be similar to the following out:
ICMP echo reply received!
ICMP echo request received!
ICMP echo reply received!
ICMP echo reply received!
ICMP echo reply received!
ICMP echo reply received!
ICMP echo request received!
ICMP echo reply received!
ICMP echo reply received!
ICMP echo reply received!
emNet shell (IP_SHELL_Start.c)
The emNet shell server is a task which opens TCP-port 23 (telnet) and waits for a
connection. The actual shell server is part of the stack, which keep the application
program nice and small. The shell server task can be added to any application and
should be used to retrieve status information while the target is running. To connect
to the target, use the command line: telnet <target-ip> where <target-ip>
represents the IP address of the target, which depends on the configuration and is
usually 192.168.2.252 if the DHCP client is not enabled.
emNet simple server (IP_SimpleServer.c)
Demonstrates setup of a simple server which simply sends back the target system
tick for every character received. It opens TCP-port 23 (telnet) and waits for a connection.
To connect to the target, use the command line: telnet <target-ip>
where <target-ip> represents the IP address of the target, which depends on the
configuration and is usually 192.168.2.252 if the DHCP client is not enabled.
emNet speed client (IP_SpeedClient_TCP.c)
The emNet speed client is a small application to detect the TCP send and receive
performance of emNet on your hardware.
Running the emNet speed client
To test the emNet performance, you have to perform the following steps:
- Start the Windows speed test server. The example application for the host-side is
supplied as executable and in source code in the Windows\SpeedTestServer\ directory.
To run the speed test server, simply start the executable, for example by double-clicking
it or open the supplied Visual C project and compile and start the application.
- Add IP_SpeedClient.c to your project.
- Customize the Local defines, configurable section of IP_SpeedClient.c.
Change the macro SERVER_IP_ADDR according to your configuration. For example,
if the Windows host PC running the speed test server uses the IP address
192.168.5.15, change the SERVER_IP_ADDR macro to 0xC0A8050F. If you have
changed the port which the Windows host application uses to listen, change the
macro SERVER_PORT accordingly.
- Build and download the speed client into your target. The target connects to the
server and starts the transmission.
emNet start (IP_Start.c)
Demonstrates use of the IP stack without any server or client program. To ping the
target, use the command line: ping <target-ip> where <target-ip> represents the
IP address of the target, which depends on the configuration and is usually
192.168.2.252 if the DHCP client is not enabled.
emNet UDP discover (IP_UDPDiscover.c / IP_UDPDiscover_ZeroCopy.c)
To test the emNet UDP discover example, you have to perform the following
steps:
- Start the Windows UDP discover example application. The example application for the
host-side is supplied as executable and in source code in the Windows\UDPDiscover\
directory. To run the UDP discover example, simply start the executable, for example
by double-clicking it or open the supplied Visual C project and compile and start the
application.
- Add IP_UDPDiscover.c to your project.
- Customize the Local defines, configurable section of IP_UDPDiscover.c.
By default, the example uses port 50020. If you have changed the port that the
Windows host application uses, change the macro PORT accordingly.
- Build and download the UDP discover example into your target. The target sends
an answer for every received discover packet. The related host application sends
discover packets as UDP broadcasts and waits for the feedback of the targets
which are available in the subnet.
Core functions
In this chapter, you will find a description of each emNet core function.
API functions
The table below lists the available API functions within their respective categories.