# HG changeset patch # User Florian Pose # Date 1204624656 0 # Node ID 69122084d06670def01223f28d4f0968ec9d7c7a # Parent 7874c884dc2bd0a4b1b18a58643b91b8b6952fe7 Basic reading realtime Sdo access working. diff -r 7874c884dc2b -r 69122084d066 examples/mini/mini.c --- a/examples/mini/mini.c Tue Mar 04 09:20:14 2008 +0000 +++ b/examples/mini/mini.c Tue Mar 04 09:57:36 2008 +0000 @@ -41,10 +41,13 @@ /*****************************************************************************/ -// module parameters +// Module parameters #define FREQUENCY 100 + +// Optional features #define CONFIGURE_MAPPING #define EXTERNAL_MEMORY +#define SDO_ACCESS #define PFX "ec_mini: " @@ -112,6 +115,13 @@ /*****************************************************************************/ +#ifdef SDO_ACCESS +static ec_sdo_request_t *sdo; +static int not_first_time = 0; +#endif + +/*****************************************************************************/ + void check_domain1_state(void) { ec_domain_state_t ds; @@ -155,6 +165,32 @@ /*****************************************************************************/ +#ifdef SDO_ACCESS +void read_sdo(void) +{ + switch (ecrt_sdo_request_state(sdo)) { + case EC_REQUEST_COMPLETE: + if (not_first_time) { + printk(KERN_INFO PFX "Sdo value: 0x%04X\n", + EC_READ_U16(ecrt_sdo_request_data(sdo))); + } else { + not_first_time = 1; + } + ecrt_sdo_request_read(sdo); + break; + case EC_REQUEST_FAILURE: + printk(KERN_INFO PFX "Failed to read Sdo!\n"); + ecrt_sdo_request_read(sdo); + break; + default: + printk(KERN_INFO PFX "Still busy...\n"); + break; + } +} +#endif + +/*****************************************************************************/ + void cyclic_task(unsigned long data) { // receive process data @@ -168,7 +204,7 @@ if (counter) { counter--; - } else { // do this at FREQUENCY + } else { // do this at 1 Hz counter = FREQUENCY; // calculate new process data @@ -176,6 +212,11 @@ // check for master state (optional) check_master_state(); + +#ifdef SDO_ACCESS + // read process data Sdo + read_sdo(); +#endif } // write process data @@ -256,6 +297,19 @@ } #endif +#ifdef SDO_ACCESS + printk(KERN_INFO PFX "Creating Sdo requests...\n"); + if (!(sc = ecrt_master_slave_config(master, 0, 1, Beckhoff_EL3162))) { + printk(KERN_ERR PFX "Failed to get slave configuration.\n"); + goto out_release_master; + } + + if (!(sdo = ecrt_slave_config_create_sdo_request(sc, 0x3102, 2, 2))) { + printk(KERN_ERR PFX "Failed to create Sdo request.\n"); + goto out_release_master; + } +#endif + printk(KERN_INFO PFX "Registering Pdo entries...\n"); if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) { printk(KERN_ERR PFX "Pdo entry registration failed!\n"); diff -r 7874c884dc2b -r 69122084d066 include/ecrt.h --- a/include/ecrt.h Tue Mar 04 09:20:14 2008 +0000 +++ b/include/ecrt.h Tue Mar 04 09:57:36 2008 +0000 @@ -131,6 +131,9 @@ struct ec_domain; typedef struct ec_domain ec_domain_t; /**< \see ec_domain */ +struct ec_sdo_request; +typedef struct ec_sdo_request ec_sdo_request_t; /**< \see ec_sdo_request. */ + /*****************************************************************************/ /** Bus state. @@ -248,6 +251,28 @@ offset in the process data. */ } ec_pdo_entry_reg_t; +/*****************************************************************************/ + +/** Generic request state. + */ +typedef enum { + EC_REQUEST_QUEUED, + EC_REQUEST_IN_PROGRESS, + EC_REQUEST_COMPLETE, + EC_REQUEST_FAILURE +} ec_request_state_t; + +/*****************************************************************************/ + +/** Sdo request error. + * + * This is used as return type of ecrt_sdo_request_error(). + */ +typedef enum { + EC_SDO_REQUEST_SUCCESS, /**< There is no error. */ + EC_SDO_REQUEST_TIMEOUT, /**< The request timed out. */ +} ec_sdo_request_error_t; + /****************************************************************************** * Global functions *****************************************************************************/ @@ -513,6 +538,18 @@ uint32_t value /**< Value to set. */ ); +/** Create an Sdo request to exchange Sdos during realtime operation. + * + * The created Sdo request object is freed automatically when the master is + * released. + */ +ec_sdo_request_t *ecrt_slave_config_create_sdo_request( + ec_slave_config_t *sc, /**< Slave configuration. */ + uint16_t index, /**< Sdo index. */ + uint8_t subindex, /**< Sdo subindex. */ + size_t size /**< Data size to reserve. */ + ); + /** Outputs the state of the slave configuration. * * Stores the state information in the given \a state structure. @@ -599,6 +636,62 @@ information. */ ); +/***************************************************************************** + * Sdo request methods. + ****************************************************************************/ + +/** Set the timeout for an Sdo request. + * + * If the request cannot be processed in the specified time, if will be marked + * as failed. + */ +void ecrt_sdo_request_timeout( + ec_sdo_request_t *req, /**< Sdo request. */ + uint32_t timeout /**< Timeout in milliseconds. */ + ); + +/** Access to the Sdo request's data. + * + * \attention The return value is invalid during (ecrt_sdo_request_state() != + * EC_REQUEST_COMPLETE) a read operation, because the internal Sdo data + * memory could be re-allocated. + * + * \return Pointer to the internal Sdo data memory. + */ +uint8_t *ecrt_sdo_request_data( + ec_sdo_request_t *req /**< Sdo request. */ + ); + +/** Get the current state of the Sdo request. + * + * \return Request state. + */ +ec_request_state_t ecrt_sdo_request_state( + const ec_sdo_request_t *req /**< Sdo request. */ + ); + +/** Get the error code of the Sdo request. + */ +ec_sdo_request_error_t ecrt_sdo_request_error( + const ec_sdo_request_t *req /**< Sdo request. */ + ); + +/** Schedule an Sdo write operation. + */ +void ecrt_sdo_request_write( + ec_sdo_request_t *req /**< Sdo request. */ + ); + +/** Schedule an Sdo read operation . + * + * \attention After calling this function, the return value of + * ecrt_sdo_request_data() will be invalid until ecrt_sdo_request_state() + * is EC_REQUEST_COMPLETE. + */ +void ecrt_sdo_request_read( + ec_sdo_request_t *req /**< Sdo request. */ + ); + /****************************************************************************** * Bitwise read/write macros *****************************************************************************/ diff -r 7874c884dc2b -r 69122084d066 master/fsm_coe_map.c --- a/master/fsm_coe_map.c Tue Mar 04 09:20:14 2008 +0000 +++ b/master/fsm_coe_map.c Tue Mar 04 09:57:36 2008 +0000 @@ -182,7 +182,7 @@ ec_pdo_mapping_clear_pdos(&fsm->mapping); ec_sdo_request_address(&fsm->request, fsm->sync_sdo_index, 0); - ec_sdo_request_read(&fsm->request); + ecrt_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo_count; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately @@ -238,7 +238,7 @@ if (fsm->sync_subindex <= fsm->sync_subindices) { ec_sdo_request_address(&fsm->request, fsm->sync_sdo_index, fsm->sync_subindex); - ec_sdo_request_read(&fsm->request); + ecrt_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately @@ -295,7 +295,7 @@ list_add_tail(&fsm->pdo->list, &fsm->mapping.pdos); ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); - ec_sdo_request_read(&fsm->request); + ecrt_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo_entry_count; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately @@ -342,7 +342,7 @@ { if (fsm->pdo_subindex <= fsm->pdo_subindices) { ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->pdo_subindex); - ec_sdo_request_read(&fsm->request); + ecrt_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo_entry; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately diff -r 7874c884dc2b -r 69122084d066 master/fsm_master.c --- a/master/fsm_master.c Tue Mar 04 09:20:14 2008 +0000 +++ b/master/fsm_master.c Tue Mar 04 09:57:36 2008 +0000 @@ -41,6 +41,7 @@ #include "globals.h" #include "master.h" #include "mailbox.h" +#include "slave_config.h" #ifdef EC_EOE #include "ethernet.h" #endif @@ -376,9 +377,39 @@ { ec_master_t *master = fsm->master; ec_master_sdo_request_t *request; + ec_sdo_request_t *req; ec_slave_t *slave; - // search the first request to be processed + // search for internal requests to be processed + list_for_each_entry(slave, &master->slaves, list) { + if (!slave->config) + continue; + list_for_each_entry(req, &slave->config->sdo_requests, list) { + if (req->state == EC_REQUEST_QUEUED) { + req->state = EC_REQUEST_IN_PROGRESS; + + if (slave->current_state == EC_SLAVE_STATE_INIT || + slave->error_flag) { + req->state = EC_REQUEST_FAILURE; + continue; + } + + if (master->debug_level) + EC_DBG("Processing Sdo request for slave %u...\n", + slave->ring_position); + + fsm->idle = 0; + fsm->sdo_request = req; + fsm->slave = slave; + fsm->state = ec_fsm_master_state_sdo_request; + ec_fsm_coe_upload(&fsm->fsm_coe, slave, req); + ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately + return 1; + } + } + } + + // search the first external request to be processed while (1) { down(&master->sdo_sem); if (list_empty(&master->slave_sdo_requests)) { @@ -410,7 +441,8 @@ // Start uploading Sdo fsm->idle = 0; - fsm->sdo_request = request; + fsm->sdo_request = &request->req; + fsm->slave = slave; fsm->state = ec_fsm_master_state_sdo_request; ec_fsm_coe_upload(&fsm->fsm_coe, slave, &request->req); ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately @@ -499,7 +531,7 @@ return; } - // Check for a pending Sdo request + // Check for pending Sdo requests if (ec_fsm_master_action_process_sdo(fsm)) return; @@ -1026,25 +1058,25 @@ void ec_fsm_master_state_sdo_request(ec_fsm_master_t *fsm /**< master state machine */) { ec_master_t *master = fsm->master; - ec_master_sdo_request_t *request = fsm->sdo_request; + ec_sdo_request_t *request = fsm->sdo_request; if (ec_fsm_coe_exec(&fsm->fsm_coe)) return; if (!ec_fsm_coe_success(&fsm->fsm_coe)) { - EC_DBG("Failed to process Sdo request for slave %i.\n", + EC_DBG("Failed to process Sdo request for slave %u.\n", fsm->slave->ring_position); - request->req.state = EC_REQUEST_FAILURE; + request->state = EC_REQUEST_FAILURE; wake_up(&master->sdo_queue); fsm->state = ec_fsm_master_state_error; return; } // Sdo request finished - request->req.state = EC_REQUEST_COMPLETE; + request->state = EC_REQUEST_COMPLETE; wake_up(&master->sdo_queue); if (master->debug_level) - EC_DBG("Finished Sdo request for slave %i.\n", + EC_DBG("Finished Sdo request for slave %u.\n", fsm->slave->ring_position); // check for another Sdo request diff -r 7874c884dc2b -r 69122084d066 master/fsm_master.h --- a/master/fsm_master.h Tue Mar 04 09:20:14 2008 +0000 +++ b/master/fsm_master.h Tue Mar 04 09:57:36 2008 +0000 @@ -97,7 +97,7 @@ ec_slave_t *slave; /**< current slave */ ec_eeprom_write_request_t *eeprom_request; /**< EEPROM write request */ off_t eeprom_index; /**< index to EEPROM write request data */ - ec_master_sdo_request_t *sdo_request; /**< Sdo request to process. */ + ec_sdo_request_t *sdo_request; /**< Sdo request to process. */ ec_fsm_slave_config_t fsm_slave_config; /**< slave state machine */ ec_fsm_slave_scan_t fsm_slave_scan; /**< slave state machine */ diff -r 7874c884dc2b -r 69122084d066 master/fsm_pdo_config.c --- a/master/fsm_pdo_config.c Tue Mar 04 09:20:14 2008 +0000 +++ b/master/fsm_pdo_config.c Tue Mar 04 09:57:36 2008 +0000 @@ -214,7 +214,7 @@ EC_WRITE_U8(&fsm->request.data, 0); fsm->request.data_size = 1; ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); - ec_sdo_request_write(&fsm->request); + ecrt_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Setting entry count to zero for Pdo 0x%04X.\n", fsm->pdo->index); @@ -254,7 +254,7 @@ EC_WRITE_U32(&fsm->request.data, value); fsm->request.data_size = 4; ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->entry_count); - ec_sdo_request_write(&fsm->request); + ecrt_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Configuring Pdo entry %08X at position %u.\n", value, fsm->entry_count); @@ -320,7 +320,7 @@ EC_WRITE_U8(&fsm->request.data, fsm->entry_count); fsm->request.data_size = 1; ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); - ec_sdo_request_write(&fsm->request); + ecrt_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Setting number of Pdo entries to %u.\n", fsm->entry_count); diff -r 7874c884dc2b -r 69122084d066 master/fsm_pdo_mapping.c --- a/master/fsm_pdo_mapping.c Tue Mar 04 09:20:14 2008 +0000 +++ b/master/fsm_pdo_mapping.c Tue Mar 04 09:57:36 2008 +0000 @@ -205,7 +205,7 @@ EC_WRITE_U8(&fsm->request.data, 0); // zero Pdos mapped fsm->request.data_size = 1; ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0); - ec_sdo_request_write(&fsm->request); + ecrt_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Setting Pdo count to zero for SM%u.\n", fsm->sync->index); @@ -248,7 +248,7 @@ fsm->request.data_size = 2; ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, fsm->pdo_count); - ec_sdo_request_write(&fsm->request); + ecrt_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Mapping Pdo 0x%04X at position %u.\n", fsm->pdo->index, fsm->pdo_count); @@ -314,7 +314,7 @@ EC_WRITE_U8(&fsm->request.data, fsm->pdo_count); fsm->request.data_size = 1; ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0); - ec_sdo_request_write(&fsm->request); + ecrt_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Setting number of mapped Pdos to %u.\n", fsm->pdo_count); diff -r 7874c884dc2b -r 69122084d066 master/fsm_slave_config.c --- a/master/fsm_slave_config.c Tue Mar 04 09:20:14 2008 +0000 +++ b/master/fsm_slave_config.c Tue Mar 04 09:57:36 2008 +0000 @@ -450,7 +450,7 @@ fsm->state = ec_fsm_slave_config_state_sdo_conf; fsm->request = list_entry(fsm->slave->config->sdo_configs.next, ec_sdo_request_t, list); - ec_sdo_request_write(fsm->request); + ecrt_sdo_request_write(fsm->request); ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->request); ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately } @@ -479,7 +479,7 @@ if (fsm->request->list.next != &fsm->slave->config->sdo_configs) { fsm->request = list_entry(fsm->request->list.next, ec_sdo_request_t, list); - ec_sdo_request_write(fsm->request); + ecrt_sdo_request_write(fsm->request); ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->request); ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately return; diff -r 7874c884dc2b -r 69122084d066 master/globals.h --- a/master/globals.h Tue Mar 04 09:20:14 2008 +0000 +++ b/master/globals.h Tue Mar 04 09:57:36 2008 +0000 @@ -191,17 +191,6 @@ /*****************************************************************************/ -/** Master request state. - */ -typedef enum { - EC_REQUEST_QUEUED, - EC_REQUEST_IN_PROGRESS, - EC_REQUEST_COMPLETE, - EC_REQUEST_FAILURE -} ec_request_state_t; - -/*****************************************************************************/ - /** Origin type. */ typedef enum { diff -r 7874c884dc2b -r 69122084d066 master/sdo_entry.c --- a/master/sdo_entry.c Tue Mar 04 09:20:14 2008 +0000 +++ b/master/sdo_entry.c Tue Mar 04 09:57:36 2008 +0000 @@ -269,7 +269,7 @@ request.slave = entry->sdo->slave; ec_sdo_request_init(&request.req); ec_sdo_request_address(&request.req, entry->sdo->index, entry->subindex); - ec_sdo_request_read(&request.req); + ecrt_sdo_request_read(&request.req); // schedule request. down(&master->sdo_sem); diff -r 7874c884dc2b -r 69122084d066 master/sdo_request.c --- a/master/sdo_request.c Tue Mar 04 09:20:14 2008 +0000 +++ b/master/sdo_request.c Tue Mar 04 09:57:36 2008 +0000 @@ -148,26 +148,54 @@ return 0; } -/*****************************************************************************/ - -/** Start an Sdo read operation (Sdo upload). - */ -void ec_sdo_request_read( - ec_sdo_request_t *req /**< Sdo request. */ - ) +/***************************************************************************** + * Realtime interface. + ****************************************************************************/ + +void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout) +{ +} + +/*****************************************************************************/ + +uint8_t *ecrt_sdo_request_data(ec_sdo_request_t *req) +{ + return req->data; +} + +/*****************************************************************************/ + +ec_request_state_t ecrt_sdo_request_state(const ec_sdo_request_t *req) +{ + return req->state; +} + +/*****************************************************************************/ + +ec_sdo_request_error_t ecrt_sdo_request_error(const ec_sdo_request_t *req) +{ + return EC_SDO_REQUEST_SUCCESS; // FIXME +} + +/*****************************************************************************/ + +void ecrt_sdo_request_read(ec_sdo_request_t *req) { req->state = EC_REQUEST_QUEUED; } /*****************************************************************************/ -/** Start an Sdo write operation (Sdo download). - */ -void ec_sdo_request_write( - ec_sdo_request_t *req /**< Sdo request. */ - ) +void ecrt_sdo_request_write(ec_sdo_request_t *req) { req->state = EC_REQUEST_QUEUED; } /*****************************************************************************/ + +EXPORT_SYMBOL(ecrt_sdo_request_timeout); +EXPORT_SYMBOL(ecrt_sdo_request_data); +EXPORT_SYMBOL(ecrt_sdo_request_state); +EXPORT_SYMBOL(ecrt_sdo_request_error); +EXPORT_SYMBOL(ecrt_sdo_request_read); +EXPORT_SYMBOL(ecrt_sdo_request_write); diff -r 7874c884dc2b -r 69122084d066 master/sdo_request.h --- a/master/sdo_request.h Tue Mar 04 09:20:14 2008 +0000 +++ b/master/sdo_request.h Tue Mar 04 09:57:36 2008 +0000 @@ -43,13 +43,15 @@ #include +#include "../include/ecrt.h" + #include "globals.h" /*****************************************************************************/ /** CANopen Sdo request. */ -typedef struct { +struct ec_sdo_request { struct list_head list; /**< List item. */ uint16_t index; /**< Sdo index. */ uint8_t subindex; /**< Sdo subindex. */ @@ -57,7 +59,7 @@ size_t mem_size; /**< Size of Sdo data memory. */ size_t data_size; /**< Size of Sdo data. */ ec_request_state_t state; /**< Sdo request state. */ -} ec_sdo_request_t; +}; /*****************************************************************************/ @@ -68,9 +70,6 @@ int ec_sdo_request_alloc(ec_sdo_request_t *, size_t); int ec_sdo_request_copy_data(ec_sdo_request_t *, const uint8_t *, size_t); -void ec_sdo_request_read(ec_sdo_request_t *); -void ec_sdo_request_write(ec_sdo_request_t *); - /*****************************************************************************/ #endif diff -r 7874c884dc2b -r 69122084d066 master/slave_config.c --- a/master/slave_config.c Tue Mar 04 09:20:14 2008 +0000 +++ b/master/slave_config.c Tue Mar 04 09:57:36 2008 +0000 @@ -105,6 +105,7 @@ ec_pdo_mapping_init(&sc->mapping[dir]); INIT_LIST_HEAD(&sc->sdo_configs); + INIT_LIST_HEAD(&sc->sdo_requests); sc->used_fmmus = 0; @@ -174,6 +175,13 @@ kfree(req); } + // free all Sdo requests + list_for_each_entry_safe(req, next_req, &sc->sdo_requests, list) { + list_del(&req->list); + ec_sdo_request_clear(req); + kfree(req); + } + kfree(sc); } @@ -276,6 +284,16 @@ buf += sprintf(buf, "\n"); } + // type-cast to avoid warnings on some compilers + if (!list_empty((struct list_head *) &sc->sdo_requests)) { + buf += sprintf(buf, "\nSdo requests:\n"); + + list_for_each_entry(req, &sc->sdo_requests, list) { + buf += sprintf(buf, " 0x%04X:%u\n", req->index, req->subindex); + } + buf += sprintf(buf, "\n"); + } + return buf - buffer; } @@ -672,6 +690,32 @@ /*****************************************************************************/ +ec_sdo_request_t *ecrt_slave_config_create_sdo_request(ec_slave_config_t *sc, + uint16_t index, uint8_t subindex, size_t size) +{ + ec_sdo_request_t *req; + + if (!(req = (ec_sdo_request_t *) + kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) { + EC_ERR("Failed to allocate Sdo request memory!\n"); + return NULL; + } + + ec_sdo_request_init(req); + ec_sdo_request_address(req, index, subindex); + + if (ec_sdo_request_alloc(req, size)) { + ec_sdo_request_clear(req); + kfree(req); + return NULL; + } + + list_add_tail(&req->list, &sc->sdo_requests); + return req; +} + +/*****************************************************************************/ + /** \cond */ EXPORT_SYMBOL(ecrt_slave_config_pdo); @@ -681,6 +725,7 @@ EXPORT_SYMBOL(ecrt_slave_config_sdo8); EXPORT_SYMBOL(ecrt_slave_config_sdo16); EXPORT_SYMBOL(ecrt_slave_config_sdo32); +EXPORT_SYMBOL(ecrt_slave_config_create_sdo_request); /** \endcond */ diff -r 7874c884dc2b -r 69122084d066 master/slave_config.h --- a/master/slave_config.h Tue Mar 04 09:20:14 2008 +0000 +++ b/master/slave_config.h Tue Mar 04 09:57:36 2008 +0000 @@ -71,7 +71,8 @@ ec_pdo_mapping_t mapping[2]; /**< Output and input Pdo mapping. */ - struct list_head sdo_configs; /**< Sdo configurations. */ + struct list_head sdo_configs; /**< List of Sdo configurations. */ + struct list_head sdo_requests; /**< List of Sdo requests. */ ec_fmmu_config_t fmmu_configs[EC_MAX_FMMUS]; /**< FMMU configurations. */ uint8_t used_fmmus; /**< Number of FMMUs used. */