rtems/nicdrv.c
Go to the documentation of this file.
1 /*
2  * Licensed under the GNU General Public License version 2 with exceptions. See
3  * LICENSE file in the project root for full license information
4  */
5 
33 #include <sys/time.h>
34 #include <time.h>
35 #include <sys/types.h>
36 #include <sys/ioctl.h>
37 #include <net/bpf.h>
38 #include <sys/socket.h>
39 #include <net/if.h>
40 #include <unistd.h>
41 #include <arpa/inet.h>
42 #include <stdio.h>
43 #include <fcntl.h>
44 #include <string.h>
45 #include <pthread.h>
46 #include <assert.h>
47 
48 #include "oshw.h"
49 #include "osal.h"
50 
52 enum
53 {
58 };
59 
60 
67 const uint16 priMAC[3] = { 0x0201, 0x0101, 0x0101 };
69 const uint16 secMAC[3] = { 0x0604, 0x0404, 0x0404 };
70 
72 #define RX_PRIM priMAC[1]
73 
74 #define RX_SEC secMAC[1]
75 
76 static void ecx_clear_rxbufstat(int *rxbufstat)
77 {
78  int i;
79  for(i = 0; i < EC_MAXBUF; i++)
80  {
81  rxbufstat[i] = EC_BUF_EMPTY;
82  }
83 }
84 
91 int ecx_setupnic(ecx_portt *port, const char *ifname, int secondary)
92 {
93  int i;
94  int r, rval;
95  struct timeval timeout;
96  struct ifreq ifr;
97  int *bpf;
98  // const uint8_t bpffnamelen = 12;
99  char fname[13] = {0};
100  const int maxbpffile = 1000;
101  uint true_val = 1;
102 
103  rval = 0;
104  if (secondary)
105  {
106  /* secondary port struct available? */
107  if (port->redport)
108  {
109  /* when using secondary socket it is automatically a redundant setup */
110  bpf = &(port->redport->sockhandle);
111  *bpf = -1;
112  port->redstate = ECT_RED_DOUBLE;
113  port->redport->stack.sock = &(port->redport->sockhandle);
114  port->redport->stack.txbuf = &(port->txbuf);
115  port->redport->stack.txbuflength = &(port->txbuflength);
116  port->redport->stack.tempbuf = &(port->redport->tempinbuf);
117  port->redport->stack.rxbuf = &(port->redport->rxbuf);
118  port->redport->stack.rxbufstat = &(port->redport->rxbufstat);
119  port->redport->stack.rxsa = &(port->redport->rxsa);
120  ecx_clear_rxbufstat(&(port->redport->rxbufstat[0]));
121  }
122  else
123  {
124  /* fail */
125  return 0;
126  }
127  }
128  else
129  {
130  pthread_mutex_init(&(port->getindex_mutex), NULL);
131  pthread_mutex_init(&(port->tx_mutex) , NULL);
132  pthread_mutex_init(&(port->rx_mutex) , NULL);
133  port->sockhandle = -1;
134  port->lastidx = 0;
135  port->redstate = ECT_RED_NONE;
136  port->stack.sock = &(port->sockhandle);
137  port->stack.txbuf = &(port->txbuf);
138  port->stack.txbuflength = &(port->txbuflength);
139  port->stack.tempbuf = &(port->tempinbuf);
140  port->stack.rxbuf = &(port->rxbuf);
141  port->stack.rxbufstat = &(port->rxbufstat);
142  port->stack.rxsa = &(port->rxsa);
143  ecx_clear_rxbufstat(&(port->rxbufstat[0]));
144  bpf = &(port->sockhandle);
145  }
146 
147  /* Open a bpf file descriptor */
148  *bpf = -1;
149  for(i = 0; *bpf == -1 && i < maxbpffile; ++i)
150  {
151  sprintf(fname, "/dev/bpf%i", i);
152  *bpf = open(fname, O_RDWR);
153  }
154 
155  if(*bpf == -1)
156  {
157  /* Failed to open bpf */
158  perror("Could not open bpf\n");
159  return 0;
160  }
161 
162  /* Need to hand the same buffer size as bpf expects,
163  force bpf to use our buffer size! */
164  uint buffer_len = sizeof(ec_bufT);
165  if (ioctl(*bpf, BIOCSBLEN, &buffer_len) == -1) {
166  perror("BIOCGBLEN");
167  }
168 
169  if (buffer_len < 1518) {
170  printf("buffer_len %d < 1518\n", buffer_len);
171  return 0;
172  }
173 
174  /* connect bpf to NIC by name */
175  strcpy(ifr.ifr_name, ifname);
176  if(ioctl(*bpf, BIOCSETIF, &ifr) == -1) {
177  perror("BIOCSETIF");
178  return 0;
179  }
180 
181  /* Set required bpf options */
182 
183  /* Activate immediate mode */
184  if (ioctl(*bpf, BIOCIMMEDIATE, &true_val) == -1) {
185  perror("BIOCIMMEDIATE");
186  return 0;
187  }
188 
189  /* Set interface in promiscuous mode */
190  if (ioctl(*bpf, BIOCPROMISC, &true_val) == -1) {
191  perror("BIOCPROMISC");
192  return 0;
193  }
194 
195  /* Allow to have custom source address */
196  if (ioctl(*bpf, BIOCSHDRCMPLT, &true_val) == -1) {
197  perror("BIOCSHDRCMPLT");
198  return 0;
199  }
200 
201  /* Listen only to incomming messages */
202  uint direction = BPF_D_IN;
203  if (ioctl(*bpf, BIOCSDIRECTION, &direction) == -1) {
204  perror("BIOCSDIRECTION");
205  return 0;
206  }
207 
208  /* Set read timeout */
209  timeout.tv_sec = 0;
210  timeout.tv_usec = 11000;
211  if (ioctl(*bpf, BIOCSRTIMEOUT, &timeout) == -1) {
212  perror("BIOCSRTIMEOUT");
213  return 0;
214  }
215 
216  /* setup ethernet headers in tx buffers so we don't have to repeat it */
217  for (i = 0; i < EC_MAXBUF; i++)
218  {
219  ec_setupheader(&(port->txbuf[i]));
220  port->rxbufstat[i] = EC_BUF_EMPTY;
221  }
222  ec_setupheader(&(port->txbuf2));
223 
224  return 1;
225 }
226 
232 {
233  if (port->sockhandle >= 0)
234  close(port->sockhandle);
235  if ((port->redport) && (port->redport->sockhandle >= 0))
236  close(port->redport->sockhandle);
237 
238  return 0;
239 }
240 
246 void ec_setupheader(void *p)
247 {
248  ec_etherheadert *bp;
249  bp = p;
250  bp->da0 = htons(0xffff);
251  bp->da1 = htons(0xffff);
252  bp->da2 = htons(0xffff);
253  bp->sa0 = htons(priMAC[0]);
254  bp->sa1 = htons(priMAC[1]);
255  bp->sa2 = htons(priMAC[2]);
256  bp->etype = htons(ETH_P_ECAT);
257 }
258 
264 {
265  int idx;
266  int cnt;
267 
268  pthread_mutex_lock( &(port->getindex_mutex) );
269 
270  idx = port->lastidx + 1;
271  /* index can't be larger than buffer array */
272  if (idx >= EC_MAXBUF)
273  {
274  idx = 0;
275  }
276  cnt = 0;
277  /* try to find unused index */
278  while ((port->rxbufstat[idx] != EC_BUF_EMPTY) && (cnt < EC_MAXBUF))
279  {
280  idx++;
281  cnt++;
282  if (idx >= EC_MAXBUF)
283  {
284  idx = 0;
285  }
286  }
287  port->rxbufstat[idx] = EC_BUF_ALLOC;
288  if (port->redstate != ECT_RED_NONE)
289  port->redport->rxbufstat[idx] = EC_BUF_ALLOC;
290  port->lastidx = idx;
291 
292  pthread_mutex_unlock( &(port->getindex_mutex) );
293 
294  return idx;
295 }
296 
302 void ecx_setbufstat(ecx_portt *port, int idx, int bufstat)
303 {
304  port->rxbufstat[idx] = bufstat;
305  if (port->redstate != ECT_RED_NONE)
306  port->redport->rxbufstat[idx] = bufstat;
307 }
308 
315 int ecx_outframe(ecx_portt *port, int idx, int stacknumber)
316 {
317  int lp, rval;
318  ec_stackT *stack;
319 
320  if (!stacknumber)
321  {
322  stack = &(port->stack);
323  }
324  else
325  {
326  stack = &(port->redport->stack);
327  }
328  lp = (*stack->txbuflength)[idx];
329  //rval = send(*stack->sock, (*stack->txbuf)[idx], lp, 0);
330  (*stack->rxbufstat)[idx] = EC_BUF_TX;
331  rval = write (*stack->sock,(*stack->txbuf)[idx], lp);
332  if (rval == -1)
333  {
334  (*stack->rxbufstat)[idx] = EC_BUF_EMPTY;
335  }
336 
337  return rval;
338 }
339 
345 int ecx_outframe_red(ecx_portt *port, int idx)
346 {
347  ec_comt *datagramP;
348  ec_etherheadert *ehp;
349  int rval;
350 
351  ehp = (ec_etherheadert *)&(port->txbuf[idx]);
352  /* rewrite MAC source address 1 to primary */
353  ehp->sa1 = htons(priMAC[1]);
354  /* transmit over primary socket*/
355  rval = ecx_outframe(port, idx, 0);
356  if (port->redstate != ECT_RED_NONE)
357  {
358  pthread_mutex_lock( &(port->tx_mutex) );
359  ehp = (ec_etherheadert *)&(port->txbuf2);
360  /* use dummy frame for secondary socket transmit (BRD) */
361  datagramP = (ec_comt*)&(port->txbuf2[ETH_HEADERSIZE]);
362  /* write index to frame */
363  datagramP->index = idx;
364  /* rewrite MAC source address 1 to secondary */
365  ehp->sa1 = htons(secMAC[1]);
366  /* transmit over secondary socket */
367  //send(port->redport->sockhandle, &(port->txbuf2), port->txbuflength2 , 0);
368  port->redport->rxbufstat[idx] = EC_BUF_TX;
369  if (write(port->redport->sockhandle, &(port->txbuf2), port->txbuflength2) == -1)
370  {
371  (*stack->rxbufstat)[idx] = EC_BUF_EMPTY;
372  }
373  pthread_mutex_unlock( &(port->tx_mutex) );
374  }
375 
376  return rval;
377 }
378 
384 static int ecx_recvpkt(ecx_portt *port, int stacknumber)
385 {
386  int lp, bytesrx;
387  ec_stackT *stack;
388 
389  if (!stacknumber)
390  {
391  stack = &(port->stack);
392  }
393  else
394  {
395  stack = &(port->redport->stack);
396  }
397  lp = sizeof(port->tempinbuf);
398  //bytesrx = recv(*stack->sock, (*stack->tempbuf), lp, 0);
399  bytesrx = read(*stack->sock, (*stack->tempbuf), lp);
400  port->tempinbufs = bytesrx;
401 
402  return (bytesrx > 0);
403 }
404 
421 int ecx_inframe(ecx_portt *port, int idx, int stacknumber)
422 {
423  uint16 l;
424  int rval;
425  int idxf;
426  ec_etherheadert *ehp;
427  ec_comt *ecp;
428  ec_stackT *stack;
429  ec_bufT *rxbuf;
430 
431  if (!stacknumber)
432  {
433  stack = &(port->stack);
434  }
435  else
436  {
437  stack = &(port->redport->stack);
438  }
439  rval = EC_NOFRAME;
440  rxbuf = &(*stack->rxbuf)[idx];
441  /* check if requested index is already in buffer ? */
442  if ((idx < EC_MAXBUF) && ((*stack->rxbufstat)[idx] == EC_BUF_RCVD))
443  {
444  l = (*rxbuf)[0] + ((uint16)((*rxbuf)[1] & 0x0f) << 8);
445  /* return WKC */
446  rval = ((*rxbuf)[l] + ((uint16)(*rxbuf)[l + 1] << 8));
447  /* mark as completed */
448  (*stack->rxbufstat)[idx] = EC_BUF_COMPLETE;
449  }
450  else
451  {
452  pthread_mutex_lock(&(port->rx_mutex));
453  /* non blocking call to retrieve frame from socket */
454  if (ecx_recvpkt(port, stacknumber))
455  {
456  /* The data read from /dev/bpf includes an extra header, skip it. */
457  struct bpf_hdr *bpfh = (struct bpf_hdr *)(stack->tempbuf);
458  rval = EC_OTHERFRAME;
459  ehp =(ec_etherheadert*)(*stack->tempbuf + bpfh->bh_hdrlen);
460  /* check if it is an EtherCAT frame */
461  if (ehp->etype == htons(ETH_P_ECAT))
462  {
463  /* The EtherCAT header follows the ethernet frame header. */
464  ecp =(ec_comt*)(&ehp[1]);
465  l = etohs(ecp->elength) & 0x0fff;
466  idxf = ecp->index;
467  /* found index equals requested index ? */
468  if (idxf == idx)
469  {
470  /* yes, put it in the buffer array (strip headers) */
471  memcpy(rxbuf, &(ehp[1]), port->tempinbufs - ((uint32_t)ecp - (uint32_t)*stack->tempbuf));
472  /* return WKC */
473  rval = ((*rxbuf)[l] + ((uint16)((*rxbuf)[l + 1]) << 8));
474  /* mark as completed */
475  (*stack->rxbufstat)[idx] = EC_BUF_COMPLETE;
476  /* store MAC source word 1 for redundant routing info */
477  (*stack->rxsa)[idx] = ntohs(ehp->sa1);
478  }
479  else
480  {
481  /* check if index exist and someone is waiting for it */
482  if (idxf < EC_MAXBUF && (*stack->rxbufstat)[idxf] == EC_BUF_TX)
483  {
484  rxbuf = &(*stack->rxbuf)[idxf];
485  /* put it in the buffer array (strip ethernet header) */
486  memcpy(rxbuf, &(*stack->tempbuf)[ETH_HEADERSIZE], (*stack->txbuflength)[idxf] - ETH_HEADERSIZE);
487  /* mark as received */
488  (*stack->rxbufstat)[idxf] = EC_BUF_RCVD;
489  (*stack->rxsa)[idxf] = ntohs(ehp->sa1);
490  }
491  else
492  {
493  /* strange things happened */
494  }
495  }
496  }
497  }
498  pthread_mutex_unlock( &(port->rx_mutex) );
499 
500  }
501 
502  /* WKC if matching frame found */
503  return rval;
504 }
505 
518 static int ecx_waitinframe_red(ecx_portt *port, int idx, osal_timert *timer)
519 {
520  osal_timert timer2;
521  int wkc = EC_NOFRAME;
522  int wkc2 = EC_NOFRAME;
523  int primrx, secrx;
524 
525  /* if not in redundant mode then always assume secondary is OK */
526  if (port->redstate == ECT_RED_NONE)
527  wkc2 = 0;
528  do
529  {
530  /* only read frame if not already in */
531  if (wkc <= EC_NOFRAME)
532  wkc = ecx_inframe(port, idx, 0);
533  /* only try secondary if in redundant mode */
534  if (port->redstate != ECT_RED_NONE)
535  {
536  /* only read frame if not already in */
537  if (wkc2 <= EC_NOFRAME)
538  wkc2 = ecx_inframe(port, idx, 1);
539  }
540  /* wait for both frames to arrive or timeout */
541  } while (((wkc <= EC_NOFRAME) || (wkc2 <= EC_NOFRAME)) && !osal_timer_is_expired(timer));
542  /* only do redundant functions when in redundant mode */
543  if (port->redstate != ECT_RED_NONE)
544  {
545  /* primrx if the received MAC source on primary socket */
546  primrx = 0;
547  if (wkc > EC_NOFRAME) primrx = port->rxsa[idx];
548  /* secrx if the received MAC source on psecondary socket */
549  secrx = 0;
550  if (wkc2 > EC_NOFRAME) secrx = port->redport->rxsa[idx];
551 
552  /* primary socket got secondary frame and secondary socket got primary frame */
553  /* normal situation in redundant mode */
554  if ( ((primrx == RX_SEC) && (secrx == RX_PRIM)) )
555  {
556  /* copy secondary buffer to primary */
557  memcpy(&(port->rxbuf[idx]), &(port->redport->rxbuf[idx]), port->txbuflength[idx] - ETH_HEADERSIZE);
558  wkc = wkc2;
559  }
560  /* primary socket got nothing or primary frame, and secondary socket got secondary frame */
561  /* we need to resend TX packet */
562  if ( ((primrx == 0) && (secrx == RX_SEC)) ||
563  ((primrx == RX_PRIM) && (secrx == RX_SEC)) )
564  {
565  /* If both primary and secondary have partial connection retransmit the primary received
566  * frame over the secondary socket. The result from the secondary received frame is a combined
567  * frame that traversed all slaves in standard order. */
568  if ( (primrx == RX_PRIM) && (secrx == RX_SEC) )
569  {
570  /* copy primary rx to tx buffer */
571  memcpy(&(port->txbuf[idx][ETH_HEADERSIZE]), &(port->rxbuf[idx]), port->txbuflength[idx] - ETH_HEADERSIZE);
572  }
573  osal_timer_start (&timer2, EC_TIMEOUTRET);
574  /* resend secondary tx */
575  ecx_outframe(port, idx, 1);
576  do
577  {
578  /* retrieve frame */
579  wkc2 = ecx_inframe(port, idx, 1);
580  } while ((wkc2 <= EC_NOFRAME) && !osal_timer_is_expired(&timer2));
581  if (wkc2 > EC_NOFRAME)
582  {
583  /* copy secondary result to primary rx buffer */
584  memcpy(&(port->rxbuf[idx]), &(port->redport->rxbuf[idx]), port->txbuflength[idx] - ETH_HEADERSIZE);
585  wkc = wkc2;
586  }
587  }
588  }
589 
590  /* return WKC or EC_NOFRAME */
591  return wkc;
592 }
593 
601 int ecx_waitinframe(ecx_portt *port, int idx, int timeout)
602 {
603  int wkc;
604  osal_timert timer;
605 
606  osal_timer_start (&timer, timeout);
607  wkc = ecx_waitinframe_red(port, idx, &timer);
608 
609  return wkc;
610 }
611 
624 int ecx_srconfirm(ecx_portt *port, int idx, int timeout)
625 {
626  int wkc = EC_NOFRAME;
627  osal_timert timer1, timer2;
628 
629  osal_timer_start (&timer1, timeout);
630  do
631  {
632  /* tx frame on primary and if in redundant mode a dummy on secondary */
633  ecx_outframe_red(port, idx);
634  if (timeout < EC_TIMEOUTRET)
635  {
636  osal_timer_start (&timer2, timeout);
637  }
638  else
639  {
640  /* normally use partial timeout for rx */
641  osal_timer_start (&timer2, EC_TIMEOUTRET);
642  }
643  /* get frame from primary or if in redundant mode possibly from secondary */
644  wkc = ecx_waitinframe_red(port, idx, &timer2);
645  /* wait for answer with WKC>=0 or otherwise retry until timeout */
646  } while ((wkc <= EC_NOFRAME) && !osal_timer_is_expired (&timer1));
647 
648  return wkc;
649 }
650 
651 #ifdef EC_VER1
652 int ec_setupnic(const char *ifname, int secondary)
653 {
654  return ecx_setupnic(&ecx_port, ifname, secondary);
655 }
656 
657 int ec_closenic(void)
658 {
659  return ecx_closenic(&ecx_port);
660 }
661 
662 int ec_getindex(void)
663 {
664  return ecx_getindex(&ecx_port);
665 }
666 
667 void ec_setbufstat(int idx, int bufstat)
668 {
669  ecx_setbufstat(&ecx_port, idx, bufstat);
670 }
671 
672 int ec_outframe(int idx, int stacknumber)
673 {
674  return ecx_outframe(&ecx_port, idx, stacknumber);
675 }
676 
677 int ec_outframe_red(int idx)
678 {
679  return ecx_outframe_red(&ecx_port, idx);
680 }
681 
682 int ec_inframe(int idx, int stacknumber)
683 {
684  return ecx_inframe(&ecx_port, idx, stacknumber);
685 }
686 
687 int ec_waitinframe(int idx, int timeout)
688 {
689  return ecx_waitinframe(&ecx_port, idx, timeout);
690 }
691 
692 int ec_srconfirm(int idx, int timeout)
693 {
694  return ecx_srconfirm(&ecx_port, idx, timeout);
695 }
696 #endif
int ecx_closenic(ecx_portt *port)
Definition: rtems/nicdrv.c:231
int ec_outframe(int idx, int sock)
ec_bufT rxbuf[EC_MAXBUF]
Definition: erika/nicdrv.h:43
int rxsa[EC_MAXBUF]
Definition: erika/nicdrv.h:47
ec_bufT txbuf[EC_MAXBUF]
Definition: erika/nicdrv.h:68
boolean osal_timer_is_expired(osal_timert *self)
Definition: erika/osal.c:74
int(* rxsa)[EC_MAXBUF]
Definition: erika/nicdrv.h:34
int txbuflength[EC_MAXBUF]
Definition: erika/nicdrv.h:70
int ec_setupnic(const char *ifname, int secondary)
static int ecx_recvpkt(ecx_portt *port, int stacknumber)
Definition: rtems/nicdrv.c:384
static int ecx_waitinframe_red(ecx_portt *port, int idx, osal_timert *timer)
Definition: rtems/nicdrv.c:518
Headerfile for ethercatbase.c.
#define EC_MAXBUF
Definition: ethercattype.h:62
#define RX_PRIM
Definition: rtems/nicdrv.c:72
ec_bufT txbuf2
Definition: erika/nicdrv.h:72
void ec_setupheader(void *p)
Definition: rtems/nicdrv.c:246
int rxsa[EC_MAXBUF]
Definition: erika/nicdrv.h:62
int(* txbuflength)[EC_MAXBUF]
Definition: erika/nicdrv.h:26
PACKED_BEGIN struct PACKED ec_etherheadert
ec_bufT * tempbuf
Definition: erika/nicdrv.h:28
int txbuflength2
Definition: erika/nicdrv.h:74
uint16_t uint16
Definition: osal.h:29
#define etohs(A)
Definition: ethercattype.h:536
#define ETH_HEADERSIZE
Definition: ethercattype.h:103
int rxbufstat[EC_MAXBUF]
Definition: erika/nicdrv.h:45
ec_stackT stack
Definition: erika/nicdrv.h:55
ec_bufT rxbuf[EC_MAXBUF]
Definition: erika/nicdrv.h:58
pthread_mutex_t tx_mutex
Definition: linux/nicdrv.h:85
ec_stackT stack
Definition: erika/nicdrv.h:40
ec_bufT tempinbuf
Definition: erika/nicdrv.h:64
int ecx_setupnic(ecx_portt *port, const char *ifname, int secondary)
Definition: rtems/nicdrv.c:91
ec_bufT(* rxbuf)[EC_MAXBUF]
Definition: erika/nicdrv.h:30
int ecx_waitinframe(ecx_portt *port, int idx, int timeout)
Definition: rtems/nicdrv.c:601
int ec_srconfirm(int idx, int timeout)
unsigned int uint32_t
Definition: stdint.h:80
void ecx_setbufstat(ecx_portt *port, int idx, int bufstat)
Definition: rtems/nicdrv.c:302
int tempinbufs
Definition: erika/nicdrv.h:66
ec_bufT(* txbuf)[EC_MAXBUF]
Definition: erika/nicdrv.h:24
int ecx_srconfirm(ecx_portt *port, int idx, int timeout)
Definition: rtems/nicdrv.c:624
void ec_setbufstat(int idx, int bufstat)
ecx_redportt * redport
Definition: erika/nicdrv.h:80
PACKED_BEGIN struct PACKED ec_comt
#define RX_SEC
Definition: rtems/nicdrv.c:74
#define EC_TIMEOUTRET
Definition: ethercattype.h:64
#define EC_OTHERFRAME
Definition: ethercattype.h:43
pthread_mutex_t getindex_mutex
Definition: linux/nicdrv.h:84
static void ecx_clear_rxbufstat(int *rxbufstat)
Definition: rtems/nicdrv.c:76
int ec_outframe_red(int idx)
int redstate
Definition: erika/nicdrv.h:78
#define ETH_P_ECAT
Definition: ethercattype.h:459
int wkc
Definition: aliastool.c:47
int ecx_inframe(ecx_portt *port, int idx, int stacknumber)
Definition: rtems/nicdrv.c:421
int rxbufstat[EC_MAXBUF]
Definition: erika/nicdrv.h:60
uint8 ec_bufT[EC_BUFSIZE]
Definition: ethercattype.h:87
ec_bufT tempinbuf
Definition: erika/nicdrv.h:49
int ec_closenic(void)
int ec_getindex(void)
int ecx_outframe_red(ecx_portt *port, int idx)
Definition: rtems/nicdrv.c:345
int ecx_getindex(ecx_portt *port)
Definition: rtems/nicdrv.c:263
const uint16 secMAC[3]
Definition: rtems/nicdrv.c:69
Packet header.
Definition: Packet32.h:150
int ec_waitinframe(int idx, int timeout)
void osal_timer_start(osal_timert *self, uint32 timeout_usec)
Definition: erika/osal.c:59
int(* rxbufstat)[EC_MAXBUF]
Definition: erika/nicdrv.h:32
int sockhandle
Definition: erika/nicdrv.h:56
#define EC_NOFRAME
Definition: ethercattype.h:41
USHORT bh_hdrlen
Definition: Packet32.h:158
const uint16 priMAC[3]
Definition: rtems/nicdrv.c:67
int * sock
Definition: erika/nicdrv.h:22
pthread_mutex_t rx_mutex
Definition: linux/nicdrv.h:86
int ecx_outframe(ecx_portt *port, int idx, int stacknumber)
Definition: rtems/nicdrv.c:315
uint8 rxbuf[1024]
Definition: eoe_test.c:50


soem
Author(s): Arthur Ketels and M.J.G. van den Molengraft
autogenerated on Mon Feb 28 2022 23:46:57