ethercatfoe.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 
13 #include <stdio.h>
14 #include <string.h>
15 #include "osal.h"
16 #include "oshw.h"
17 #include "ethercattype.h"
18 #include "ethercatbase.h"
19 #include "ethercatmain.h"
20 #include "ethercatfoe.h"
21 
22 #define EC_MAXFOEDATA 512
23 
28 typedef struct PACKED
29 {
33  union
34  {
38  };
39  union
40  {
44  };
45 } ec_FOEt;
47 
54 int ecx_FOEdefinehook(ecx_contextt *context, void *hook)
55 {
56  context->FOEhook = hook;
57  return 1;
58 }
59 
71 int ecx_FOEread(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout)
72 {
73  ec_FOEt *FOEp, *aFOEp;
74  int wkc;
75  int32 dataread = 0;
76  int32 buffersize, packetnumber, prevpacket = 0;
77  uint16 fnsize, maxdata, segmentdata;
78  ec_mbxbuft MbxIn, MbxOut;
79  uint8 cnt;
80  boolean worktodo;
81 
82  buffersize = *psize;
83  ec_clearmbx(&MbxIn);
84  /* Empty slave out mailbox if something is in. Timeout set to 0 */
85  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
86  ec_clearmbx(&MbxOut);
87  aFOEp = (ec_FOEt *)&MbxIn;
88  FOEp = (ec_FOEt *)&MbxOut;
89  fnsize = (uint16)strlen(filename);
90  maxdata = context->slavelist[slave].mbx_l - 12;
91  if (fnsize > maxdata)
92  {
93  fnsize = maxdata;
94  }
95  FOEp->MbxHeader.length = htoes(0x0006 + fnsize);
96  FOEp->MbxHeader.address = htoes(0x0000);
97  FOEp->MbxHeader.priority = 0x00;
98  /* get new mailbox count value, used as session handle */
99  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
100  context->slavelist[slave].mbx_cnt = cnt;
101  FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
102  FOEp->OpCode = ECT_FOE_READ;
103  FOEp->Password = htoel(password);
104  /* copy filename in mailbox */
105  memcpy(&FOEp->FileName[0], filename, fnsize);
106  /* send FoE request to slave */
107  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
108  if (wkc > 0) /* succeeded to place mailbox in slave ? */
109  {
110  do
111  {
112  worktodo = FALSE;
113  /* clean mailboxbuffer */
114  ec_clearmbx(&MbxIn);
115  /* read slave response */
116  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
117  if (wkc > 0) /* succeeded to read slave response ? */
118  {
119  /* slave response should be FoE */
120  if ((aFOEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_FOE)
121  {
122  if(aFOEp->OpCode == ECT_FOE_DATA)
123  {
124  segmentdata = etohs(aFOEp->MbxHeader.length) - 0x0006;
125  packetnumber = etohl(aFOEp->PacketNumber);
126  if ((packetnumber == ++prevpacket) && (dataread + segmentdata <= buffersize))
127  {
128  memcpy(p, &aFOEp->Data[0], segmentdata);
129  dataread += segmentdata;
130  p = (uint8 *)p + segmentdata;
131  if (segmentdata == maxdata)
132  {
133  worktodo = TRUE;
134  }
135  FOEp->MbxHeader.length = htoes(0x0006);
136  FOEp->MbxHeader.address = htoes(0x0000);
137  FOEp->MbxHeader.priority = 0x00;
138  /* get new mailbox count value */
139  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
140  context->slavelist[slave].mbx_cnt = cnt;
141  FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
142  FOEp->OpCode = ECT_FOE_ACK;
143  FOEp->PacketNumber = htoel(packetnumber);
144  /* send FoE ack to slave */
145  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
146  if (wkc <= 0)
147  {
148  worktodo = FALSE;
149  }
150  if (context->FOEhook)
151  {
152  context->FOEhook(slave, packetnumber, dataread);
153  }
154  }
155  else
156  {
157  /* FoE error */
159  }
160  }
161  else
162  {
163  if(aFOEp->OpCode == ECT_FOE_ERROR)
164  {
165  /* FoE error */
167  }
168  else
169  {
170  /* unexpected mailbox received */
172  }
173  }
174  }
175  else
176  {
177  /* unexpected mailbox received */
179  }
180  *psize = dataread;
181  }
182  } while (worktodo);
183  }
184 
185  return wkc;
186 }
187 
199 int ecx_FOEwrite(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout)
200 {
201  ec_FOEt *FOEp, *aFOEp;
202  int wkc;
203  int32 packetnumber, sendpacket = 0;
204  uint16 fnsize, maxdata;
205  int segmentdata;
206  ec_mbxbuft MbxIn, MbxOut;
207  uint8 cnt;
208  boolean worktodo, dofinalzero;
209  int tsize;
210 
211  ec_clearmbx(&MbxIn);
212  /* Empty slave out mailbox if something is in. Timeout set to 0 */
213  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
214  ec_clearmbx(&MbxOut);
215  aFOEp = (ec_FOEt *)&MbxIn;
216  FOEp = (ec_FOEt *)&MbxOut;
217  dofinalzero = FALSE;
218  fnsize = (uint16)strlen(filename);
219  maxdata = context->slavelist[slave].mbx_l - 12;
220  if (fnsize > maxdata)
221  {
222  fnsize = maxdata;
223  }
224  FOEp->MbxHeader.length = htoes(0x0006 + fnsize);
225  FOEp->MbxHeader.address = htoes(0x0000);
226  FOEp->MbxHeader.priority = 0x00;
227  /* get new mailbox count value, used as session handle */
228  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
229  context->slavelist[slave].mbx_cnt = cnt;
230  FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
231  FOEp->OpCode = ECT_FOE_WRITE;
232  FOEp->Password = htoel(password);
233  /* copy filename in mailbox */
234  memcpy(&FOEp->FileName[0], filename, fnsize);
235  /* send FoE request to slave */
236  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
237  if (wkc > 0) /* succeeded to place mailbox in slave ? */
238  {
239  do
240  {
241  worktodo = FALSE;
242  /* clean mailboxbuffer */
243  ec_clearmbx(&MbxIn);
244  /* read slave response */
245  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
246  if (wkc > 0) /* succeeded to read slave response ? */
247  {
248  /* slave response should be FoE */
249  if ((aFOEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_FOE)
250  {
251  switch (aFOEp->OpCode)
252  {
253  case ECT_FOE_ACK:
254  {
255  packetnumber = etohl(aFOEp->PacketNumber);
256  if (packetnumber == sendpacket)
257  {
258  if (context->FOEhook)
259  {
260  context->FOEhook(slave, packetnumber, psize);
261  }
262  tsize = psize;
263  if (tsize > maxdata)
264  {
265  tsize = maxdata;
266  }
267  if(tsize || dofinalzero)
268  {
269  worktodo = TRUE;
270  dofinalzero = FALSE;
271  segmentdata = tsize;
272  psize -= segmentdata;
273  /* if last packet was full size, add a zero size packet as final */
274  /* EOF is defined as packetsize < full packetsize */
275  if (!psize && (segmentdata == maxdata))
276  {
277  dofinalzero = TRUE;
278  }
279  FOEp->MbxHeader.length = htoes(0x0006 + segmentdata);
280  FOEp->MbxHeader.address = htoes(0x0000);
281  FOEp->MbxHeader.priority = 0x00;
282  /* get new mailbox count value */
283  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
284  context->slavelist[slave].mbx_cnt = cnt;
285  FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
286  FOEp->OpCode = ECT_FOE_DATA;
287  sendpacket++;
288  FOEp->PacketNumber = htoel(sendpacket);
289  memcpy(&FOEp->Data[0], p, segmentdata);
290  p = (uint8 *)p + segmentdata;
291  /* send FoE data to slave */
292  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
293  if (wkc <= 0)
294  {
295  worktodo = FALSE;
296  }
297  }
298  }
299  else
300  {
301  /* FoE error */
303  }
304  break;
305  }
306  case ECT_FOE_BUSY:
307  {
308  /* resend if data has been send before */
309  /* otherwise ignore */
310  if (sendpacket)
311  {
312  if (!psize)
313  {
314  dofinalzero = TRUE;
315  }
316  psize += segmentdata;
317  p = (uint8 *)p - segmentdata;
318  --sendpacket;
319  }
320  break;
321  }
322  case ECT_FOE_ERROR:
323  {
324  /* FoE error */
325  if (aFOEp->ErrorCode == 0x8001)
326  {
328  }
329  else
330  {
332  }
333  break;
334  }
335  default:
336  {
337  /* unexpected mailbox received */
339  break;
340  }
341  }
342  }
343  else
344  {
345  /* unexpected mailbox received */
347  }
348  }
349  } while (worktodo);
350  }
351 
352  return wkc;
353 }
354 
355 #ifdef EC_VER1
356 int ec_FOEdefinehook(void *hook)
357 {
358  return ecx_FOEdefinehook(&ecx_context, hook);
359 }
360 
361 int ec_FOEread(uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout)
362 {
363  return ecx_FOEread(&ecx_context, slave, filename, password, psize, p, timeout);
364 }
365 
366 int ec_FOEwrite(uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout)
367 {
368  return ecx_FOEwrite(&ecx_context, slave, filename, password, psize, p, timeout);
369 }
370 #endif
PACKED::Password
uint32 Password
Definition: ethercatfoe.c:35
wkc
int wkc
Definition: aliastool.c:47
slave
int slave
Definition: aliastool.c:44
ec_slave::mbx_cnt
uint8 mbx_cnt
Definition: ethercatmain.h:167
ec_FOEt
PACKED_BEGIN struct PACKED ec_FOEt
etohs
#define etohs(A)
Definition: ethercattype.h:536
ec_FOEread
int ec_FOEread(uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout)
Definition: ethercatfoe.c:361
ecx_FOEwrite
int ecx_FOEwrite(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout)
Definition: ethercatfoe.c:199
ec_mbxbuft
uint8 ec_mbxbuft[EC_MAXMBX+1]
Definition: ethercatmain.h:312
ethercatmain.h
Headerfile for ethercatmain.c.
ecx_FOEdefinehook
PACKED_END int ecx_FOEdefinehook(ecx_contextt *context, void *hook)
Definition: ethercatfoe.c:54
EC_ERR_TYPE_PACKET_ERROR
@ EC_ERR_TYPE_PACKET_ERROR
Definition: ethercattype.h:466
uint32
uint32_t uint32
Definition: osal.h:30
ECT_FOE_WRITE
@ ECT_FOE_WRITE
Definition: ethercattype.h:372
PACKED::PacketNumber
uint32 PacketNumber
Definition: ethercatfoe.c:36
EC_ERR_TYPE_FOE_BUF2SMALL
@ EC_ERR_TYPE_FOE_BUF2SMALL
Definition: ethercattype.h:469
ECT_FOE_ACK
@ ECT_FOE_ACK
Definition: ethercattype.h:374
PACKED::Data
uint8 Data[EC_MAXFOEDATA]
Definition: ethercatfoe.c:42
EC_ERR_TYPE_FOE_ERROR
@ EC_ERR_TYPE_FOE_ERROR
Definition: ethercattype.h:468
ec_mbxheadert
PACKED_BEGIN struct PACKED ec_mbxheader ec_mbxheadert
int32
int32_t int32
Definition: osal.h:27
uint8
uint8_t uint8
Definition: osal.h:28
ethercatbase.h
Headerfile for ethercatbase.c.
ECT_FOE_BUSY
@ ECT_FOE_BUSY
Definition: ethercattype.h:376
PACKED_END
#define PACKED_END
Definition: erika/osal_defs.h:30
ec_clearmbx
void ec_clearmbx(ec_mbxbuft *Mbx)
Definition: ethercatmain.c:921
PACKED::ErrorText
char ErrorText[EC_MAXFOEDATA]
Definition: ethercatfoe.c:43
PACKED_BEGIN
#define PACKED_BEGIN
Definition: erika/osal_defs.h:28
ec_FOEdefinehook
int ec_FOEdefinehook(void *hook)
Definition: ethercatfoe.c:356
PACKED::Reserved
uint8 Reserved
Definition: ethercatcoe.c:47
PACKED
Definition: ethercatcoe.c:24
osal.h
EC_ERR_TYPE_FOE_FILE_NOTFOUND
@ EC_ERR_TYPE_FOE_FILE_NOTFOUND
Definition: ethercattype.h:473
PACKED::ErrorCode
uint32 ErrorCode
Definition: ethercatfoe.c:37
ecx_mbxsend
int ecx_mbxsend(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
Definition: ethercatmain.c:968
htoes
#define htoes(A)
Definition: ethercattype.h:533
EC_TIMEOUTTXM
#define EC_TIMEOUTTXM
Definition: ethercattype.h:72
ECT_FOE_DATA
@ ECT_FOE_DATA
Definition: ethercattype.h:373
uint16
uint16_t uint16
Definition: osal.h:29
ecx_mbxreceive
int ecx_mbxreceive(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
Definition: ethercatmain.c:1001
EC_MAXFOEDATA
#define EC_MAXFOEDATA
Definition: ethercatfoe.c:22
TRUE
#define TRUE
Definition: osal.h:19
ecx_context::slavelist
ec_slavet * slavelist
Definition: ethercatmain.h:389
ethercatfoe.h
Headerfile for ethercatfoe.c.
ec_FOEwrite
int ec_FOEwrite(uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout)
Definition: ethercatfoe.c:366
FALSE
#define FALSE
Definition: osal.h:22
PACKED::OpCode
uint8 OpCode
Definition: ethercatfoe.c:31
ecx_context
Definition: ethercatmain.h:384
ECT_FOE_ERROR
@ ECT_FOE_ERROR
Definition: ethercattype.h:375
ECT_FOE_READ
@ ECT_FOE_READ
Definition: ethercattype.h:371
htoel
#define htoel(A)
Definition: ethercattype.h:534
ecx_FOEread
int ecx_FOEread(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout)
Definition: ethercatfoe.c:71
EC_ERR_TYPE_FOE_PACKETNUMBER
@ EC_ERR_TYPE_FOE_PACKETNUMBER
Definition: ethercattype.h:470
ecx_context::FOEhook
int(* FOEhook)(uint16 slave, int packetnumber, int datasize)
Definition: ethercatmain.h:427
PACKED::FileName
char FileName[EC_MAXFOEDATA]
Definition: ethercatfoe.c:41
ec_nextmbxcnt
uint8 ec_nextmbxcnt(uint8 cnt)
Definition: ethercatmain.c:907
ethercattype.h
General typedefs and defines for EtherCAT.
etohl
#define etohl(A)
Definition: ethercattype.h:537
filename
char filename[256]
Definition: linux/firm_update/firm_update.c:28
ec_slave::mbx_l
uint16 mbx_l
Definition: ethercatmain.h:157
ECT_MBXT_FOE
@ ECT_MBXT_FOE
Definition: ethercattype.h:324
PACKED::MbxHeader
ec_mbxheadert MbxHeader
Definition: ethercatcoe.c:26


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