INtime SDK Help
High-Performance Ethernet
INtime SDK v6 > About INtime > Networking and I/O > High-Performance Ethernet

About HPE

The INtime High-Performance Ethernet interface provides a high degree of control over the Ethernet hardware in order to enable high-performance applications to take maximum advantage of the features of the interface. It is ideally suited to applications where minimal latency between application and interface is important. Examples of such applications might be industrial Ethernet-based fieldbus implementations, and time synchronization protocols.

The philosophy of the HPE design is to allow the programmer as much control as possible over the operation of the Ethernet controller, including memory management and the operation of the DMA engine. For example, attaching the transmit frames to the controller in advance of issuing the command to start transmission allows the controller to start to buffer the data so that any FIFOs are loaded before the transmission starts, thus reducing the time between issuing the command the the operation starting

Theory of Operation

The interface architecture separates the queuing of Ethernet datagrams for transmission and the start of the transmit cycle. This allows for the application to provide the send and receive buffers used directly by the DMA engine, and to control precisely when the transmission starts.

INtime's High-performance Ethernet system calls perform the following actions:

Each Ethernet interface under the control of this software is identified by a short text name. This is determined when the driver loads. An application accesses an interface by opening it. A handle is returned which is then used in all subsequent calls to the same interface until the interface closes.

Since HPE operation directly accesses the network device hardware, a single network device cannot be used directly as a HPE device and as a INtime Network (TCP/IP) device at the same time. If both HPE and TCP/IP are required, you need at least two network devices, or you can use the XCNT "connector" driver to forward packets to and from the network stack from your HPE application.
Alternatively, if both low level Ethernet operation and TCP/IP are required using a single network device, consider using BPF and/or pcap. BPF/pcap are part of INtime network system. BPF/pcap are not as fast as HPE but they allow sending/receiving raw Ethernet frames as well as regular TCP/IP packets using the same network device.

HPE3 Extensions

HPE3 is the newest release of the interface and takes advantage of extended functionality available in some advanced Ethernet controllers, especially the Intel i210 controller. The extended functionality for HPE3 is in four areas:

  1. Multi-queue support for transmit and receive. Most of the original calls are now implemented as queue-specific calls. For example hpeAttachReceiveBufferSetToQueue supersedes hpeAttachReceiveBufferSet; the original call is an alias for queue 0. Any code written for HPE2 will continue to work with HPE3.
  2. QaV transmission features – timed transmit descriptors and use of a global time offset to reset the transmit times on all descriptors.
  3. IEEE1588 timer access and control – access to the 1588 timer, 1588 counter arithmetic and use as an interrupt source for timer interrupts from the device.
  4. Receive filtering – sort incoming traffic into different queues for prioritization or other filtering. Not all features are available on all interfaces, so call hpeGetQueueConfiguration to determine which features are available. Note: in the initial release of the driver the extended features are only available for the Intel i210 interface.

The enhancements implemented in the HPE3 interface combined with the hardware features of the Intel i210 controller allow for the creation of high-performance, high-precision Ethernet applications well suited to the requirements of a range of demanding industrial applications.

A transmit queue can be one of two types. A "priority" queue is the default type and the queue can be assigned a priority. Packets will be transmitted from a high-priority queue before a low-priority queue. This feature can be used for traffic shaping or QoS management. A queue can alternatively be designated as a "stream" queue. Queues of this type transmit packets according to a timer descriptor which uses built-in timer hardware to determine when to transmit packets in the queue. This gives the device isochronous capability and this feature is very useful in the design of industrial Ethernet implementations, for example.

Incoming packets may be filtered using internal filtering hardware and the packets delivered to a different queue depending on its content. This feature may be used to prioritize incoming traffic for example. High-priority traffic would be delivered to the first queue, lower-priority traffic to a second queue, etc.

Sample applications

Three sample applications are included with the product. A general HPE sample application "High Performance Ethernet Sample" illustrates how to use the HPE API to send and receive Ethernet frames. It includes a WIndows application to also send and receive frames using the WinPCAP interface.

