eoe_test.c
Go to the documentation of this file.
1 
23 #include <stdio.h>
24 #include <string.h>
25 #include <inttypes.h>
26 
27 #include "ethercat.h"
28 
29 #define EC_TIMEOUTMON 500
30 
31 char IOmap[4096];
32 
34 boolean needlf;
35 volatile int globalwkc;
36 boolean inOP;
40 uint8 txbuf[1024];
41 
50 uint8 rxbuf[1024];
51 int size_of_rx = sizeof(rxbuf);
52 
54 int eoe_hook(ecx_contextt * context, uint16 slave, void * eoembx)
55 {
56  int wkc;
57  /* Pass received Mbx data to EoE recevive fragment function that
58  * that will start/continue fill an Ethernet frame buffer
59  */
60  size_of_rx = sizeof(rxbuf);
61  wkc = ecx_EOEreadfragment(eoembx,
62  &rxfragmentno,
63  &rxframesize,
65  &rxframeno,
66  &size_of_rx,
67  rxbuf);
68 
69  printf("Read frameno %d, fragmentno %d\n", rxframeno, rxfragmentno);
70 
71  /* wkc == 1 would mean a frame is complete , last fragment flag have been set and all
72  * other checks must have past
73  */
74  if (wkc > 0)
75  {
77  uint16 type = ntohs(bp->etype);
78  printf("Frameno %d, type 0x%x complete\n", rxframeno, type);
79  if (type == ETH_P_ECAT)
80  {
81  /* Sanity check that received buffer still is OK */
82  if (sizeof(txbuf) != size_of_rx)
83  {
84  printf("Size differs, expected %d , received %d\n", sizeof(txbuf), size_of_rx);
85  }
86  else
87  {
88  printf("Size OK, expected %d , received %d\n", sizeof(txbuf), size_of_rx);
89  }
90  /* Check that the TX and RX frames are EQ */
91  if (memcmp(rxbuf, txbuf, size_of_rx))
92  {
93  printf("memcmp result != 0\n");
94  }
95  else
96  {
97  printf("memcmp result == 0\n");
98  }
99  /* Send a new frame */
100  int ixme;
101  for (ixme = ETH_HEADERSIZE; ixme < sizeof(txbuf); ixme++)
102  {
103  txbuf[ixme] = (uint8)rand();
104  }
105  printf("Send a new frame\n");
106  ecx_EOEsend(context, 1, 0, sizeof(txbuf), txbuf, EC_TIMEOUTRXM);
107  }
108  else
109  {
110  printf("Skip type 0x%x\n", type);
111  }
112  }
113  /* No point in returning as unhandled */
114  return 1;
115 }
116 
118 {
119  ecx_contextt *context = (ecx_contextt *)lpParam;
120  int wkc;
121  ec_mbxbuft MbxIn;
122  ec_mbxheadert * MbxHdr = (ec_mbxheadert *)MbxIn;
123 
124  int ixme;
126  for (ixme = ETH_HEADERSIZE; ixme < sizeof(txbuf); ixme++)
127  {
128  txbuf[ixme] = (uint8)rand();
129  }
130  /* Send a made up frame to trigger a fragmented transfer
131  * Used with a special bound impelmentaion of SOES. Will
132  * trigger a fragmented transfer back of the same frame.
133  */
134  ecx_EOEsend(context, 1, 0, sizeof(txbuf), txbuf, EC_TIMEOUTRXM);
135 
136  for (;;)
137  {
138  /* Read mailbox if no other mailbox conversation is ongoing eg. SDOwrite/SDOwrite etc.*/
139  wkc = ecx_mbxreceive(context, 1, (ec_mbxbuft *)&MbxIn, 0);
140  if (wkc > 0)
141  {
142  printf("Unhandled mailbox response 0x%x\n", MbxHdr->mbxtype);
143  }
144  osal_usleep(1 * 1000 * 1000);
145  }
146 }
147 
148 void test_eoe(ecx_contextt * context)
149 {
150  /* Set the HOOK */
151  ecx_EOEdefinehook(context, eoe_hook);
152 
153  eoe_param_t ipsettings, re_ipsettings;
154  memset(&ipsettings, 0, sizeof(ipsettings));
155  memset(&re_ipsettings, 0, sizeof(re_ipsettings));
156 
157  ipsettings.ip_set = 1;
158  ipsettings.subnet_set = 1;
159  ipsettings.default_gateway_set = 1;
160 
161  EOE_IP4_ADDR_TO_U32(&ipsettings.ip, 192, 168, 9, 200);
162  EOE_IP4_ADDR_TO_U32(&ipsettings.subnet, 255, 255, 255, 0);
163  EOE_IP4_ADDR_TO_U32(&ipsettings.default_gateway, 0, 0, 0, 0);
164 
165  /* Send a set IP request */
166  ecx_EOEsetIp(context, 1, 0, &ipsettings, EC_TIMEOUTRXM);
167 
168  /* Send a get IP request, should return the expected IP back */
169  ecx_EOEgetIp(context, 1, 0, &re_ipsettings, EC_TIMEOUTRXM);
170 
171  /* Trigger an MBX read request, to be replaced by slave Mbx
172  * full notification via polling of FMMU status process data
173  */
174  printf("recieved IP (%d.%d.%d.%d)\n",
175  eoe_ip4_addr1(&re_ipsettings.ip),
176  eoe_ip4_addr2(&re_ipsettings.ip),
177  eoe_ip4_addr3(&re_ipsettings.ip),
178  eoe_ip4_addr4(&re_ipsettings.ip));
179  printf("recieved subnet (%d.%d.%d.%d)\n",
180  eoe_ip4_addr1(&re_ipsettings.subnet),
181  eoe_ip4_addr2(&re_ipsettings.subnet),
182  eoe_ip4_addr3(&re_ipsettings.subnet),
183  eoe_ip4_addr4(&re_ipsettings.subnet));
184  printf("recieved gateway (%d.%d.%d.%d)\n",
185  eoe_ip4_addr1(&re_ipsettings.default_gateway),
186  eoe_ip4_addr2(&re_ipsettings.default_gateway),
187  eoe_ip4_addr3(&re_ipsettings.default_gateway),
188  eoe_ip4_addr4(&re_ipsettings.default_gateway));
189 
190  /* Create a asyncronous EoE reader */
192 }
193 
194 void teststarter(char *ifname)
195 {
196  int i, oloop, iloop, chk;
197  needlf = FALSE;
198  inOP = FALSE;
199 
200  printf("Starting eoe test\n");
201 
202  /* initialise SOEM, bind socket to ifname */
203  if (ec_init(ifname))
204  {
205  printf("ec_init on %s succeeded.\n",ifname);
206  /* find and auto-config slaves */
207  if ( ec_config_init(FALSE) > 0 )
208  {
209  printf("%d slaves found and configured.\n",ec_slavecount);
210 
212 
213  ec_configdc();
214 
215  printf("Slaves mapped, state to SAFE_OP.\n");
216  /* wait for all slaves to reach SAFE_OP state */
218 
219  oloop = ec_slave[0].Obytes;
220  if ((oloop == 0) && (ec_slave[0].Obits > 0)) oloop = 1;
221  if (oloop > 8) oloop = 8;
222  iloop = ec_slave[0].Ibytes;
223  if ((iloop == 0) && (ec_slave[0].Ibits > 0)) iloop = 1;
224  if (iloop > 8) iloop = 8;
225 
226  printf("segments : %d : %d %d %d %d\n",ec_group[0].nsegments ,ec_group[0].IOsegment[0],ec_group[0].IOsegment[1],ec_group[0].IOsegment[2],ec_group[0].IOsegment[3]);
227 
228  printf("Request operational state for all slaves\n");
229  expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC;
230  printf("Calculated workcounter %d\n", expectedWKC);
232  /* send one valid process data to make outputs in slaves happy*/
235 
236  /* Simple EoE test */
238 
239  /* request OP state for all slaves */
240  ec_writestate(0);
241  chk = 200;
242  /* wait for all slaves to reach OP state */
243  do
244  {
248  }
249  while (chk-- && (ec_slave[0].state != EC_STATE_OPERATIONAL));
250  if (ec_slave[0].state == EC_STATE_OPERATIONAL )
251  {
252  printf("Operational state reached for all slaves.\n");
254  inOP = TRUE;
255  /* cyclic loop */
256  for(i = 1; i <= 10000; i++)
257  {
260 #if PRINT_EOE_INFO_INSTEAD
261  int j;
262  if(globalwkc >= expectedWKC)
263  {
264  printf("Processdata cycle %4d, WKC %d , O:", i, globalwkc);
265  for(j = 0 ; j < oloop; j++)
266  {
267  printf(" %2.2x", *(ec_slave[0].outputs + j));
268  }
269  printf(" I:");
270  for(j = 0 ; j < iloop; j++)
271  {
272  printf(" %2.2x", *(ec_slave[0].inputs + j));
273  }
274  printf(" T:%"PRId64"\r",ec_DCtime);
275  needlf = TRUE;
276  }
277 #endif
278  osal_usleep(1000);
279  }
280  inOP = FALSE;
281  }
282  else
283  {
284  printf("Not all slaves reached operational state.\n");
285  ec_readstate();
286  for(i = 1; i<=ec_slavecount ; i++)
287  {
288  if(ec_slave[i].state != EC_STATE_OPERATIONAL)
289  {
290  printf("Slave %d State=0x%2.2x StatusCode=0x%4.4x : %s\n",
291  i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
292  }
293  }
294  }
295  printf("\nRequest init state for all slaves\n");
297  /* request INIT state for all slaves */
298  ec_writestate(0);
299  }
300  else
301  {
302  printf("No slaves found!\n");
303  }
304  printf("End eoe test, close socket\n");
305  /* stop SOEM, close socket */
306  ec_close();
307  }
308  else
309  {
310  printf("No socket connection on %s\nExcecute as root\n",ifname);
311  }
312 }
313 
315 {
316  int slave;
317  (void)ptr; /* Not used */
318 
319  while(1)
320  {
321  if( inOP && ((globalwkc < expectedWKC) || ec_group[currentgroup].docheckstate))
322  {
323  if (globalwkc < expectedWKC)
324  {
325  printf("(wkc < expectedWKC) , globalwkc %d\n", globalwkc);
326  }
327  if (ec_group[currentgroup].docheckstate)
328  {
329  printf("(ec_group[currentgroup].docheckstate)\n");
330  }
331 
332  if (needlf)
333  {
334  needlf = FALSE;
335  printf("\n");
336  }
337  /* one ore more slaves are not responding */
339  ec_readstate();
340  for (slave = 1; slave <= ec_slavecount; slave++)
341  {
342  if ((ec_slave[slave].group == currentgroup) && (ec_slave[slave].state != EC_STATE_OPERATIONAL))
343  {
345  if (ec_slave[slave].state == (EC_STATE_SAFE_OP + EC_STATE_ERROR))
346  {
347  printf("ERROR : slave %d is in SAFE_OP + ERROR, attempting ack.\n", slave);
350  }
351  else if(ec_slave[slave].state == EC_STATE_SAFE_OP)
352  {
353  printf("WARNING : slave %d is in SAFE_OP, change to OPERATIONAL.\n", slave);
356  }
357  else if(ec_slave[slave].state > EC_STATE_NONE)
358  {
360  {
362  printf("MESSAGE : slave %d reconfigured\n",slave);
363  }
364  }
365  else if(!ec_slave[slave].islost)
366  {
367  /* re-check state */
369  if (ec_slave[slave].state == EC_STATE_NONE)
370  {
372  printf("ERROR : slave %d lost\n",slave);
373  }
374  }
375  }
376  if (ec_slave[slave].islost)
377  {
378  if(ec_slave[slave].state == EC_STATE_NONE)
379  {
381  {
383  printf("MESSAGE : slave %d recovered\n",slave);
384  }
385  }
386  else
387  {
389  printf("MESSAGE : slave %d found\n",slave);
390  }
391  }
392  }
393  if(!ec_group[currentgroup].docheckstate)
394  printf("OK : all slaves resumed OPERATIONAL.\n");
395  }
396  osal_usleep(10000);
397  }
398 }
399 
400 int main(int argc, char *argv[])
401 {
402  printf("SOEM (Simple Open EtherCAT Master)\nEoE test\n");
403 
404  if (argc > 1)
405  {
406  /* create thread to handle slave error handling in OP */
407 // pthread_create( &thread1, NULL, (void *) &ecatcheck, (void*) &ctime);
408  osal_thread_create(&thread1, 128000, &ecatcheck, (void*) &ctime);
409 
410  /* start cyclic part */
411  teststarter(argv[1]);
412  }
413  else
414  {
415  printf("Usage: eoe_test ifname1\nifname = eth0 for example\n");
416  }
417 
418  printf("End program\n");
419  return (0);
420 }
ecatcheck
OSAL_THREAD_FUNC ecatcheck(void *ptr)
Definition: eoe_test.c:314
wkc
int wkc
Definition: aliastool.c:47
ec_configdc
boolean ec_configdc(void)
Definition: ethercatdc.c:444
uint8_t
unsigned char uint8_t
Definition: stdint.h:78
slave
int slave
Definition: aliastool.c:44
rxbuf
uint8 rxbuf[1024]
Definition: eoe_test.c:50
inOP
boolean inOP
Definition: eoe_test.c:36
ec_slave::islost
boolean islost
Definition: ethercatmain.h:229
ec_readstate
int ec_readstate(void)
Definition: ethercatmain.c:2138
ec_close
void ec_close(void)
Definition: ethercatmain.c:2048
uint16_t
unsigned short uint16_t
Definition: stdint.h:79
ec_mbxbuft
uint8 ec_mbxbuft[EC_MAXMBX+1]
Definition: ethercatmain.h:312
thread1
OSAL_THREAD_HANDLE thread1
Definition: eoe_test.c:38
ec_send_processdata
int ec_send_processdata(void)
Definition: ethercatmain.c:2383
eoe_ip4_addr3
#define eoe_ip4_addr3(ipaddr)
Definition: ethercateoe.h:50
eoe_ip4_addr1
#define eoe_ip4_addr1(ipaddr)
Definition: ethercateoe.h:48
ethercat.h
Headerfile for all ethercat headers.
ec_init
int ec_init(const char *ifname)
Definition: ethercatmain.c:2029
EC_TIMEOUTRXM
#define EC_TIMEOUTRXM
Definition: ethercattype.h:74
ec_group
Definition: ethercatmain.h:239
eoe_ip4_addr4
#define eoe_ip4_addr4(ipaddr)
Definition: ethercateoe.h:51
txbuf
uint8 txbuf[1024]
Definition: eoe_test.c:40
ec_slave::Ibytes
uint32 Ibytes
Definition: ethercatmain.h:137
rxframeno
uint16_t rxframeno
Definition: eoe_test.c:49
ec_group::outputsWKC
uint16 outputsWKC
Definition: ethercatmain.h:266
ec_mbxheadert
PACKED_BEGIN struct PACKED ec_mbxheader ec_mbxheadert
ec_DCtime
int64 ec_DCtime
Definition: ethercatmain.c:95
uint8
uint8_t uint8
Definition: osal.h:28
EC_STATE_SAFE_OP
@ EC_STATE_SAFE_OP
Definition: ethercattype.h:166
ETH_P_ECAT
#define ETH_P_ECAT
Definition: ethercattype.h:459
size_of_rx
int size_of_rx
Definition: eoe_test.c:51
PRId64
#define PRId64
Definition: inttypes.h:78
j
int j
Definition: linux/firm_update/firm_update.c:31
eoe_ip4_addr2
#define eoe_ip4_addr2(ipaddr)
Definition: ethercateoe.h:49
ec_slave::state
uint16 state
Definition: ethercatmain.h:109
EOE_IP4_ADDR_TO_U32
#define EOE_IP4_ADDR_TO_U32(ipaddr, a, b, c, d)
Definition: ethercateoe.h:54
ec_config_init
int ec_config_init(uint8 usetable)
Definition: ethercatconfig.c:1606
EC_TIMEOUTRET
#define EC_TIMEOUTRET
Definition: ethercattype.h:64
ec_recover_slave
int ec_recover_slave(uint16 slave, int timeout)
Definition: ethercatconfig.c:1700
ec_group::docheckstate
boolean docheckstate
Definition: ethercatmain.h:270
rxfragmentno
uint8_t rxfragmentno
Definition: eoe_test.c:43
IOmap
char IOmap[4096]
Definition: eoe_test.c:31
rxframesize
uint16_t rxframesize
Definition: eoe_test.c:45
ecx_EOEsend
int ecx_EOEsend(ecx_contextt *context, uint16 slave, uint8 port, int psize, void *p, int timeout)
Definition: ethercateoe.c:322
ecx_EOEdefinehook
int ecx_EOEdefinehook(ecx_contextt *context, void *hook)
Definition: ethercateoe.c:52
rxframeoffset
uint16_t rxframeoffset
Definition: eoe_test.c:47
ec_reconfig_slave
int ec_reconfig_slave(uint16 slave, int timeout)
Definition: ethercatconfig.c:1712
mailbox_reader
OSAL_THREAD_FUNC mailbox_reader(void *lpParam)
Definition: eoe_test.c:117
uint16
uint16_t uint16
Definition: osal.h:29
ecx_EOEgetIp
int ecx_EOEgetIp(ecx_contextt *context, uint16 slave, uint8 port, eoe_param_t *ipparam, int timeout)
Definition: ethercateoe.c:181
EC_STATE_INIT
@ EC_STATE_INIT
Definition: ethercattype.h:160
ecx_mbxreceive
int ecx_mbxreceive(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
Definition: ethercatmain.c:1001
expectedWKC
int expectedWKC
Definition: eoe_test.c:33
OSAL_THREAD_FUNC
#define OSAL_THREAD_FUNC
Definition: intime/osal_defs.h:36
globalwkc
volatile int globalwkc
Definition: eoe_test.c:35
thread2
OSAL_THREAD_HANDLE thread2
Definition: eoe_test.c:39
currentgroup
uint8 currentgroup
Definition: eoe_test.c:37
osal_usleep
int osal_usleep(uint32 usec)
Definition: erika/osal.c:22
TRUE
#define TRUE
Definition: osal.h:19
EC_TIMEOUTMON
#define EC_TIMEOUTMON
Definition: eoe_test.c:29
teststarter
void teststarter(char *ifname)
Definition: eoe_test.c:194
ec_writestate
int ec_writestate(uint16 slave)
Definition: ethercatmain.c:2149
ec_slave
Definition: ethercatmain.h:106
FALSE
#define FALSE
Definition: osal.h:22
ecx_context
Definition: ethercatmain.h:384
ec_etherheadert
PACKED_BEGIN struct PACKED ec_etherheadert
EC_STATE_ERROR
@ EC_STATE_ERROR
Definition: ethercattype.h:171
needlf
boolean needlf
Definition: eoe_test.c:34
EC_TIMEOUTSTATE
#define EC_TIMEOUTSTATE
Definition: ethercattype.h:76
eoe_param_t
PACKED_END struct eoe_param eoe_param_t
ec_slavecount
int ec_slavecount
Definition: ethercatmain.c:69
OSAL_THREAD_HANDLE
#define OSAL_THREAD_HANDLE
Definition: intime/osal_defs.h:35
main
int main(int argc, char *argv[])
Definition: eoe_test.c:400
ec_statecheck
uint16 ec_statecheck(uint16 slave, uint16 reqstate, int timeout)
Definition: ethercatmain.c:2162
ec_receive_processdata
int ec_receive_processdata(int timeout)
Definition: ethercatmain.c:2393
ec_ALstatuscode2string
char * ec_ALstatuscode2string(uint16 ALstatuscode)
Definition: ethercatprint.c:245
eoe_hook
int eoe_hook(ecx_contextt *context, uint16 slave, void *eoembx)
Definition: eoe_test.c:54
ec_setupheader
void ec_setupheader(void *p)
Definition: erika/nicdrv.c:151
ec_config_map
int ec_config_map(void *pIOmap)
Definition: ethercatconfig.c:1643
inttypes.h
ecx_EOEsetIp
int ecx_EOEsetIp(ecx_contextt *context, uint16 slave, uint8 port, eoe_param_t *ipparam, int timeout)
Definition: ethercateoe.c:67
ec_slave::Obytes
uint32 Obytes
Definition: ethercatmain.h:129
EC_STATE_NONE
@ EC_STATE_NONE
Definition: ethercattype.h:158
ETH_HEADERSIZE
#define ETH_HEADERSIZE
Definition: ethercattype.h:103
test_eoe
void test_eoe(ecx_contextt *context)
Definition: eoe_test.c:148
osal_thread_create
int osal_thread_create(void *thandle, int stacksize, void *func, void *param)
Definition: linux/osal.c:102
EC_STATE_OPERATIONAL
@ EC_STATE_OPERATIONAL
Definition: ethercattype.h:168
ecx_EOEreadfragment
int ecx_EOEreadfragment(ec_mbxbuft *MbxIn, uint8 *rxfragmentno, uint16 *rxframesize, uint16 *rxframeoffset, uint16 *rxframeno, int *psize, void *p)
Definition: ethercateoe.c:534
EC_STATE_ACK
@ EC_STATE_ACK
Definition: ethercattype.h:170


soem
Author(s): Arthur Ketels and M.J.G. van den Molengraft
autogenerated on Wed Mar 2 2022 01:01:48