EtherCAT RAW socket driver. More...
#include <assert.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include "ethercattype.h"
#include "nicdrv.h"
#include "osal.h"
Go to the source code of this file.
Macros | |
#define | RX_PRIM priMAC[1] |
#define | RX_SEC secMAC[1] |
Enumerations | |
enum | { ECT_RED_NONE, ECT_RED_DOUBLE } |
Functions | |
void | ec_setupheader (void *p) |
static void | ecx_clear_rxbufstat (int *rxbufstat) |
int | ecx_closenic (ecx_portt *port) |
int | ecx_getindex (ecx_portt *port) |
int | ecx_inframe (ecx_portt *port, int idx, int stacknumber) |
int | ecx_outframe (ecx_portt *port, int idx, int stacknumber) |
int | ecx_outframe_red (ecx_portt *port, int idx) |
static int | ecx_recvpkt (ecx_portt *port, int stacknumber) |
void | ecx_setbufstat (ecx_portt *port, int idx, int bufstat) |
int | ecx_setupnic (ecx_portt *port, const char *ifname, int secondary) |
int | ecx_srconfirm (ecx_portt *port, int idx, int timeout) |
int | ecx_waitinframe (ecx_portt *port, int idx, int timeout) |
static int | ecx_waitinframe_red (ecx_portt *port, int idx, osal_timert *timer) |
Variables | |
static char | errbuf [PCAP_ERRBUF_SIZE] |
const uint16 | priMAC [3] = { 0x0101, 0x0101, 0x0101 } |
const uint16 | secMAC [3] = { 0x0404, 0x0404, 0x0404 } |
EtherCAT RAW socket driver.
Low level interface functions to send and receive EtherCAT packets. EtherCAT has the property that packets are only send by the master, and the send packets always return in the receive buffer. There can be multiple packets "on the wire" before they return. To combine the received packets with the original send packets a buffer system is installed. The identifier is put in the index item of the EtherCAT header. The index is stored and compared when a frame is received. If there is a match the packet can be combined with the transmit packet and returned to the higher level function.
The socket layer can exhibit a reversal in the packet order (rare). If the Tx order is A-B-C the return order could be A-C-B. The indexed buffer will reorder the packets automatically.
The "redundant" option will configure two sockets and two NIC interfaces. Slaves are connected to both interfaces, one on the IN port and one on the OUT port. Packets are send via both interfaces. Any one of the connections (also an interconnect) can be removed and the slaves are still serviced with packets. The software layer will detect the possible failure modes and compensate. If needed the packets from interface A are resent through interface B. This layer is fully transparent for the higher layers.
Definition in file macosx/nicdrv.c.
#define RX_PRIM priMAC[1] |
second MAC word is used for identification
Definition at line 64 of file macosx/nicdrv.c.
#define RX_SEC secMAC[1] |
second MAC word is used for identification
Definition at line 66 of file macosx/nicdrv.c.
anonymous enum |
Redundancy modes
Enumerator | |
---|---|
ECT_RED_NONE |
No redundancy, single NIC mode |
ECT_RED_DOUBLE |
Double redundant NIC connection |
Definition at line 45 of file macosx/nicdrv.c.
void ec_setupheader | ( | void * | p | ) |
Fill buffer with ethernet header structure. Destination MAC is always broadcast. Ethertype is always ETH_P_ECAT.
[out] | p | = buffer |
Definition at line 187 of file macosx/nicdrv.c.
|
static |
Definition at line 70 of file macosx/nicdrv.c.
|
inline |
Close sockets used
[in] | port | = port context struct |
Definition at line 163 of file macosx/nicdrv.c.
int ecx_getindex | ( | ecx_portt * | port | ) |
Get new frame identifier index and allocate corresponding rx buffer.
[in] | port | = port context struct |
Definition at line 204 of file macosx/nicdrv.c.
int ecx_inframe | ( | ecx_portt * | port, |
int | idx, | ||
int | stacknumber | ||
) |
Non blocking receive frame function. Uses RX buffer and index to combine read frame with transmitted frame. To compensate for received frames that are out-of-order all frames are stored in their respective indexed buffer. If a frame was placed in the buffer previously, the function retrieves it from that buffer index without calling ec_recvpkt. If the requested index is not already in the buffer it calls ec_recvpkt to fetch it. There are three options now, 1 no frame read, so exit. 2 frame read but other than requested index, store in buffer and exit. 3 frame read with matching index, store in buffer, set completed flag in buffer status and exit.
[in] | port | = port context struct |
[in] | idx | = requested index of frame |
[in] | stacknumber | = 0=primary 1=secondary stack |
Definition at line 374 of file macosx/nicdrv.c.
int ecx_outframe | ( | ecx_portt * | port, |
int | idx, | ||
int | stacknumber | ||
) |
Transmit buffer over socket (non blocking).
[in] | port | = port context struct |
[in] | idx | = index in tx buffer array |
[in] | stacknumber | = 0=Primary 1=Secondary stack |
Definition at line 256 of file macosx/nicdrv.c.
int ecx_outframe_red | ( | ecx_portt * | port, |
int | idx | ||
) |
Transmit buffer over socket (non blocking).
[in] | port | = port context struct |
[in] | idx | = index in tx buffer array |
Definition at line 285 of file macosx/nicdrv.c.
|
static |
Non blocking read of socket. Put frame in temporary buffer.
[in] | port | = port context struct |
[in] | stacknumber | = 0=primary 1=secondary stack |
Definition at line 323 of file macosx/nicdrv.c.
void ecx_setbufstat | ( | ecx_portt * | port, |
int | idx, | ||
int | bufstat | ||
) |
Set rx buffer status.
[in] | port | = port context struct |
[in] | idx | = index in buffer array |
[in] | bufstat | = status to set |
Definition at line 243 of file macosx/nicdrv.c.
int ecx_setupnic | ( | ecx_portt * | port, |
const char * | ifname, | ||
int | secondary | ||
) |
Basic setup to connect NIC to socket.
[in] | port | = port context struct |
[in] | ifname | = Name of NIC device, f.e. "eth0" |
[in] | secondary | = if >0 then use secondary stack instead of primary |
Definition at line 85 of file macosx/nicdrv.c.
int ecx_srconfirm | ( | ecx_portt * | port, |
int | idx, | ||
int | timeout | ||
) |
Blocking send and receive frame function. Used for non processdata frames. A datagram is build into a frame and transmitted via this function. It waits for an answer and returns the workcounter. The function retries if time is left and the result is WKC=0 or no frame received.
The function calls ec_outframe_red() and ec_waitinframe_red().
[in] | port | = port context struct |
[in] | idx | = index of frame |
[in] | timeout | = timeout in us |
Definition at line 575 of file macosx/nicdrv.c.
int ecx_waitinframe | ( | ecx_portt * | port, |
int | idx, | ||
int | timeout | ||
) |
Blocking receive frame function. Calls ec_waitinframe_red().
[in] | port | = port context struct |
[in] | idx | = requested index of frame |
[in] | timeout | = timeout in us |
Definition at line 552 of file macosx/nicdrv.c.
|
static |
Blocking redundant receive frame function. If redundant mode is not active then it skips the secondary stack and redundancy functions. In redundant mode it waits for both (primary and secondary) frames to come in. The result goes in an decision tree that decides, depending on the route of the packet and its possible missing arrival, how to reroute the original packet to get the data in an other try.
[in] | port | = port context struct |
[in] | idx | = requested index of frame |
[in] | tvs | = timeout |
Definition at line 469 of file macosx/nicdrv.c.
|
static |
Definition at line 68 of file macosx/nicdrv.c.
const uint16 priMAC[3] = { 0x0101, 0x0101, 0x0101 } |
Primary source MAC address used for EtherCAT. This address is not the MAC address used from the NIC. EtherCAT does not care about MAC addressing, but it is used here to differentiate the route the packet traverses through the EtherCAT segment. This is needed to fund out the packet flow in redundant configurations.
Definition at line 59 of file macosx/nicdrv.c.
const uint16 secMAC[3] = { 0x0404, 0x0404, 0x0404 } |
Secondary source MAC address used for EtherCAT.
Definition at line 61 of file macosx/nicdrv.c.