A second sample, "HPE3 Extra Features Sample", illustrates some of the advanced features of the HPE3 interface. Included are examples for the following:

A third sample, "XCNT-HPE Sample" illustrates how an HPE application can interact with the TCP/IP stack using the Ethernet Connector driver (XCNT), acting as a filter or monitor for IP traffic.

HPE library calls

This lists common operations related to High-performance Gigabit Ethernet and the INtime system calls that do the operations.

Library calls

To . . . Use this system call . . .
Initialization and configuration  
Initialize an Ethernet interface hpeOpen
Similar to hpeOpen; specify additional options hpeOpenWithOptions
Close an Ethernet interface indicated by the handle parameter hpeClose
Obtain information about the hardware interface hpeGetInterfaceInfo
Configure options for the Ethernet controller, such as multicast packet reception hpeConfigOptions
Obtain a list of queue features supported by the hardware interface hpeGetQueueConfiguration
Report the interface's 6-byte MAC address hpeGetMacAddress
Report the current status of the media interface of the Ethernet controller hpeGetMediaStatus
Obtain statistics from a queue hpeGetQueueStats
Receive  
Allocate a receive buffer set which is compatible with the network device hpeAllocateReceiveBufferSet
Attaches a set of receive buffers to a queue for use by the DMA engine to receive Ethernet frames. hpeAttachReceiveBufferSetToQueue
Attach a set of receive buffers to queue 0 for use by the DMA engine to receive Ethernet frames. hpeAttachReceiveBufferSet
Free memory allocated by hpeAllocateReceiveBufferSet hpeFreeReceiveBufferSet
Return a pointer to the next receive buffer in the default receive queue which has a fully-received frame in it hpeGetReceiveBuffer
Return a pointer to the next receive buffer in the designated queue which has a fully-received frame in it. hpeGetReceiveQueueBuffer
Returns the receive buffer obtained by hpeGetReceiveBuffer to the network device on queue 0. hpeReturnReceiveBuffer
Returns the receive buffer obtained by hpeGetReceiveBuffer to the network device on the designated queue. hpeReturnReceiveQueueBuffer
Determine the queue to receive packets that are not matched by a filter. hpeSetDefaultReceiveQueue
Enable or disable receipt of all packets (promiscuous mode) at the device. hpeSetPromiscuousMode
Set the type of a receive queue. hpeSetReceiveQueueAttributes
Enable a receive queue filter by setting its parameters. hpeSetReceiveQueueFilter
Instruct the caller to sleep until the next receive interrupt occurs for the default queue. hpeWaitForReceiveComplete
Instruct the caller to sleep until the next receive interrupt occurs for the designated queue. hpeWaitForReceiveQueueComplete
Transmit  
Attach a set of transmit buffers to the driver on queue 0. hpeAttachTransmitBufferSet
Attach a set of transmit buffers to the driver on designated queue. hpeAttachTransmitBufferSetToQueue
Return a value indicating the current state of the transmitter of queue 0. hpeGetTransmitterState
Return a value indicating the current state of the transmitter of the designated queue. hpeGetTransmitterQueueState
Set the time to subtract from the launch time to begin packet fetch. hpeSetTransmitFetchDelta
Set the type of a transmit queue. hpeSetTransmitQueueAttributes
Set the global offset to be added to the launch time. hpeSetTransmitTimeOffset
Set the priority of a transmit queue. hpeSetTransmitQueuePriority
Cause the transmitter to transmit any and all frames which are ready to be sent from queue 0. hpeStartTransmitter
Cause the transmitter to transmit any and all frames which are ready to be sent from designated queue. hpeStartTransmitterQueue
Instruct the caller to sleep until the next transmit interrupt occurs for queue 0. hpeWaitForTransmitComplete
Instruct the caller to sleep until the next transmit interrupt occurs for the designated queue. hpeWaitForTransmitQueueComplete
Timers and IEEE 1588 Time Support  
Signal a semaphore when a target time is reached. hpeSetTargetTimer
Read the 1588 time from the controller. hpe1588GetSystemTime
Write the 1588 time to the controller. hpe1588SetSystemTime
Adjust the 1588 system clock in the controller. hpe1588AdjustSystemTime
Set the offset at which the 1588 timestamp is written in transmit packets. hpe1588SetTimestampOffset
Retrieve the receive timestamp from the packet buffer. hpe1588GetRxTimestamp
Retrieve the timestamp for the most recently transmitted packet. hpe1588GetTxTimestamp
Retrieve the size of the timestamp header. hpe1588GetRxTimestampHeaderSize
Add two 1588 time values. hpe1588TimeAdd
Subtract a 1588 time values from another. hpe1588TimeSubtract
Compare two 1588 time values. hpe1588TimeCompare
Return the difference between two 1588 time values. hpe1588TimeDifference

