aliastool.c
Go to the documentation of this file.
1 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/time.h>
21 #include <unistd.h>
22 #include <time.h>
23 
24 #include "ethercat.h"
25 
26 #define MAXBUF 32768
27 #define STDBUF 2048
28 #define MINBUF 128
29 
30 #define MODE_NONE 0
31 #define MODE_READBIN 1
32 #define MODE_READINTEL 2
33 #define MODE_WRITEBIN 3
34 #define MODE_WRITEINTEL 4
35 #define MODE_WRITEALIAS 5
36 #define MODE_INFO 6
37 
38 #define MAXSLENGTH 256
39 
43 int os;
44 int slave;
45 int alias;
46 struct timeval tstart,tend, tdif;
47 int wkc;
48 int mode;
50 
51 #define IHEXLENGTH 0x20
52 
53 int input_bin(char *fname, int *length)
54 {
55  FILE *fp;
56 
57  int cc = 0, c;
58 
59  fp = fopen(fname, "rb");
60  if(fp == NULL)
61  return 0;
62  while (((c = fgetc(fp)) != EOF) && (cc < MAXBUF))
63  ebuf[cc++] = (uint8)c;
64  *length = cc;
65  fclose(fp);
66 
67  return 1;
68 }
69 
70 int input_intelhex(char *fname, int *start, int *length)
71 {
72  FILE *fp;
73 
74  int c, sc, retval = 1;
75  int ll, ladr, lt, sn, i, lval;
76  int hstart, hlength, sum;
77 
78  fp = fopen(fname, "r");
79  if(fp == NULL)
80  return 0;
81  hstart = MAXBUF;
82  hlength = 0;
83  sum = 0;
84  do
85  {
86  memset(sline, 0x00, MAXSLENGTH);
87  sc = 0;
88  while (((c = fgetc(fp)) != EOF) && (c != 0x0A) && (sc < (MAXSLENGTH -1)))
89  sline[sc++] = (uint8)c;
90  if ((c != EOF) && ((sc < 11) || (sline[0] != ':')))
91  {
92  c = EOF;
93  retval = 0;
94  printf("Invalid Intel Hex format.\n");
95  }
96  if (c != EOF)
97  {
98  sn = sscanf(sline , ":%2x%4x%2x", &ll, &ladr, &lt);
99  if ((sn == 3) && ((ladr + ll) <= MAXBUF) && (lt == 0))
100  {
101  sum = ll + (ladr >> 8) + (ladr & 0xff) + lt;
102  if(ladr < hstart) hstart = ladr;
103  for(i = 0; i < ll ; i++)
104  {
105  sn = sscanf(&sline[9 + (i << 1)], "%2x", &lval);
106  ebuf[ladr + i] = (uint8)lval;
107  sum += (uint8)lval;
108  }
109  if(((ladr + ll) - hstart) > hlength)
110  hlength = (ladr + ll) - hstart;
111  sum = (0x100 - sum) & 0xff;
112  sn = sscanf(&sline[9 + (i << 1)], "%2x", &lval);
113  if (!sn || ((sum - lval) != 0))
114  {
115  c = EOF;
116  retval = 0;
117  printf("Invalid checksum.\n");
118  }
119  }
120  }
121  }
122  while (c != EOF);
123  if (retval)
124  {
125  *length = hlength;
126  *start = hstart;
127  }
128  fclose(fp);
129 
130  return retval;
131 }
132 
133 int output_bin(char *fname, int length)
134 {
135  FILE *fp;
136 
137  int cc;
138 
139  fp = fopen(fname, "wb");
140  if(fp == NULL)
141  return 0;
142  for (cc = 0 ; cc < length ; cc++)
143  fputc( ebuf[cc], fp);
144  fclose(fp);
145 
146  return 1;
147 }
148 
149 int output_intelhex(char *fname, int length)
150 {
151  FILE *fp;
152 
153  int cc = 0, ll, sum, i;
154 
155  fp = fopen(fname, "w");
156  if(fp == NULL)
157  return 0;
158  while (cc < length)
159  {
160  ll = length - cc;
161  if (ll > IHEXLENGTH) ll = IHEXLENGTH;
162  sum = ll + (cc >> 8) + (cc & 0xff);
163  fprintf(fp, ":%2.2X%4.4X00", ll, cc);
164  for (i = 0; i < ll; i++)
165  {
166  fprintf(fp, "%2.2X", ebuf[cc + i]);
167  sum += ebuf[cc + i];
168  }
169  fprintf(fp, "%2.2X\n", (0x100 - sum) & 0xff);
170  cc += ll;
171  }
172  fprintf(fp, ":00000001FF\n");
173  fclose(fp);
174 
175  return 1;
176 }
177 
178 int eeprom_read(int slave, int start, int length)
179 {
180  int i, wkc, ainc = 4;
181  uint16 estat, aiadr;
182  uint32 b4;
183  uint64 b8;
184  uint8 eepctl;
185 
186  if((ec_slavecount >= slave) && (slave > 0) && ((start + length) <= MAXBUF))
187  {
188  aiadr = 1 - slave;
189  eepctl = 2;
190  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
191  eepctl = 0;
192  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
193 
194  estat = 0x0000;
195  aiadr = 1 - slave;
196  wkc=ec_APRD(aiadr, ECT_REG_EEPSTAT, sizeof(estat), &estat, EC_TIMEOUTRET); /* read eeprom status */
197  estat = etohs(estat);
198  if (estat & EC_ESTAT_R64)
199  {
200  ainc = 8;
201  for (i = start ; i < (start + length) ; i+=ainc)
202  {
203  b8 = ec_readeepromAP(aiadr, i >> 1 , EC_TIMEOUTEEP);
204  ebuf[i] = b8;
205  ebuf[i+1] = b8 >> 8;
206  ebuf[i+2] = b8 >> 16;
207  ebuf[i+3] = b8 >> 24;
208  ebuf[i+4] = b8 >> 32;
209  ebuf[i+5] = b8 >> 40;
210  ebuf[i+6] = b8 >> 48;
211  ebuf[i+7] = b8 >> 56;
212  }
213  }
214  else
215  {
216  for (i = start ; i < (start + length) ; i+=ainc)
217  {
218  b4 = ec_readeepromAP(aiadr, i >> 1 , EC_TIMEOUTEEP);
219  ebuf[i] = b4;
220  ebuf[i+1] = b4 >> 8;
221  ebuf[i+2] = b4 >> 16;
222  ebuf[i+3] = b4 >> 24;
223  }
224  }
225 
226  return 1;
227  }
228 
229  return 0;
230 }
231 
232 int eeprom_write(int slave, int start, int length)
233 {
234  int i, wkc, dc = 0;
235  uint16 aiadr, *wbuf;
236  uint8 eepctl;
237  int ret;
238 
239  if((ec_slavecount >= slave) && (slave > 0) && ((start + length) <= MAXBUF))
240  {
241  aiadr = 1 - slave;
242  eepctl = 2;
243  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
244  eepctl = 0;
245  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
246 
247  aiadr = 1 - slave;
248  wbuf = (uint16 *)&ebuf[0];
249  for (i = start ; i < (start + length) ; i+=2)
250  {
251  ret = ec_writeeepromAP(aiadr, i >> 1 , *(wbuf + (i >> 1)), EC_TIMEOUTEEP);
252  if (++dc >= 100)
253  {
254  dc = 0;
255  printf(".");
256  fflush(stdout);
257  }
258  }
259 
260  return 1;
261  }
262 
263  return 0;
264 }
265 
267 {
268  int i, wkc, dc = 0;
269  uint16 aiadr, *wbuf;
270  uint8 eepctl;
271  int ret;
272 
273  if((ec_slavecount >= slave) && (slave > 0) && (alias <= 0xffff))
274  {
275  aiadr = 1 - slave;
276  eepctl = 2;
277  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
278  eepctl = 0;
279  wkc = ec_APWR(aiadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
280 
281  ret = ec_writeeepromAP(aiadr, 0x04 , alias, EC_TIMEOUTEEP);
282 
283  return ret;
284  }
285 
286  return 0;
287 }
288 
289 void eepromtool(char *ifname, int slave, int mode, char *fname)
290 {
291  int w, rc = 0, estart, esize;
292  uint16 *wbuf;
293 
294  /* initialise SOEM, bind socket to ifname */
295  if (ec_init(ifname))
296  {
297  printf("ec_init on %s succeeded.\n",ifname);
298 
299  w = 0x0000;
300  wkc = ec_BRD(0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE); /* detect number of slaves */
301  if (wkc > 0)
302  {
303  ec_slavecount = wkc;
304 
305  printf("%d slaves found.\n",ec_slavecount);
306  if((ec_slavecount >= slave) && (slave > 0))
307  {
308  if ((mode == MODE_INFO) || (mode == MODE_READBIN) || (mode == MODE_READINTEL))
309  {
310  rc = gettimeofday(&tstart, NULL);
311  eeprom_read(slave, 0x0000, MINBUF); // read first 128 bytes
312 
313  wbuf = (uint16 *)&ebuf[0];
314  printf("Slave %d data\n", slave);
315  printf(" PDI Control : %4.4X\n",*(wbuf + 0x00));
316  printf(" PDI Config : %4.4X\n",*(wbuf + 0x01));
317  printf(" Config Alias : %4.4X\n",*(wbuf + 0x04));
318  printf(" Checksum : %4.4X\n",*(wbuf + 0x07));
319  printf(" Vendor ID : %8.8X\n",*(uint32 *)(wbuf + 0x08));
320  printf(" Product Code : %8.8X\n",*(uint32 *)(wbuf + 0x0A));
321  printf(" Revision Number : %8.8X\n",*(uint32 *)(wbuf + 0x0C));
322  printf(" Serial Number : %8.8X\n",*(uint32 *)(wbuf + 0x0E));
323  printf(" Mailbox Protocol : %4.4X\n",*(wbuf + 0x1C));
324  esize = (*(wbuf + 0x3E) + 1) * 128;
325  if (esize > MAXBUF) esize = MAXBUF;
326  printf(" Size : %4.4X = %d bytes\n",*(wbuf + 0x3E), esize);
327  printf(" Version : %4.4X\n",*(wbuf + 0x3F));
328  }
329  if ((mode == MODE_READBIN) || (mode == MODE_READINTEL))
330  {
331  if (esize > MINBUF)
332  eeprom_read(slave, MINBUF, esize - MINBUF); // read reminder
333 
334  rc = gettimeofday(&tend, NULL);
335  timersub(&tend, &tstart, &tdif);
336  if (mode == MODE_READINTEL) output_intelhex(fname, esize);
337  if (mode == MODE_READBIN) output_bin(fname, esize);
338 
339  printf("\nTotal EEPROM read time :%ldms\n", (tdif.tv_usec+(tdif.tv_sec*1000000L)) / 1000);
340  }
341  if ((mode == MODE_WRITEBIN) || (mode == MODE_WRITEINTEL))
342  {
343  estart = 0;
344  if (mode == MODE_WRITEINTEL) rc = input_intelhex(fname, &estart, &esize);
345  if (mode == MODE_WRITEBIN) rc = input_bin(fname, &esize);
346 
347  if (rc > 0)
348  {
349  wbuf = (uint16 *)&ebuf[0];
350  printf("Slave %d\n", slave);
351  printf(" Vendor ID : %8.8X\n",*(uint32 *)(wbuf + 0x08));
352  printf(" Product Code : %8.8X\n",*(uint32 *)(wbuf + 0x0A));
353  printf(" Revision Number : %8.8X\n",*(uint32 *)(wbuf + 0x0C));
354  printf(" Serial Number : %8.8X\n",*(uint32 *)(wbuf + 0x0E));
355 
356  printf("Busy");
357  fflush(stdout);
358  rc = gettimeofday(&tstart, NULL);
359  eeprom_write(slave, estart, esize);
360  rc = gettimeofday(&tend, NULL);
361  timersub(&tend, &tstart, &tdif);
362 
363  printf("\nTotal EEPROM write time :%ldms\n", (tdif.tv_usec+(tdif.tv_sec*1000000L)) / 1000);
364  }
365  else
366  printf("Error reading file, abort.\n");
367  }
368  if (mode == MODE_WRITEALIAS)
369  {
370  if(eeprom_writealias(slave, alias))
371  printf("Alias %4.4X written successfully to slave %d\n");
372  else
373  printf("Alias not written\n");
374  }
375  }
376  else
377  printf("Slave number outside range.\n");
378  }
379  else
380  printf("No slaves found!\n");
381  printf("End, close socket\n");
382  /* stop SOEM, close socket */
383  ec_close();
384  }
385  else
386  printf("No socket connection on %s\nExcecute as root\n",ifname);
387 }
388 
389 int main(int argc, char *argv[])
390 {
391  printf("SOEM (Simple Open EtherCAT Master)\nEEPROM tool\n");
392 
393  mode = MODE_NONE;
394  if (argc > 3)
395  {
396  slave = atoi(argv[2]);
397  if ((strncmp(argv[3], "-i", sizeof("-i")) == 0)) mode = MODE_INFO;
398  if (argc > 4)
399  {
400  if ((strncmp(argv[3], "-r", sizeof("-r")) == 0)) mode = MODE_READBIN;
401  if ((strncmp(argv[3], "-ri", sizeof("-ri")) == 0)) mode = MODE_READINTEL;
402  if ((strncmp(argv[3], "-w", sizeof("-w")) == 0)) mode = MODE_WRITEBIN;
403  if ((strncmp(argv[3], "-wi", sizeof("-wi")) == 0)) mode = MODE_WRITEINTEL;
404  if ((strncmp(argv[3], "-walias", sizeof("-walias")) == 0))
405  {
407  alias = atoi(argv[4]);
408  }
409  }
410  /* start tool */
411  eepromtool(argv[1],slave,mode,argv[4]);
412  }
413  else
414  {
415  printf("Usage: eepromtool ifname slave OPTION fname|alias\n");
416  printf("ifname = eth0 for example\n");
417  printf("slave = slave number in EtherCAT order 1..n\n");
418  printf(" -i display EEPROM information\n");
419  printf(" -walias write slave alias\n");
420  printf(" -r read EEPROM, output binary format\n");
421  printf(" -ri read EEPROM, output Intel Hex format\n");
422  printf(" -w write EEPROM, input binary format\n");
423  printf(" -wi write EEPROM, input Intel Hex format\n");
424  }
425 
426  printf("End program\n");
427 
428  return (0);
429 }
int eeprom_read(int slave, int start, int length)
Definition: aliastool.c:178
ec_timet tend
int ec_writeeepromAP(uint16 aiadr, uint16 eeproma, uint16 data, int timeout)
int ec_APWR(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:598
int ec_APRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:559
#define MODE_READBIN
Definition: aliastool.c:31
#define timersub(a, b, result)
Definition: rtk/osal.c:26
#define MAXSLENGTH
Definition: aliastool.c:38
#define MAXBUF
Definition: aliastool.c:26
#define EC_TIMEOUTSAFE
Definition: ethercattype.h:68
uint8_t uint8
Definition: osal.h:28
#define MODE_WRITEINTEL
Definition: aliastool.c:34
void eepromtool(char *ifname, int slave, int mode, char *fname)
Definition: aliastool.c:289
Headerfile for all ethercat headers.
int ec_init(const char *ifname)
uint16_t uint16
Definition: osal.h:29
#define MODE_INFO
Definition: aliastool.c:36
#define etohs(A)
Definition: ethercattype.h:536
int output_intelhex(char *fname, int length)
Definition: aliastool.c:149
struct timeval tstart tend tdif
Definition: aliastool.c:46
int alias
Definition: aliastool.c:45
int eeprom_write(int slave, int start, int length)
Definition: aliastool.c:232
int input_intelhex(char *fname, int *start, int *length)
Definition: aliastool.c:70
uint8 ob
Definition: aliastool.c:41
int ec_BRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
Definition: ethercatbase.c:554
char sline[MAXSLENGTH]
Definition: aliastool.c:49
int ec_slavecount
Definition: ethercatmain.c:69
int os
Definition: aliastool.c:43
int slave
Definition: aliastool.c:44
#define MODE_WRITEALIAS
Definition: aliastool.c:35
#define EC_TIMEOUTEEP
Definition: ethercattype.h:70
uint64_t uint64
Definition: osal.h:32
ec_timet tstart
#define EC_TIMEOUTRET
Definition: ethercattype.h:64
int wkc
Definition: aliastool.c:47
uint64 ec_readeepromAP(uint16 aiadr, uint16 eeproma, int timeout)
#define MINBUF
Definition: aliastool.c:28
int main(int argc, char *argv[])
Definition: aliastool.c:389
uint32_t uint32
Definition: osal.h:30
int gettimeofday(struct timeval *tp, void *tzp)
Definition: rtk/osal.c:50
uint8 ebuf[MAXBUF]
Definition: aliastool.c:40
#define MODE_NONE
Definition: aliastool.c:30
void ec_close(void)
int input_bin(char *fname, int *length)
Definition: aliastool.c:53
#define MODE_WRITEBIN
Definition: aliastool.c:33
int ainc
uint16 ow
Definition: aliastool.c:42
int output_bin(char *fname, int length)
Definition: aliastool.c:133
int mode
Definition: aliastool.c:48
int eeprom_writealias(int slave, int alias)
Definition: aliastool.c:266
#define EC_ESTAT_R64
Definition: ethercattype.h:271
#define IHEXLENGTH
Definition: aliastool.c:51
#define MODE_READINTEL
Definition: aliastool.c:32


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