INtime SDK Help
Multiprocess HPE
INtime SDK v7.1 > About INtime > Networking and I/O > Multiprocess HPE

About MHPE

The INtime Multiprocess High-Performance Ethernet ("MHPE") interface extends the HPE API to allow multiple processes to share elements of the same Ethernet interface. A limitation of the HPE API is that it requires a single application to own the entire Ethernet interface and all of the resources that the Ethernet interface provides.

The MHPE architecture provides a single process which owns and manages one of more interfacEthernet devices but the API allows that process to divide the Ethernet deice into a number of separate resources which may be accessed and managed by different processes. For example, an Ethernet interface which provides multiple transmit and receive queues may now have those queues assigned to different applications and separate the traffic to and from those applications by using those queue resources.

<< add architecture diagram here >>

The same degree of control is provided by the new interface as with the HPE interface but with the additional flexibility of being able to partition the resources of the given controller between different applications.

Theory of Operation

A MHPE master process is provided which owns any Ethernet device assigned to it and directly manages any interrupts and register resources provided by that interface. However the MHPE API allows different processes to access separate resources of that device either exclusively, or in some cases sharing a resource between multiple processes.

Examples of resources provided by an Ethernet device may include the following:

A resource such as a transmit queue may be used by multiple processes to transmit packets, but a receive queue may be dedicated to a single process for its exclusive use. A timer may be read by multiple processes but one process may have exclusive access for modifying the timer.

Each resource provided by a device interface is called an endpoint. Interfaces have the same naming scheme as with HPE. Endpoints have names with consist of the interface name with a suffix to denote the endpoint for that interface.

 

Sample application

A sample application "MHPE sample" is included with the product. It illustrates various possible operations with the MHPE API.

MHPE API calls

This lists common operations related to MHPE and the INtime calls that do the operations.

Library calls

To . . . Use this system call . . .
A title  
MHPE master process calls  
Find the location of a MHPE master process mhpeFindMaster
Attach to an MHPE master process mhpeAttachMaster
Detach from MHPE master process mhpeDetachMaster
Interface calls  
Create an interface on a node mhpeCreateInterface
Enumerate existing interfaces on a node mhpeEnumInterfaces
Open an existing interface mhpeOpenInterface
Delete an interface mhpeDeleteInterface
Create an interface with options mhpeCreateInterfaceWithOptions
Close an interface mhpeCloseInterface
Configure options for an interface mhpeConfigOptions
Get interface information mhpeGetInterfaceInfo
Get interface current media status mhpeGetMediaStatus
Get interface MAC address mhpeGetMacAddress
Enable or disable receipt of all packets (promiscuous mode) at interface mhpeSetPromiscuousMode
Obtain a list of queue features supported by the hardware interface mhpeGetQueueConfiguration
Endpoint calls  
Enumerate endpoints of an interface mhpeEnumEndpoints
Open an endpoint by type and index mhpeOpenEndpoint
Open an endpoint by name mhpeOpenEndpointByName
Close an endpoint mhpeCloseEndpoint
Get statistics for a transmit or receive endpoint mhpeGetEndpointStats
Transmit endpoint calls  
Attach a set of transmit buffers to a transmit endpoint mhpeAttachTransmitBufferSet
Return the current state of the transmitter at endpoint mhpeGetTransmitterState
Sleep until the next transmit interrupt occurs for endpoint mhpeWaitForTransmitComplete
Set the type of transmit queue for endpoint mhpeSetTransmitAttributes
Start the transmitter at endpoint mhpeStartTransmitter
Set the transmit priority for the endpoint mhpeSetTransmitPriority
Set the global offset to be added to the launch time for the endpoint mhpeSetTransmitTimeOffset
Set the time to subtract from the launch time to be begin packet fetch on endpoint mhpeSetTransmitFetchDelta
Receive endpoint calls  
Allocate a receive buffer set which is compatible with the network device mhpeAllocateReceiveBufferSet
Free a previously-allocated receive buffer set mhpeFreeReceiveBufferSet
Attach a receive buffer set to a receive endpoint mhpeAttachReceiveBufferSet
Sleep until the next receive interrupt occurs for the endpoint mhpeWaitForReceiveComplete
Return a pointer to the next receive buffer at the endpoint which has a fully-received frame in it mhpeGetReceiveBuffer
Returns the receive buffer obtained by mhpeGetReceiveBuffer to the endpoint mhpeReturnReceiveBuffer
Set the type of the receive endpoint mhpeSetReceiveAttributes
Set the receive endpoint to receive all packets not matched by a filter mhpeSetDefaultReceiveEndpoint
Enable a receive endpoint filter by settings its parameters mhpeSetReceiveFilter
Get receive filter mhpeGetReceiveFilter
1588 timer calls  
Read the 1588 time from the timer endpoint mhpe1588GetSystemTime
Set the 1588 time at the timer endpoint mhpe1588SetSystemTime
Adjust the 1588 time at the time endpoint mhpe1588AdjustSystemTime
Set the byte offset at which the 1588 timestamp is written in the transmit packets mhpe1588SetTimestampOffset
Get the transmit timestamp for the most recently transmitted packet mhpe1588GetTxTimestamp
Get the receive timestamp from the receive packet buffer mhpe1588GetRxTimestamp
Retrieve the size of the timestamp header mhpe1588GetRxTimestampHeaderSize
Get the current a588 system time adjustment mhpe1588GetSystemTimeAdjustment
Get the current 1588 system time increment mhpe1588GetSystemTimeIncrement
Get the 1588 system time increment mhpe1588SetSystemTimeIncrement
Signal a semaphore when a target time is reached mhpeSetTargetTimer
Set the parameters to driver a GPIO ping from the 1588 system timer mhpeSetClockGeneratorPin
1588 timer arithmetic helper calls  
Add two 1588 time values mhpe1588TimeAdd
Subtract a 1588 time value from another mhpe1588TimeSubtract
Compare two 1588 time values mhpe1588TimeCompare
Return the difference between two 1588 time values mhpe1588TimeDifference

