# HG changeset patch # User Florian Pose # Date 1161267804 0 # Node ID cf724fc82a00269433c6e7a4f804217046343804 # Parent 7a43437bc48bed409febdcda502712d298fb4021 Moved SDO dictionary fetching to master FSMs; added SDO parent kobj. diff -r 7a43437bc48b -r cf724fc82a00 master/canopen.c --- a/master/canopen.c Thu Oct 19 14:05:56 2006 +0000 +++ b/master/canopen.c Thu Oct 19 14:23:24 2006 +0000 @@ -111,8 +111,8 @@ memset(&sdo->kobj, 0x00, sizeof(struct kobject)); kobject_init(&sdo->kobj); sdo->kobj.ktype = &ktype_ec_sdo; - sdo->kobj.parent = &slave->kobj; - if (kobject_set_name(&sdo->kobj, "sdo%4X", sdo->index)) { + sdo->kobj.parent = &slave->sdo_kobj; + if (kobject_set_name(&sdo->kobj, "%4X", sdo->index)) { EC_ERR("Failed to set kobj name.\n"); return -1; } @@ -195,7 +195,7 @@ kobject_init(&entry->kobj); entry->kobj.ktype = &ktype_ec_sdo_entry; entry->kobj.parent = &sdo->kobj; - if (kobject_set_name(&entry->kobj, "entry%02X", entry->subindex)) { + if (kobject_set_name(&entry->kobj, "%i", entry->subindex)) { EC_ERR("Failed to set kobj name.\n"); return -1; } diff -r 7a43437bc48b -r cf724fc82a00 master/fsm.c --- a/master/fsm.c Thu Oct 19 14:05:56 2006 +0000 +++ b/master/fsm.c Thu Oct 19 14:23:24 2006 +0000 @@ -54,6 +54,7 @@ void ec_fsm_master_configure_slave(ec_fsm_t *); void ec_fsm_master_scan_slaves(ec_fsm_t *); void ec_fsm_master_write_eeprom(ec_fsm_t *); +void ec_fsm_master_sdodict(ec_fsm_t *); void ec_fsm_startup_start(ec_fsm_t *); void ec_fsm_startup_broadcast(ec_fsm_t *); @@ -73,9 +74,8 @@ void ec_fsm_slaveconf_init(ec_fsm_t *); void ec_fsm_slaveconf_sync(ec_fsm_t *); void ec_fsm_slaveconf_preop(ec_fsm_t *); -void ec_fsm_slaveconf_sdodict(ec_fsm_t *); +void ec_fsm_slaveconf_fmmu(ec_fsm_t *); void ec_fsm_slaveconf_sdoconf(ec_fsm_t *); -void ec_fsm_slaveconf_fmmu(ec_fsm_t *); void ec_fsm_slaveconf_saveop(ec_fsm_t *); void ec_fsm_slaveconf_op(ec_fsm_t *); @@ -593,6 +593,39 @@ // Check, if EoE processing has to be started ec_master_eoe_start(master); + // check, if slaves have an SDO dictionary to read out. + list_for_each_entry(slave, &master->slaves, list) { + if (!(slave->sii_mailbox_protocols & EC_MBOX_COE) + || slave->sdo_dictionary_fetched + || slave->current_state == EC_SLAVE_STATE_INIT + || jiffies - slave->jiffies_preop < 5 * HZ + || !slave->online + || slave->error_flag) continue; + + if (master->debug_level) { + EC_DBG("Fetching SDO dictionary of slave %i.\n", + slave->ring_position); + } + + if (kobject_add(&slave->sdo_kobj)) { + EC_ERR("Failed to add SDO kobj of slave %i.\n", + slave->ring_position); + slave->error_flag = 1; + fsm->master_state = ec_fsm_master_start; + fsm->master_state(fsm); // execute immediately + return; + } + + slave->sdo_dictionary_fetched = 1; + + // start fetching SDO dictionary + fsm->slave = slave; + fsm->master_state = ec_fsm_master_sdodict; + fsm->coe_state = ec_fsm_coe_dict_start; + fsm->coe_state(fsm); // execute immediately + return; + } + if (master->mode == EC_MASTER_MODE_IDLE) { // nothing to configure. check for pending EEPROM write operations. list_for_each_entry(slave, &master->slaves, list) { @@ -982,7 +1015,39 @@ // restart master state machine. fsm->master_state = ec_fsm_master_start; fsm->master_state(fsm); // execute immediately - return; +} + +/*****************************************************************************/ + +/** + Master state: SDODICT. +*/ + +void ec_fsm_master_sdodict(ec_fsm_t *fsm /**< finite state machine */) +{ + ec_slave_t *slave = fsm->slave; + ec_master_t *master = fsm->master; + + fsm->coe_state(fsm); // execute CoE state machine + + if (fsm->coe_state == ec_fsm_error) { + fsm->slave->error_flag = 1; + fsm->slave_state = ec_fsm_error; + return; + } + + if (fsm->coe_state != ec_fsm_end) return; + + // SDO dictionary fetching finished + + if (master->debug_level) { + EC_DBG("Finished fetching SDO dictionary of slave %i.\n", + slave->ring_position); + } + + // restart master state machine. + fsm->master_state = ec_fsm_master_start; + fsm->master_state(fsm); // execute immediately } /****************************************************************************** @@ -1434,26 +1499,23 @@ if (fsm->change_state != ec_fsm_end) return; // slave is now in PREOP + slave->jiffies_preop = fsm->datagram.jiffies_received; if (master->debug_level) { EC_DBG("Slave %i is now in PREOP.\n", slave->ring_position); } - if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) { - // slave does not support CoE. skip dictionary fetching - // and SDO configuration - - if (slave->current_state == slave->requested_state) { - fsm->slave_state = ec_fsm_end; // successful - if (master->debug_level) { - EC_DBG("Finished configuration of slave %i.\n", - slave->ring_position); - } - return; - } - - if (!slave->base_fmmu_count) { - // slave has no FMMUs. skip configuration and go to SAVEOP + if (slave->current_state == slave->requested_state) { + fsm->slave_state = ec_fsm_end; // successful + if (master->debug_level) { + EC_DBG("Finished configuration of slave %i.\n", + slave->ring_position); + } + return; + } + + if (!slave->base_fmmu_count) { // skip FMMU configuration + if (list_empty(&slave->sdo_confs)) { // skip SDO configuration fsm->slave_state = ec_fsm_slaveconf_saveop; fsm->change_new = EC_SLAVE_STATE_SAVEOP; fsm->change_state = ec_fsm_change_start; @@ -1461,63 +1523,6 @@ return; } - // configure FMMUs - ec_datagram_npwr(datagram, slave->station_address, - 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count); - memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); - for (j = 0; j < slave->fmmu_count; j++) { - ec_fmmu_config(&slave->fmmus[j], slave, - datagram->data + EC_FMMU_SIZE * j); - } - - ec_master_queue_datagram(master, datagram); - fsm->slave_state = ec_fsm_slaveconf_fmmu; - return; - } - - if (!list_empty(&slave->sdo_dictionary)) { - // SDO dictionary already fetched - - if (master->debug_level) { - EC_DBG("SDO dictionary already present for slave %i.\n", - slave->ring_position); - } - - if (slave->current_state == slave->requested_state) { - fsm->slave_state = ec_fsm_end; // successful - if (master->debug_level) { - EC_DBG("Finished configuration of slave %i.\n", - slave->ring_position); - } - return; - } - - if (list_empty(&slave->sdo_confs)) { - // skip SDO configuration - - if (!slave->base_fmmu_count) { - // slave has no FMMUs. skip configuration and go to SAVEOP - fsm->slave_state = ec_fsm_slaveconf_saveop; - fsm->change_new = EC_SLAVE_STATE_SAVEOP; - fsm->change_state = ec_fsm_change_start; - fsm->change_state(fsm); // execute immediately - return; - } - - // configure FMMUs - ec_datagram_npwr(datagram, slave->station_address, - 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count); - memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); - for (j = 0; j < slave->fmmu_count; j++) { - ec_fmmu_config(&slave->fmmus[j], slave, - datagram->data + EC_FMMU_SIZE * j); - } - - ec_master_queue_datagram(master, datagram); - fsm->slave_state = ec_fsm_slaveconf_fmmu; - return; - } - // start SDO configuration fsm->slave_state = ec_fsm_slaveconf_sdoconf; fsm->coe_sdodata = list_entry(slave->sdo_confs.next, ec_sdo_data_t, list); @@ -1526,136 +1531,6 @@ return; } - if (master->debug_level) { - EC_DBG("Fetching SDO dictionary of slave %i.\n", - slave->ring_position); - } - - // start fetching SDO dictionary - fsm->slave_state = ec_fsm_slaveconf_sdodict; - fsm->coe_state = ec_fsm_coe_dict_start; - fsm->coe_state(fsm); // execute immediately -} - -/*****************************************************************************/ - -/** - Slave configuration state: SDODICT. -*/ - -void ec_fsm_slaveconf_sdodict(ec_fsm_t *fsm /**< finite state machine */) -{ - ec_slave_t *slave = fsm->slave; - ec_datagram_t *datagram = &fsm->datagram; - ec_master_t *master = fsm->master; - unsigned int j; - - fsm->coe_state(fsm); // execute CoE state machine - - if (fsm->coe_state == ec_fsm_error) { - fsm->slave->error_flag = 1; - fsm->slave_state = ec_fsm_error; - return; - } - - if (fsm->coe_state != ec_fsm_end) return; - - // SDO dictionary fetching finished - - if (master->debug_level) { - EC_DBG("Finished fetching SDO dictionary of slave %i.\n", - slave->ring_position); - } - - if (slave->current_state == slave->requested_state) { - fsm->slave_state = ec_fsm_end; // successful - if (master->debug_level) { - EC_DBG("Finished configuration of slave %i.\n", - slave->ring_position); - } - return; - } - - if (list_empty(&slave->sdo_confs)) { - // skip SDO configuration - - if (!slave->base_fmmu_count) { - // slave has no FMMUs. skip configuration. - - // set state to SAVEOP - fsm->slave_state = ec_fsm_slaveconf_saveop; - fsm->change_new = EC_SLAVE_STATE_SAVEOP; - fsm->change_state = ec_fsm_change_start; - fsm->change_state(fsm); // execute immediately - return; - } - - // configure FMMUs - ec_datagram_npwr(datagram, slave->station_address, - 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count); - memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); - for (j = 0; j < slave->fmmu_count; j++) { - ec_fmmu_config(&slave->fmmus[j], slave, - datagram->data + EC_FMMU_SIZE * j); - } - - ec_master_queue_datagram(master, datagram); - fsm->slave_state = ec_fsm_slaveconf_fmmu; - return; - } - - // start SDO configuration - fsm->slave_state = ec_fsm_slaveconf_sdoconf; - fsm->coe_sdodata = list_entry(slave->sdo_confs.next, ec_sdo_data_t, list); - fsm->coe_state = ec_fsm_coe_down_start; - fsm->coe_state(fsm); // execute immediately -} - -/*****************************************************************************/ - -/** - Slave configuration state: SDOCONF. -*/ - -void ec_fsm_slaveconf_sdoconf(ec_fsm_t *fsm /**< finite state machine */) -{ - ec_slave_t *slave = fsm->slave; - ec_datagram_t *datagram = &fsm->datagram; - ec_master_t *master = fsm->master; - unsigned int j; - - fsm->coe_state(fsm); // execute CoE state machine - - if (fsm->coe_state == ec_fsm_error) { - fsm->slave->error_flag = 1; - fsm->slave_state = ec_fsm_error; - return; - } - - if (fsm->coe_state != ec_fsm_end) return; - - // Another SDO to configure? - if (fsm->coe_sdodata->list.next != &fsm->slave->sdo_confs) { - fsm->coe_sdodata = list_entry(fsm->coe_sdodata->list.next, - ec_sdo_data_t, list); - fsm->coe_state = ec_fsm_coe_down_start; - fsm->coe_state(fsm); // execute immediately - return; - } - - // All SDOs are now configured. - - if (!slave->base_fmmu_count) { - // slave has no FMMUs. skip configuration. - - // set state to SAVEOP - fsm->slave_state = ec_fsm_slaveconf_saveop; - fsm->change_new = EC_SLAVE_STATE_SAVEOP; - fsm->change_state = ec_fsm_change_start; - fsm->change_state(fsm); // execute immediately - return; - } - // configure FMMUs ec_datagram_npwr(datagram, slave->station_address, 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count); @@ -1678,6 +1553,7 @@ void ec_fsm_slaveconf_fmmu(ec_fsm_t *fsm /**< finite state machine */) { ec_datagram_t *datagram = &fsm->datagram; + ec_slave_t *slave = fsm->slave; if (datagram->state != EC_DATAGRAM_RECEIVED || datagram->working_counter != 1) { @@ -1688,6 +1564,52 @@ return; } + // No CoE configuration to be applied? Jump to SAVEOP state. + if (list_empty(&slave->sdo_confs)) { // skip SDO configuration + // set state to SAVEOP + fsm->slave_state = ec_fsm_slaveconf_saveop; + fsm->change_new = EC_SLAVE_STATE_SAVEOP; + fsm->change_state = ec_fsm_change_start; + fsm->change_state(fsm); // execute immediately + return; + } + + // start SDO configuration + fsm->slave_state = ec_fsm_slaveconf_sdoconf; + fsm->coe_sdodata = list_entry(slave->sdo_confs.next, ec_sdo_data_t, list); + fsm->coe_state = ec_fsm_coe_down_start; + fsm->coe_state(fsm); // execute immediately +} + +/*****************************************************************************/ + +/** + Slave configuration state: SDOCONF. +*/ + +void ec_fsm_slaveconf_sdoconf(ec_fsm_t *fsm /**< finite state machine */) +{ + fsm->coe_state(fsm); // execute CoE state machine + + if (fsm->coe_state == ec_fsm_error) { + fsm->slave->error_flag = 1; + fsm->slave_state = ec_fsm_error; + return; + } + + if (fsm->coe_state != ec_fsm_end) return; + + // Another SDO to configure? + if (fsm->coe_sdodata->list.next != &fsm->slave->sdo_confs) { + fsm->coe_sdodata = list_entry(fsm->coe_sdodata->list.next, + ec_sdo_data_t, list); + fsm->coe_state = ec_fsm_coe_down_start; + fsm->coe_state(fsm); // execute immediately + return; + } + + // All SDOs are now configured. + // set state to SAVEOP fsm->slave_state = ec_fsm_slaveconf_saveop; fsm->change_new = EC_SLAVE_STATE_SAVEOP; diff -r 7a43437bc48b -r cf724fc82a00 master/slave.c --- a/master/slave.c Thu Oct 19 14:05:56 2006 +0000 +++ b/master/slave.c Thu Oct 19 14:23:24 2006 +0000 @@ -83,6 +83,8 @@ .default_attrs = def_attrs }; +static struct kobj_type ktype_ec_slave_sdos = {}; + /** \endcond */ /*****************************************************************************/ @@ -114,6 +116,18 @@ return -1; } + // init SDO kobject and add it to the hierarchy + memset(&slave->sdo_kobj, 0x00, sizeof(struct kobject)); + kobject_init(&slave->sdo_kobj); + slave->sdo_kobj.ktype = &ktype_ec_slave_sdos; + slave->sdo_kobj.parent = &slave->kobj; + if (kobject_set_name(&slave->sdo_kobj, "sdos")) { + EC_ERR("Failed to set kobject name.\n"); + kobject_put(&slave->sdo_kobj); + kobject_put(&slave->kobj); + return -1; + } + slave->master = master; slave->requested_state = EC_SLAVE_STATE_UNKNOWN; @@ -158,6 +172,9 @@ INIT_LIST_HEAD(&slave->sdo_dictionary); INIT_LIST_HEAD(&slave->sdo_confs); + slave->sdo_dictionary_fetched = 0; + slave->jiffies_preop = 0; + for (i = 0; i < 4; i++) { slave->dl_link[i] = 0; slave->dl_loop[i] = 0; @@ -225,6 +242,10 @@ kobject_put(&sdo->kobj); } + // free SDO kobject + if (slave->sdo_dictionary_fetched) kobject_del(&slave->sdo_kobj); + kobject_put(&slave->sdo_kobj); + // free all SDO configurations list_for_each_entry_safe(sdodata, next_sdodata, &slave->sdo_confs, list) { list_del(&sdodata->list); diff -r 7a43437bc48b -r cf724fc82a00 master/slave.h --- a/master/slave.h Thu Oct 19 14:05:56 2006 +0000 +++ b/master/slave.h Thu Oct 19 14:23:24 2006 +0000 @@ -248,8 +248,11 @@ ec_fmmu_t fmmus[EC_MAX_FMMUS]; /**< FMMU configurations */ uint8_t fmmu_count; /**< number of FMMUs used */ + struct kobject sdo_kobj; /**< kobject for SDOs */ struct list_head sdo_dictionary; /**< SDO dictionary list */ struct list_head sdo_confs; /**< list of SDO configurations */ + uint8_t sdo_dictionary_fetched; /**< dictionary has been fetched */ + unsigned long jiffies_preop; /**< time, the slave went to PREOP */ }; /*****************************************************************************/