IgH EtherCAT Master  1.5.2
fsm_slave.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
6 *
7 * This file is part of the IgH EtherCAT Master.
8 *
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version 2, as
11 * published by the Free Software Foundation.
12 *
13 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 * Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with the IgH EtherCAT Master; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 * ---
23 *
24 * The license mentioned above concerns the source code only. Using the
25 * EtherCAT technology and brand is only permitted in compliance with the
26 * industrial property and similar rights of Beckhoff Automation GmbH.
27 *
28 *****************************************************************************/
29
34/*****************************************************************************/
35
36#include "globals.h"
37#include "master.h"
38#include "mailbox.h"
39#include "slave_config.h"
40
41#include "fsm_slave.h"
42
43/*****************************************************************************/
44
55
56/*****************************************************************************/
57
61 ec_fsm_slave_t *fsm,
62 ec_slave_t *slave
63 )
64{
65 fsm->slave = slave;
66 INIT_LIST_HEAD(&fsm->list); // mark as unlisted
67
69 fsm->datagram = NULL;
70 fsm->sdo_request = NULL;
71 fsm->reg_request = NULL;
72 fsm->foe_request = NULL;
73 fsm->soe_request = NULL;
74
75 // Init sub-state-machines
79}
80
81/*****************************************************************************/
82
86 ec_fsm_slave_t *fsm
87 )
88{
89 // signal requests that are currently in operation
90
91 if (fsm->sdo_request) {
92 fsm->sdo_request->state = EC_INT_REQUEST_FAILURE;
93 wake_up_all(&fsm->slave->master->request_queue);
94 }
95
96 if (fsm->reg_request) {
97 fsm->reg_request->state = EC_INT_REQUEST_FAILURE;
98 wake_up_all(&fsm->slave->master->request_queue);
99 }
100
101 if (fsm->foe_request) {
102 fsm->foe_request->state = EC_INT_REQUEST_FAILURE;
103 wake_up_all(&fsm->slave->master->request_queue);
104 }
105
106 if (fsm->soe_request) {
107 fsm->soe_request->state = EC_INT_REQUEST_FAILURE;
108 wake_up_all(&fsm->slave->master->request_queue);
109 }
110
111 // clear sub-state machines
115}
116
117/*****************************************************************************/
118
124 ec_fsm_slave_t *fsm,
125 ec_datagram_t *datagram
126 )
127{
128 int datagram_used;
129
130 fsm->state(fsm, datagram);
131
132 datagram_used = fsm->state != ec_fsm_slave_state_idle &&
134
135 if (datagram_used) {
136 fsm->datagram = datagram;
137 } else {
138 fsm->datagram = NULL;
139 }
140
141 return datagram_used;
142}
143
144/*****************************************************************************/
145
149 ec_fsm_slave_t *fsm
150 )
151{
152 if (fsm->state == ec_fsm_slave_state_idle) {
153 EC_SLAVE_DBG(fsm->slave, 1, "Ready for requests.\n");
155 }
156}
157
158/*****************************************************************************/
159
165 const ec_fsm_slave_t *fsm
166 )
167{
168 return fsm->state == ec_fsm_slave_state_ready;
169}
170
171/******************************************************************************
172 * Slave state machine
173 *****************************************************************************/
174
178 ec_fsm_slave_t *fsm,
179 ec_datagram_t *datagram
180 )
181{
182 // do nothing
183}
184
185/*****************************************************************************/
186
190 ec_fsm_slave_t *fsm,
191 ec_datagram_t *datagram
192 )
193{
194 // Check for pending external SDO requests
195 if (ec_fsm_slave_action_process_sdo(fsm, datagram)) {
196 return;
197 }
198
199 // Check for pending external register requests
200 if (ec_fsm_slave_action_process_reg(fsm, datagram)) {
201 return;
202 }
203
204 // Check for pending FoE requests
205 if (ec_fsm_slave_action_process_foe(fsm, datagram)) {
206 return;
207 }
208
209 // Check for pending SoE requests
210 if (ec_fsm_slave_action_process_soe(fsm, datagram)) {
211 return;
212 }
213}
214
215/*****************************************************************************/
216
222 ec_fsm_slave_t *fsm,
223 ec_datagram_t *datagram
224 )
225{
226 ec_slave_t *slave = fsm->slave;
227 ec_sdo_request_t *request;
228
229 if (list_empty(&slave->sdo_requests)) {
230 return 0;
231 }
232
233 // take the first request to be processed
234 request = list_entry(slave->sdo_requests.next, ec_sdo_request_t, list);
235 list_del_init(&request->list); // dequeue
236
238 EC_SLAVE_WARN(slave, "Aborting SDO request,"
239 " slave has error flag set.\n");
240 request->state = EC_INT_REQUEST_FAILURE;
241 wake_up_all(&slave->master->request_queue);
243 return 1;
244 }
245
246 if (slave->current_state == EC_SLAVE_STATE_INIT) {
247 EC_SLAVE_WARN(slave, "Aborting SDO request, slave is in INIT.\n");
248 request->state = EC_INT_REQUEST_FAILURE;
249 wake_up_all(&slave->master->request_queue);
251 return 1;
252 }
253
254 fsm->sdo_request = request;
255 request->state = EC_INT_REQUEST_BUSY;
256
257 // Found pending SDO request. Execute it!
258 EC_SLAVE_DBG(slave, 1, "Processing SDO request...\n");
259
260 // Start SDO transfer
262 ec_fsm_coe_transfer(&fsm->fsm_coe, slave, request);
263 ec_fsm_coe_exec(&fsm->fsm_coe, datagram); // execute immediately
264 return 1;
265}
266
267/*****************************************************************************/
268
272 ec_fsm_slave_t *fsm,
273 ec_datagram_t *datagram
274 )
275{
276 ec_slave_t *slave = fsm->slave;
277 ec_sdo_request_t *request = fsm->sdo_request;
278
279 if (ec_fsm_coe_exec(&fsm->fsm_coe, datagram)) {
280 return;
281 }
282
283 if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
284 EC_SLAVE_ERR(slave, "Failed to process SDO request.\n");
285 request->state = EC_INT_REQUEST_FAILURE;
286 wake_up_all(&slave->master->request_queue);
287 fsm->sdo_request = NULL;
289 return;
290 }
291
292 EC_SLAVE_DBG(slave, 1, "Finished SDO request.\n");
293
294 // SDO request finished
295 request->state = EC_INT_REQUEST_SUCCESS;
296 wake_up_all(&slave->master->request_queue);
297 fsm->sdo_request = NULL;
299}
300
301/*****************************************************************************/
302
308 ec_fsm_slave_t *fsm,
309 ec_datagram_t *datagram
310 )
311{
312 ec_slave_t *slave = fsm->slave;
313 ec_reg_request_t *reg;
314
315 fsm->reg_request = NULL;
316
317 if (slave->config) {
318 // search the first internal register request to be processed
319 list_for_each_entry(reg, &slave->config->reg_requests, list) {
320 if (reg->state == EC_INT_REQUEST_QUEUED) {
321 fsm->reg_request = reg;
322 break;
323 }
324 }
325 }
326
327 if (!fsm->reg_request && !list_empty(&slave->reg_requests)) {
328 // take the first external request to be processed
329 fsm->reg_request =
330 list_entry(slave->reg_requests.next, ec_reg_request_t, list);
331 list_del_init(&fsm->reg_request->list); // dequeue
332 }
333
334 if (!fsm->reg_request) { // no register request to process
335 return 0;
336 }
337
339 EC_SLAVE_WARN(slave, "Aborting register request,"
340 " slave has error flag set.\n");
341 fsm->reg_request->state = EC_INT_REQUEST_FAILURE;
342 wake_up_all(&slave->master->request_queue);
343 fsm->reg_request = NULL;
345 return 1;
346 }
347
348 // Found pending register request. Execute it!
349 EC_SLAVE_DBG(slave, 1, "Processing register request...\n");
350
351 fsm->reg_request->state = EC_INT_REQUEST_BUSY;
352
353 // Start register access
354 if (fsm->reg_request->dir == EC_DIR_INPUT) {
355 ec_datagram_fprd(datagram, slave->station_address,
357 ec_datagram_zero(datagram);
358 } else {
359 ec_datagram_fpwr(datagram, slave->station_address,
361 memcpy(datagram->data, fsm->reg_request->data,
363 }
364 datagram->device_index = slave->device_index;
366 return 1;
367}
368
369/*****************************************************************************/
370
374 ec_fsm_slave_t *fsm,
375 ec_datagram_t *datagram
376 )
377{
378 ec_slave_t *slave = fsm->slave;
379 ec_reg_request_t *reg = fsm->reg_request;
380
381 if (!reg) {
382 // configuration was cleared in the meantime
384 fsm->reg_request = NULL;
385 return;
386 }
387
388 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
389 EC_SLAVE_ERR(slave, "Failed to receive register"
390 " request datagram: ");
392 reg->state = EC_INT_REQUEST_FAILURE;
393 wake_up_all(&slave->master->request_queue);
394 fsm->reg_request = NULL;
396 return;
397 }
398
399 if (fsm->datagram->working_counter == 1) {
400 if (reg->dir == EC_DIR_INPUT) { // read request
401 memcpy(reg->data, fsm->datagram->data, reg->transfer_size);
402 }
403
404 reg->state = EC_INT_REQUEST_SUCCESS;
405 EC_SLAVE_DBG(slave, 1, "Register request successful.\n");
406 } else {
407 reg->state = EC_INT_REQUEST_FAILURE;
409 EC_SLAVE_ERR(slave, "Register request failed"
410 " (working counter is %u).\n",
412 }
413
414 wake_up_all(&slave->master->request_queue);
415 fsm->reg_request = NULL;
417}
418
419/*****************************************************************************/
420
426 ec_fsm_slave_t *fsm,
427 ec_datagram_t *datagram
428 )
429{
430 ec_slave_t *slave = fsm->slave;
431 ec_foe_request_t *request;
432
433 if (list_empty(&slave->foe_requests)) {
434 return 0;
435 }
436
437 // take the first request to be processed
438 request = list_entry(slave->foe_requests.next, ec_foe_request_t, list);
439 list_del_init(&request->list); // dequeue
440
442 EC_SLAVE_WARN(slave, "Aborting FoE request,"
443 " slave has error flag set.\n");
444 request->state = EC_INT_REQUEST_FAILURE;
445 wake_up_all(&slave->master->request_queue);
447 return 1;
448 }
449
450 request->state = EC_INT_REQUEST_BUSY;
451 fsm->foe_request = request;
452
453 EC_SLAVE_DBG(slave, 1, "Processing FoE request.\n");
454
456 ec_fsm_foe_transfer(&fsm->fsm_foe, slave, request);
457 ec_fsm_foe_exec(&fsm->fsm_foe, datagram);
458 return 1;
459}
460
461/*****************************************************************************/
462
466 ec_fsm_slave_t *fsm,
467 ec_datagram_t *datagram
468 )
469{
470 ec_slave_t *slave = fsm->slave;
471 ec_foe_request_t *request = fsm->foe_request;
472
473 if (ec_fsm_foe_exec(&fsm->fsm_foe, datagram)) {
474 return;
475 }
476
477 if (!ec_fsm_foe_success(&fsm->fsm_foe)) {
478 EC_SLAVE_ERR(slave, "Failed to handle FoE request.\n");
479 request->state = EC_INT_REQUEST_FAILURE;
480 wake_up_all(&slave->master->request_queue);
481 fsm->foe_request = NULL;
483 return;
484 }
485
486 // finished transferring FoE
487 EC_SLAVE_DBG(slave, 1, "Successfully transferred %zu bytes of FoE"
488 " data.\n", request->data_size);
489
490 request->state = EC_INT_REQUEST_SUCCESS;
491 wake_up_all(&slave->master->request_queue);
492 fsm->foe_request = NULL;
494}
495
496/*****************************************************************************/
497
503 ec_fsm_slave_t *fsm,
504 ec_datagram_t *datagram
505 )
506{
507 ec_slave_t *slave = fsm->slave;
508 ec_soe_request_t *req;
509
510 if (list_empty(&slave->soe_requests)) {
511 return 0;
512 }
513
514 // take the first request to be processed
515 req = list_entry(slave->soe_requests.next, ec_soe_request_t, list);
516 list_del_init(&req->list); // dequeue
517
519 EC_SLAVE_WARN(slave, "Aborting SoE request,"
520 " slave has error flag set.\n");
521 req->state = EC_INT_REQUEST_FAILURE;
522 wake_up_all(&slave->master->request_queue);
524 return 1;
525 }
526
527 if (slave->current_state == EC_SLAVE_STATE_INIT) {
528 EC_SLAVE_WARN(slave, "Aborting SoE request, slave is in INIT.\n");
529 req->state = EC_INT_REQUEST_FAILURE;
530 wake_up_all(&slave->master->request_queue);
532 return 0;
533 }
534
535 fsm->soe_request = req;
536 req->state = EC_INT_REQUEST_BUSY;
537
538 // Found pending request. Execute it!
539 EC_SLAVE_DBG(slave, 1, "Processing SoE request...\n");
540
541 // Start SoE transfer
543 ec_fsm_soe_transfer(&fsm->fsm_soe, slave, req);
544 ec_fsm_soe_exec(&fsm->fsm_soe, datagram); // execute immediately
545 return 1;
546}
547
548/*****************************************************************************/
549
553 ec_fsm_slave_t *fsm,
554 ec_datagram_t *datagram
555 )
556{
557 ec_slave_t *slave = fsm->slave;
558 ec_soe_request_t *request = fsm->soe_request;
559
560 if (ec_fsm_soe_exec(&fsm->fsm_soe, datagram)) {
561 return;
562 }
563
564 if (!ec_fsm_soe_success(&fsm->fsm_soe)) {
565 EC_SLAVE_ERR(slave, "Failed to process SoE request.\n");
566 request->state = EC_INT_REQUEST_FAILURE;
567 wake_up_all(&slave->master->request_queue);
568 fsm->soe_request = NULL;
570 return;
571 }
572
573 EC_SLAVE_DBG(slave, 1, "Finished SoE request.\n");
574
575 // SoE request finished
576 request->state = EC_INT_REQUEST_SUCCESS;
577 wake_up_all(&slave->master->request_queue);
578 fsm->soe_request = NULL;
580}
581
582/*****************************************************************************/
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:178
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:565
int ec_datagram_fpwr(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPWR datagram.
Definition: datagram.c:298
int ec_datagram_fprd(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPRD datagram.
Definition: datagram.c:273
@ EC_DATAGRAM_RECEIVED
Received (dequeued).
Definition: datagram.h:78
int ec_fsm_coe_success(const ec_fsm_coe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_coe.c:262
void ec_fsm_coe_transfer(ec_fsm_coe_t *fsm, ec_slave_t *slave, ec_sdo_request_t *request)
Starts to transfer an SDO to/from a slave.
Definition: fsm_coe.c:205
void ec_fsm_coe_init(ec_fsm_coe_t *fsm)
Constructor.
Definition: fsm_coe.c:170
int ec_fsm_coe_exec(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_coe.c:228
void ec_fsm_coe_clear(ec_fsm_coe_t *fsm)
Destructor.
Definition: fsm_coe.c:182
int ec_fsm_foe_exec(ec_fsm_foe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_foe.c:125
void ec_fsm_foe_clear(ec_fsm_foe_t *fsm)
Destructor.
Definition: fsm_foe.c:115
int ec_fsm_foe_success(const ec_fsm_foe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_foe.c:159
void ec_fsm_foe_init(ec_fsm_foe_t *fsm)
Constructor.
Definition: fsm_foe.c:103
void ec_fsm_foe_transfer(ec_fsm_foe_t *fsm, ec_slave_t *slave, ec_foe_request_t *request)
Prepares an FoE transfer.
Definition: fsm_foe.c:168
void ec_fsm_slave_state_reg_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: Register request.
Definition: fsm_slave.c:373
int ec_fsm_slave_action_process_reg(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending register requests and process one.
Definition: fsm_slave.c:307
void ec_fsm_slave_set_ready(ec_fsm_slave_t *fsm)
Sets the current state of the state machine to READY.
Definition: fsm_slave.c:148
void ec_fsm_slave_state_idle(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: IDLE.
Definition: fsm_slave.c:177
int ec_fsm_slave_exec(ec_fsm_slave_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_slave.c:123
int ec_fsm_slave_action_process_sdo(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending SDO requests and process one.
Definition: fsm_slave.c:221
void ec_fsm_slave_state_sdo_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: SDO_REQUEST.
Definition: fsm_slave.c:271
int ec_fsm_slave_action_process_foe(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending FoE requests and process one.
Definition: fsm_slave.c:425
void ec_fsm_slave_clear(ec_fsm_slave_t *fsm)
Destructor.
Definition: fsm_slave.c:85
void ec_fsm_slave_state_foe_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: FOE REQUEST.
Definition: fsm_slave.c:465
void ec_fsm_slave_init(ec_fsm_slave_t *fsm, ec_slave_t *slave)
Constructor.
Definition: fsm_slave.c:60
void ec_fsm_slave_state_soe_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: SOE_REQUEST.
Definition: fsm_slave.c:552
void ec_fsm_slave_state_ready(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: READY.
Definition: fsm_slave.c:189
int ec_fsm_slave_action_process_soe(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending SoE requests and process one.
Definition: fsm_slave.c:502
int ec_fsm_slave_is_ready(const ec_fsm_slave_t *fsm)
Returns, if the FSM is currently not busy and ready to execute.
Definition: fsm_slave.c:164
EtherCAT slave request state machine.
void ec_fsm_soe_init(ec_fsm_soe_t *fsm)
Constructor.
Definition: fsm_soe.c:105
int ec_fsm_soe_exec(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_soe.c:150
void ec_fsm_soe_transfer(ec_fsm_soe_t *fsm, ec_slave_t *slave, ec_soe_request_t *request)
Starts to transfer an IDN to/from a slave.
Definition: fsm_soe.c:128
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition: fsm_soe.c:118
int ec_fsm_soe_success(const ec_fsm_soe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_soe.c:185
Global definitions and macros.
@ EC_SLAVE_STATE_INIT
INIT state (no mailbox communication, no IO)
Definition: globals.h:118
@ EC_SLAVE_STATE_ACK_ERR
Acknowledge/Error bit (no actual state)
Definition: globals.h:128
@ EC_DIR_INPUT
Values read by the master.
Definition: ecrt.h:433
Mailbox functionality.
EtherCAT master structure.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:106
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:76
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:90
EtherCAT slave configuration structure.
EtherCAT datagram.
Definition: datagram.h:87
uint16_t working_counter
Working counter.
Definition: datagram.h:99
ec_datagram_state_t state
State.
Definition: datagram.h:100
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
Definition: datagram.h:90
uint8_t * data
Datagram payload.
Definition: datagram.h:94
FoE request.
Definition: foe_request.h:50
struct list_head list
List item.
Definition: foe_request.h:51
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:63
Finite state machine of an EtherCAT slave.
Definition: fsm_slave.h:54
ec_datagram_t * datagram
Previous state datagram.
Definition: fsm_slave.h:59
void(* state)(ec_fsm_slave_t *, ec_datagram_t *)
State function.
Definition: fsm_slave.h:58
ec_reg_request_t * reg_request
Register request to process.
Definition: fsm_slave.h:61
ec_foe_request_t * foe_request
FoE request to process.
Definition: fsm_slave.h:62
ec_sdo_request_t * sdo_request
SDO request to process.
Definition: fsm_slave.h:60
ec_fsm_soe_t fsm_soe
SoE state machine.
Definition: fsm_slave.h:68
ec_soe_request_t * soe_request
SoE request to process.
Definition: fsm_slave.h:64
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_slave.h:55
ec_fsm_foe_t fsm_foe
FoE state machine.
Definition: fsm_slave.h:67
ec_fsm_coe_t fsm_coe
CoE state machine.
Definition: fsm_slave.h:66
struct list_head list
Used for execution list.
Definition: fsm_slave.h:56
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:311
Register request.
Definition: reg_request.h:48
uint8_t * data
Pointer to data memory.
Definition: reg_request.h:51
struct list_head list
List item.
Definition: reg_request.h:49
uint16_t address
Register address.
Definition: reg_request.h:54
ec_direction_t dir
Direction.
Definition: reg_request.h:52
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:56
size_t transfer_size
Size of the data to transfer.
Definition: reg_request.h:55
CANopen SDO request.
Definition: sdo_request.h:48
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:63
struct list_head list
List item.
Definition: sdo_request.h:49
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:147
EtherCAT slave.
Definition: slave.h:177
ec_slave_config_t * config
Current configuration.
Definition: slave.h:190
struct list_head foe_requests
FoE write requests.
Definition: slave.h:231
struct list_head reg_requests
Register access requests.
Definition: slave.h:230
ec_slave_state_t current_state
Current application state.
Definition: slave.h:192
struct list_head sdo_requests
SDO access requests.
Definition: slave.h:229
struct list_head soe_requests
SoE write requests.
Definition: slave.h:232
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:179
ec_master_t * master
Master owning the slave.
Definition: slave.h:178
uint16_t station_address
Configured station address.
Definition: slave.h:184
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
struct list_head list
List item.
Definition: soe_request.h:49
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:58