Structures

To . . . Use this structure . . .
Specify options; used by mhpeConfigOptions HPE_CONFIG_OPTIONS
Specify options; used by mhpeCreateInterfaceWithOptions HPE_OPEN_OPTIONS
Describe a queue configuration HPE_QUEUE_CONFIG
Describe an individual buffer to hold frame data MHPEBUFFER
Obtain information about the currently-connected media HPEMEDIASTATUS
Describe a set of receive frame buffers MHPERXBUFFERSET
Describe a single transmit buffer MHPETXBUFFER
Describe a transmit buffer set, consisting of multiple transmit buffers MHPETXBUFFERSET
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 contains code snippets illustrating some possible operations using this API. Refer to the sample application and specific calls for additional information.

Discovery and initialization

An MHPE application may communicate with any MHPE manager ("master process") on any node on the local host. If the location of a MHPE manager is not known they may be enumerated:

HPE initialization
Copy Code
LOCATION loc;
NODE_INFO ni;

// find and print details of all discovered management processes
loc = mhpeFindMaster(0);
while (loc != BAD_LOCATION) {
    if (GetRtNodeInfo(loc, &ni)) {
        printf("loc %u: %s (%s)\n", loc, ni.szNodeName, ni.NetIdType == NETID_TYPE_NONE ? "local" : "remote");
    }
    loc = mhpeFindMaster(loc);
}

Having obtained a location for the management process, attach to the process and create or open an interface:

HPE initialization
Copy Code
HPESTATUS st;
MHPEHANDLE if_handle = BAD_RTHANDLE;
LOCATION node_loc = THIS_LOCATION;
const char *if_name = "ie1g0";

// attach to the management process at the given location
st = mhpeAttachMaster(node_loc);
if (st != E_OK) {
        fprintf(stderr, "Failed to attach to master at location %u\n", node_loc);
}
else {
        // attempt to open an interface
        st = mhpeOpenInterface(node_loc, if_name, &if_handle);
        if (st != E_OK) {
                // if the interface does not already exist, we may attempt to create
        st = mhpeCreateInterfaceWithOptions(node_loc, if_name, opts, sizeof(*opts), &if_handle);
        }
}

Enumerate endpoints on an interface

HPE initialization
Copy Code
MHPESTATUS st;
HPE_INTERFACE_ENDPOINTS mhpe_endp;
char epname[64];
DWORD index;

// Get endpoint information from the interface (count of each endpoint type)
// h is the handle of an open interface
st = mhpeGetInterfaceInfo(h, MHPE_INFO_INTERFACE_ENDPOINTS, (LPVOID)&mhpe_endp, sizeof(mhpe_endp));
if (st != E_OK) {
        mhpeCloseInterface(h);
        printf("mhpeGetInterfaceInfo(HPE_INFO_INTERFACE_ENDPOINTS) failed with status %04x\n", st);
        return 1;
}
printf("\t%u Endpoints: %u tx, %u rx, %u timer\n",
        mhpe_endp.n_endpoints, mhpe_endp.n_tx_queues,
        mhpe_endp.n_rx_queues, mhpe_endp.n_1588timers);

// Enumerate all endpoint names
for (index = 0; ; index++) {
        if (0 != mhpeEnumEndpoints(h, index, epname, sizeof(epname)))
                break;
        printf("Endpoint %u: %s\n", index, epname);
}

CODE TEMPLATE

HPE initialization
Copy Code

Open and prepare a transmit endpoint

HPE initialization
Copy Code
MHPESTATUS st;
MHPEHANDLE tx_ep;
DWORD channel = 1;              // use endpoint index 1

// h is the handle of an open interface
st = mhpeOpenEndpoint(h, MHPE_EP_TX_QUEUE, channel, EP_ACC_WRITE_SHARE, &tx_ep);
if (st != E_OK) {
        printf("Failed to open Tx endpoint %u on %s\n", channel, h);
        return;
}
// Optionally call mhpeSetTransmitAttributes to change the transmit queue properties. 
// For example, enable transmit timestamps:
st = mhpeSetTransmitAttributes(tx_ep, HPE_TX_TIMESTAMP_2STEP);
if (st != E_OK) {
        printf("Failed to set TX timestamps\n");
}
else {
        printf("Enabled TX timestmaps\n");
}

Transmit a frame and wait for completion

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);

mhpeAttachTransmitBufferSet(tx_ep, tx_buffers);
st = hpeStartTransmitter(tx_ep);

// Wait for transmission to complete
// 'interrupts' contains the interrupt mode that the interface was opened with
if (interrupts & OUTPUT_INTERRUPT) {
        for (j = 0; j < (int)txs->buffer_count; j++) {
                if ((st = mhpeWaitForTransmitComplete(tx_ep, 1000000)) != E_OK) {
                        printf("TX: hpeWaitForTransmitComplete failed: %04x\n", st);
                        goto close;
                }
        }
}
else {
        // wait for transmit to complete
        while (mhpeGetTransmitterState(tx_ep, &txstate) == E_OK
                && txstate == HPE_TXBUSY)
                RtSleepEx(1);
}

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
MHPEBUFFER *rxbuffer;

mhpeWaitForReceiveComplete(rx_ep, 1000000);
if (mhpeGetReceiveBuffer(handle, &rxbuffer) == E_OK)
    process_buffer_data(rxbuffer->ptr, rxbuffer->used);       // user function