Structures

To . . . Use this structure . . .
Specify options; used by hpeConfigOptions HPE_CONFIG_OPTIONS
Specify options; used by hpeOpenWithOptions HPE_OPEN_OPTIONS
Describe a queue configuration HPEQUEUECONFIG
Describe an individual buffer to hold frame data HPEBUFFER
Obtain information about the currently-connected media HPEMEDIASTATUS
Describe a set of receive frame buffers HPERXBUFFERSET
Describe a single transmit buffer HPETXBUFFER
Describe a transmit buffer set, consisting of multiple transmit buffers HPETXBUFFERSET
Describe a single transmit stream buffer HPETXSTREAMBUFFER
Describe a transmit stream buffer set, consisting of multiple transmit stream buffers HPETXSTREAMBUFFERSET
Describe a IEEE1588 timestamp HPE_1588_TIMESTAMP
Define an Ether type filter HPE_ETHER_FILTER
Define a Flex Data filter HPE_FLEX_FILTER
Define a 2-Tuple filter HPE_2TUPLE_FILTER

Operations

This section illustrates some possible operations using this API.

Initialization

To initialize the interface it is necessary to open it, then attach receive buffers, and attach transmit buffers. For example:

HPE initialization
Copy Code
HPESTATUS status;
HPEHANDLE handle;
HPERXBUFFERSET *rx_buffers;
HPETXBUFFERSET *tx_buffers;
int i;
char *p;
static char fixed_header[56];   // 56-byte fixed header for each transmitted frame


status = hpeOpen("ie1g0", SPEED_100|DUPLEX_FULL, ALL_INTERRUPTS, &handle);
// allocate 4 receive buffers and attach them
status  = hpeAllocateReceiveBufferSet(handle, &rx_buffers, 4, ETH_FRAME_SIZE);
status = hpeAttachReceiveBufferSet(handle, rx_buffers);
// allocate 1 transmit buffer of two fragments and 500 bytes and attach it
tx_buffers = AllocateRtMemory(4096);
p = (char *)&tx_buffers->buffers[1];
tx_buffers->buffer_count = 1;
tx_buffers->buffers[0].fragment_count = 2;
// first fragment is the fixed header, second is dynamic data
tx_buffers->buffers[0].fragments[0].ptr = fixed_header;
tx_buffers->buffers[0].fragments[0].size = 56;
tx_buffers->buffers[0].fragments[0].paddr = 0;
tx_buffers->buffers[0].fragments[1].ptr = p;
tx_buffers->buffers[0].fragments[1].size = 444;
tx_buffers->buffers[0].fragments[1].paddr = 0;

status = hpeAttachTransmitBufferSet(handle, tx_buffers);

Transmit a frame without interrupts

Once the interface is set up, load the data, attach the transmit set and start the transmitter.


Transmit a frame
Copy Code
// user function to initialize the frames to be transmitted
FillTransmitPayload(tx_buffers[0].fragments[1].ptr);

hpeAttachTransmitBufferSet(handle, tx_buffers);
status = hpeStartTransmitter(handle);

