ec_master.c
Go to the documentation of this file.
1 /*****************************************************************************
2 *
3 * FILE NAME: ec_master.c
4 *
5 * DESCRIPTION: This is the main program module.
6 *
7 \*****************************************************************************/
8 
9 #include <stdio.h>
10 
11 
12 /*****************************************************************************
13 *
14 * FUNCTION: main
15 *
16 * DESCRIPTION:
17 * This is the main program module.
18 *
19 \*****************************************************************************/
20 
34 #include <stdio.h>
35 #include <string.h>
36 #include <rt.h>
37 #include <traceapi.h>
38 
39 #include "ethercat.h"
40 
41 
42 char IOmap[4096];
43 char IOmap2[4096];
44 
58 
70 
80 
87 
89 static boolean EcatError = FALSE;
90 static boolean EcatError2 = FALSE;
91 
94 
97 
98 
99 static ecx_contextt ctx [] = {
100  {
101  &ecx_port,
102  &ec_slave[0],
103  &ec_slavecount,
104  EC_MAXSLAVE,
105  &ec_groups[0],
106  EC_MAXGROUP,
107  &esibuf[0],
108  &esimap[0],
109  0,
110  &ec_elist,
111  &ec_idxstack,
112  &EcatError,
113  0,
114  0,
115  &ec_DCtime,
116  &ec_SMcommtype,
117  &ec_PDOassign,
118  &ec_PDOdesc,
119  &ec_SM,
120  &ec_FMMU
121  },
122  {
123  &ecx_port2,
124  &ec_slave2[0],
126  EC_MAXSLAVE,
127  &ec_groups2[0],
128  EC_MAXGROUP,
129  &esibuf2[0],
130  &esimap2[0],
131  0,
132  &ec_elist2,
133  &ec_idxstack2,
134  &EcatError2,
135  0,
136  0,
137  &ec_DCtime2,
139  &ec_PDOassign2,
140  &ec_PDOdesc2,
141  &ec_SM2,
142  &ec_FMMU2
143  }
144 };
145 
146 void slaveinfo(char *ifname)
147 {
148  int cnt, i, j, nSM;
149  int ctx_count;
150  uint16 ssigen;
151  int expectedWKC[2];
152  int wkc_count;
153  int chk;
154  volatile int wkc[2];
155  boolean inOP;
156 
157  printf("Starting slaveinfo\n");
158 
159  /* initialise SOEM, bind socket to ifname */
160  if (ecx_init(&ctx[0],"ie1g1") && ecx_init(&ctx[1],"ie1g0"))
161  {
162  printf("ec_init on %s succeeded.\n",ifname);
163  /* find and auto-config slaves */
164  if ( ecx_config_init(&ctx[0],FALSE) > 0 && ecx_config_init(&ctx[1],FALSE) > 0 )
165  {
166  for (ctx_count = 0; ctx_count < 2; ctx_count++)
167  {
168  ecx_config_map_group(&ctx[ctx_count], IOmap, 0);
169  ecx_configdc(&ctx[ctx_count]);
170  while(*(ctx[ctx_count].ecaterror)) printf("%s", ecx_elist2string(&ctx[ctx_count]));
171  printf("%d slaves found and configured.\n",*(ctx[ctx_count].slavecount));
172  expectedWKC[ctx_count] = ( ctx[ctx_count].grouplist[0].outputsWKC * 2) + ctx[ctx_count].grouplist[0].inputsWKC;
173  printf("Calculated workcounter %d\n", expectedWKC[ctx_count]);
174  /* wait for all slaves to reach SAFE_OP state */
175  ecx_statecheck(&ctx[ctx_count],0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE * 3);
176  if (ctx[ctx_count].slavelist[ctx_count].state != EC_STATE_SAFE_OP )
177  {
178  printf("Not all slaves reached safe operational state.\n");
179  ecx_readstate(&ctx[ctx_count]);
180  for(i = 1; i <= *(ctx[ctx_count].slavecount) ; i++)
181  {
182  if(ctx[ctx_count].slavelist[i].state != EC_STATE_SAFE_OP)
183  {
184  printf("Slave %d State=%2x StatusCode=%4x : %s\n",
185  i, ctx[ctx_count].slavelist[i].state, ctx[ctx_count].slavelist[i].ALstatuscode, ec_ALstatuscode2string(ctx[ctx_count].slavelist[i].ALstatuscode));
186  }
187  }
188  }
189  ecx_readstate(&ctx[ctx_count]);
190 
191  for( cnt = 1 ; cnt <= *(ctx[ctx_count].slavecount) ; cnt++)
192  {
193  printf("\nSlave:%d\n Name:%s\n Output size: %dbits\n Input size: %dbits\n State: %d\n Delay: %d[ns]\n Has DC: %d\n",
194  cnt, ctx[ctx_count].slavelist[cnt].name, ctx[ctx_count].slavelist[cnt].Obits, ctx[ctx_count].slavelist[cnt].Ibits,
195  ctx[ctx_count].slavelist[cnt].state, ctx[ctx_count].slavelist[cnt].pdelay, ctx[ctx_count].slavelist[cnt].hasdc);
196  if (ctx[ctx_count].slavelist[cnt].hasdc)
197  {
198  printf(" DCParentport:%d\n", ctx[ctx_count].slavelist[cnt].parentport);
199  }
200  printf(" Activeports:%d.%d.%d.%d\n", (ctx[ctx_count].slavelist[cnt].activeports & 0x01) > 0 ,
201  (ctx[ctx_count].slavelist[cnt].activeports & 0x02) > 0 ,
202  (ctx[ctx_count].slavelist[cnt].activeports & 0x04) > 0 ,
203  (ctx[ctx_count].slavelist[cnt].activeports & 0x08) > 0 );
204  printf(" Configured address: %4.4x\n", ctx[ctx_count].slavelist[cnt].configadr);
205  printf(" Man: %8.8x ID: %8.8x Rev: %8.8x\n", (int)ctx[ctx_count].slavelist[cnt].eep_man,
206  (int)ctx[ctx_count].slavelist[cnt].eep_id, (int)ctx[ctx_count].slavelist[cnt].eep_rev);
207  for(nSM = 0 ; nSM < EC_MAXSM ; nSM++)
208  {
209  if(ctx[ctx_count].slavelist[cnt].SM[nSM].StartAddr > 0)
210  printf(" SM%1d A:%4.4x L:%4d F:%8.8x Type:%d\n",nSM, ctx[ctx_count].slavelist[cnt].SM[nSM].StartAddr,
211  ctx[ctx_count].slavelist[cnt].SM[nSM].SMlength,(int)ctx[ctx_count].slavelist[cnt].SM[nSM].SMflags,
212  ctx[ctx_count].slavelist[cnt].SMtype[nSM]);
213  }
214  for(j = 0 ; j < ctx[ctx_count].slavelist[cnt].FMMUunused ; j++)
215  {
216  printf(" FMMU%1d Ls:%8.8x Ll:%4d Lsb:%d Leb:%d Ps:%4.4x Psb:%d Ty:%2.2x Act:%2.2x\n", j,
217  (int)ctx[ctx_count].slavelist[cnt].FMMU[j].LogStart, ctx[ctx_count].slavelist[cnt].FMMU[j].LogLength,
218  ctx[ctx_count].slavelist[cnt].FMMU[j].LogStartbit, ctx[ctx_count].slavelist[cnt].FMMU[j].LogEndbit,
219  ctx[ctx_count].slavelist[cnt].FMMU[j].PhysStart, ctx[ctx_count].slavelist[cnt].FMMU[j].PhysStartBit,
220  ctx[ctx_count].slavelist[cnt].FMMU[j].FMMUtype, ctx[ctx_count].slavelist[cnt].FMMU[j].FMMUactive);
221  }
222  printf(" FMMUfunc 0:%d 1:%d 2:%d 3:%d\n",
223  ctx[ctx_count].slavelist[cnt].FMMU0func, ctx[ctx_count].slavelist[cnt].FMMU1func, ctx[ctx_count].slavelist[cnt].FMMU2func,
224  ctx[ctx_count].slavelist[cnt].FMMU3func);
225  printf(" MBX length wr: %d rd: %d MBX protocols : %2.2x\n", ctx[ctx_count].slavelist[cnt].mbx_l,
226  ctx[ctx_count].slavelist[cnt].mbx_rl, ctx[ctx_count].slavelist[cnt].mbx_proto);
227  ssigen = ecx_siifind(&ctx[ctx_count], cnt, ECT_SII_GENERAL);
228  /* SII general section */
229  if (ssigen)
230  {
231  ctx[ctx_count].slavelist[cnt].CoEdetails = ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x07);
232  ctx[ctx_count].slavelist[cnt].FoEdetails = ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x08);
233  ctx[ctx_count].slavelist[cnt].EoEdetails = ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x09);
234  ctx[ctx_count].slavelist[cnt].SoEdetails = ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x0a);
235  if((ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x0d) & 0x02) > 0)
236  {
237  ctx[ctx_count].slavelist[cnt].blockLRW = 1;
238  ctx[ctx_count].slavelist[0].blockLRW++;
239  }
240  ctx[ctx_count].slavelist[cnt].Ebuscurrent = ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x0e);
241  ctx[ctx_count].slavelist[cnt].Ebuscurrent += ecx_siigetbyte(&ctx[ctx_count], cnt, ssigen + 0x0f) << 8;
242  ctx[ctx_count].slavelist[0].Ebuscurrent += ctx[ctx_count].slavelist[cnt].Ebuscurrent;
243  }
244  printf(" CoE details: %2.2x FoE details: %2.2x EoE details: %2.2x SoE details: %2.2x\n",
245  ctx[ctx_count].slavelist[cnt].CoEdetails, ctx[ctx_count].slavelist[cnt].FoEdetails, ctx[ctx_count].slavelist[cnt].EoEdetails, ctx[ctx_count].slavelist[cnt].SoEdetails);
246  printf(" Ebus current: %d[mA]\n only LRD/LWR:%d\n",
247  ctx[ctx_count].slavelist[cnt].Ebuscurrent, ctx[ctx_count].slavelist[cnt].blockLRW);
248  }
249  }
250 
251  inOP = FALSE;
252 
253  printf("Request operational state for all slaves\n");
254  expectedWKC[0] = (ctx[0].grouplist[0].outputsWKC * 2) + ctx[0].grouplist[0].inputsWKC;
255  expectedWKC[1] = (ctx[1].grouplist[0].outputsWKC * 2) + ctx[1].grouplist[0].inputsWKC;
256  printf("Calculated workcounter master 1 %d\n", expectedWKC[0]);
257  printf("Calculated workcounter master 2 %d\n", expectedWKC[1]);
260  /* send one valid process data to make outputs in slaves happy*/
261  ecx_send_processdata(&ctx[0]);
262  ecx_send_processdata(&ctx[1]);
265  /* request OP state for all slaves */
266  ecx_writestate(&ctx[0], 0);
267  ecx_writestate(&ctx[1], 0);
268  chk = 40;
269  /* wait for all slaves to reach OP state */
270  do
271  {
272  ecx_send_processdata(&ctx[0]);
273  ecx_send_processdata(&ctx[1]);
276  ecx_statecheck(&ctx[0],0, EC_STATE_OPERATIONAL, 50000);
277  ecx_statecheck(&ctx[1],0, EC_STATE_OPERATIONAL, 50000);
278  }
279  while (chk-- && (ctx[0].slavelist[0].state != EC_STATE_OPERATIONAL) && (ctx[1].slavelist[0].state != EC_STATE_OPERATIONAL));
280 
281 
282  *(ctx[0].slavelist[6].outputs) = 0xFF;
283  *(ctx[1].slavelist[1].outputs) = 0x0F;
284 
285  if (ctx[0].slavelist[0].state == EC_STATE_OPERATIONAL && ctx[1].slavelist[0].state == EC_STATE_OPERATIONAL )
286  {
287  printf("Operational state reached for all slaves.\n");
288  /* cyclic loop */
289  start_RT_trace (1);
290  wkc_count = 0;
291  inOP = TRUE;
292  for(i = 1; i <= 10000; i++)
293  {
294  for (ctx_count = 0; ctx_count < 2; ctx_count++)
295  {
296  /* Receive processdata */
297  log_RT_event('R',(WORD)(1 + ctx_count * 10));
298  wkc[ctx_count] = ecx_receive_processdata(&ctx[ctx_count], 0);
299  log_RT_event('R',(WORD)(99 + ctx_count * 100));
300  }
301  for (ctx_count = 0; ctx_count < 2; ctx_count++)
302  {
303  /* Send processdata */
304  log_RT_event('S',(WORD)(1 + ctx_count * 10));
305  if (!ecx_send_processdata(&ctx[ctx_count]))
306  {
307  printf (" Frame no: %d on master %d,Not sentOK\n", i,ctx_count);
308  }
309  log_RT_event('S',(WORD)(99 + ctx_count * 100));
310  }
311  knRtSleep(1);
312 
313  for (ctx_count = 0; ctx_count < 2; ctx_count++)
314  {
315  if(wkc[ctx_count] >= expectedWKC[ctx_count])
316  {
317  }
318  else
319  {
320  printf (" Frame no: %d on master %d , wc not wkc >= expectedWKC, %d\n",i, ctx_count, wkc[ctx_count]);
321  }
322  }
323  }
324  stop_RT_trace ();
325  inOP = FALSE;
326 
327  }
328  }
329  else
330  {
331  printf("No slaves found!\n");
332  }
333  printf("End slaveinfo, close socket\n");
334  /* stop SOEM, close socket */
335  ecx_close(&ctx[0]);
336  ecx_close(&ctx[1]);
337  }
338  else
339  {
340  printf("No socket connection on %s\nExcecute as root\n",ifname);
341  }
342 }
343 
344 
345 void main(int argc, char* argv[])
346 {
347  printf("SOEM (Simple Open EtherCAT Master)\nSlaveinfo\n");
348 
349  if (argc > 1)
350  {
351  /* start slaveinfo */
352  slaveinfo(argv[1]);
353  }
354  else
355  {
356  printf("Usage: slaveinfo ifname [options]\nifname = eth0 for example\nOptions :\n -sdo : print SDO info\n -map : print mapping\n");
357  }
358 
359  printf("End program\n");
360 
361 }
362 
static ec_PDOassignt ec_PDOassign2
Definition: ec_master.c:76
int ecx_send_processdata(ecx_contextt *context)
int expectedWKC
Definition: eoe_test.c:33
char * ec_ALstatuscode2string(uint16 ALstatuscode)
static uint32 esimap[EC_MAXEEPBITMAP]
Definition: ec_master.c:63
static ec_SMcommtypet ec_SMcommtype2
Definition: ec_master.c:73
uint8 ecx_siigetbyte(ecx_contextt *context, uint16 slave, uint16 address)
Definition: ethercatmain.c:334
uint16 outputsWKC
Definition: ethercatmain.h:266
#define EC_MAXGROUP
Definition: ethercatmain.h:27
#define EC_TIMEOUTSTATE
Definition: ethercattype.h:76
int ec_slavecount
Definition: ec_master.c:53
static ecx_portt ecx_port2
Definition: ec_master.c:96
void ecx_close(ecx_contextt *context)
Definition: ethercatmain.c:321
static ec_idxstackT ec_idxstack2
Definition: ec_master.c:69
uint8 * outputs
Definition: ethercatmain.h:131
uint8_t uint8
Definition: osal.h:28
uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int timeout)
Definition: ethercatmain.c:862
uint8 FoEdetails
Definition: ethercatmain.h:215
void slaveinfo(char *ifname)
Definition: ec_master.c:146
#define EC_MAXEEPBUF
Definition: ethercattype.h:80
int16 Ebuscurrent
Definition: ethercatmain.h:221
int ec_slavecount2
Definition: ec_master.c:54
Headerfile for all ethercat headers.
static ec_eepromFMMUt ec_FMMU2
Definition: ec_master.c:86
PACKED_BEGIN struct PACKED ec_SMcommtype ec_SMcommtypet
static ec_eepromSMt ec_SM
Definition: ec_master.c:82
uint16 state
Definition: ethercatmain.h:109
uint16_t uint16
Definition: osal.h:29
char IOmap2[4096]
Definition: ec_master.c:43
#define EC_MAXEEPBITMAP
Definition: ethercattype.h:78
#define TRUE
Definition: osal.h:19
void main(int argc, char *argv[])
Definition: ec_master.c:345
static ec_eepromSMt ec_SM2
Definition: ec_master.c:83
uint8 CoEdetails
Definition: ethercatmain.h:213
int64 ec_DCtime2
Definition: ec_master.c:93
PACKED_END struct ec_idxstack ec_idxstackT
#define EC_MAXSM
Definition: ethercatmain.h:35
ec_groupt * grouplist
Definition: ethercatmain.h:395
int ecx_config_init(ecx_contextt *context, uint8 usetable)
static ec_PDOdesct ec_PDOdesc2
Definition: ec_master.c:79
static boolean EcatError
Definition: ec_master.c:89
char IOmap[4096]
Definition: ec_master.c:42
int ecx_init(ecx_contextt *context, const char *ifname)
Definition: ethercatmain.c:288
PACKED_END PACKED_BEGIN struct PACKED ec_PDOassign ec_PDOassignt
int ecx_writestate(ecx_contextt *context, uint16 slave)
Definition: ethercatmain.c:832
static ec_eringt ec_elist2
Definition: ec_master.c:67
uint8 blockLRW
Definition: ethercatmain.h:223
int64_t int64
Definition: osal.h:31
#define FALSE
Definition: osal.h:22
static ec_PDOassignt ec_PDOassign
Definition: ec_master.c:75
static ec_eepromFMMUt ec_FMMU
Definition: ec_master.c:85
char * ecx_elist2string(ecx_contextt *context)
static ec_SMcommtypet ec_SMcommtype
Definition: ec_master.c:72
int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group)
uint8 EoEdetails
Definition: ethercatmain.h:217
static ec_eringt ec_elist
Definition: ec_master.c:66
PACKED_END PACKED_BEGIN struct PACKED ec_PDOdesc ec_PDOdesct
#define EC_TIMEOUTRET
Definition: ethercattype.h:64
boolean ecx_configdc(ecx_contextt *context)
Definition: ethercatdc.c:252
ec_groupt ec_groups2[EC_MAXGROUP]
Definition: ec_master.c:57
int wkc
Definition: aliastool.c:47
#define EC_MAXSLAVE
Definition: ethercatmain.h:25
static ec_PDOdesct ec_PDOdesc
Definition: ec_master.c:78
static ec_idxstackT ec_idxstack
Definition: ec_master.c:68
uint32_t uint32
Definition: osal.h:30
boolean inOP
Definition: eoe_test.c:36
int ecx_readstate(ecx_contextt *context)
Definition: ethercatmain.c:723
static boolean EcatError2
Definition: ec_master.c:90
static ecx_portt ecx_port
Definition: ec_master.c:95
uint8 SoEdetails
Definition: ethercatmain.h:219
int16 ecx_siifind(ecx_contextt *context, uint16 slave, uint16 cat)
Definition: ethercatmain.c:405
static uint32 esimap2[EC_MAXEEPBITMAP]
Definition: ec_master.c:64
ec_groupt ec_groups[EC_MAXGROUP]
Definition: ec_master.c:56
uint8 FMMUunused
Definition: ethercatmain.h:227
int ecx_receive_processdata(ecx_contextt *context, int timeout)
static uint8 esibuf[EC_MAXEEPBUF]
Definition: ec_master.c:60
static uint8 esibuf2[EC_MAXEEPBUF]
Definition: ec_master.c:61
int64 ec_DCtime
Definition: ec_master.c:92
ec_slavet ec_slave2[EC_MAXSLAVE]
Definition: ec_master.c:51
static ecx_contextt ctx[]
Definition: ec_master.c:99
ec_slavet * slavelist
Definition: ethercatmain.h:389
int * slavecount
Definition: ethercatmain.h:391


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