// wait for 1 second:
status = hpeWaitForTransmitComplete(handle, 1000);
Receive frames

First check to see if a buffer is available then process the data in it. Once the buffer has been received the buffer may be reused.

Receive frames
Copy Code
// user function to initialize the frames to be transmitted
HPEBUFFER *rxbuffer;

hpeWaitForReceiveComplete(handle, 1000);
if (hpeGetReceiveBuffer(handle, &rxbuffer) == E_OK)
    process_buffer_data(rxbuffer->ptr, rxbuffer->used);       // user function
Prepare interface for STREAM processing

Open the interface then set up the transmit and receive queues as desired. In this example we are going to designate transmit queue 0 as a STREAM (i.e. QAV) queue, and transmit queue 1 as a priority queue. The receive filter will be set to receive PROFINET frames into receive queue 0 and all other traffic to receive queue 1.

Example Title
Copy Code
HPESTATUS status;
HPEHANDLE hpe;
HPERXBUFFERSET *rx_buffers_q0;
HPERXBUFFERSET *rx_buffers_q1;
HPETXSTREAMBUFFERSET *tx_buffers;
HPE_ETHER_FILTER eth_filter;
TIMESTAMP_1588 now, next;
int i; 
char *p; 
static char fixed_header[56];   // 56-byte fixed header for each transmitted frame

// Open the Intel Gigabit driver
status = hpeOpen(“ie1g0”, SPEED_100|DUPLEX_FULL, ALL_INTERRUPTS, &hpe);

// Queue 0 is set to be a STREAM queue
// Queue 1 is a PRIORITY queue by default
status = hpeSetTransmitQueueAttributes(hpe, 0, HPE_TX_STREAM); 

 

// all non-filtered traffic will be received in RX queue 1
status = hpeSetDefaultReceiveQueue(hpe, 1); 

// allocate 4 receive buffers and attach them 
status = hpeAllocateReceiveBufferSet(hpe, &rx_buffers, 4,
                ETH_FRAME_SIZE+sizeof(HPE_1588_TIMESTAMP)); 
status = hpeAttachReceiveBufferSetToQueue(hpe, 0, rx_buffers_q0);

// allocate and attach the set of receive buffers to the default queue
status = hpeAllocateReceiveBufferSet(hpe, &rx_buffers_q1, 4, ETH_FRAME_SIZE); 
status = hpeAttachReceiveBufferSetToQueue(hpe, 1, rx_buffers_q1); 

// configure the receive queue filter for queue 0
eth_filter.type = 0x8892;  // Profinet RT 
ether_filter.destination_queue = 0; 
eth_filter.insert_timestamp = 1;  
status = hpeSetReceiveQueueFilter(hpe, HPE_FILTER_ETHER_TYPE, eth_filter); 

// Calculate the launch time. 
hpeGet1588SystemTime(hpe, &now); 
next.seconds = 0; 
next.nanoseconds = 10000000;  // 10 milliseconds; 
hpe1588TimeAdd(&next, &now); 

// Allocate 1 transmit buffer of two fragments and 500 bytes and attach it 
tx_buffers = AllocateRtMemory(4096); 
p = (char *)&tx_buffers->buffers[1]; 
tx_buffers->buffer_count = 1; 
tx_buffers->buffers[0].fragment_count = 2; 
tx_buffers->buffers[0].timestamp_offset = 0;  // not cyclic 
tx_buffers->buffers[0].launch_time = next.nanoseconds; 

// first fragment is the fixed header, second is dynamic data 
tx_buffers->buffers[0].fragments[0].ptr = fixed_header; 
tx_buffers->buffers[0].fragments[0].size = 56; 
tx_buffers->buffers[0].fragments[0].paddr = 0; 
tx_buffers->buffers[0].fragments[1].ptr = p; 
tx_buffers->buffers[0].fragments[1].size = 444; 
tx_buffers->buffers[0].fragments[1].paddr = 0; 
status = hpeAttachTransmitBufferSetToQueue(handle, 0, 1, tx_buffers);
See Also