diff --git a/NEWS b/NEWS index c658bb53155e6dc97ce59e6e7734eabdbb0ff0cb..dd8ab964b0f906cca132e76e787e85752555caa2 100644 --- a/NEWS +++ b/NEWS @@ -46,6 +46,7 @@ Changes in version 1.3.0: * Master state machine scheduled with timeout if idle, otherwise is executed as fast as possible (with schedule()). * Added dummy module for simulation purpuses. +* Limited infinite EEPROM reading, if 0xffff limiter word is missing. * Removed EtherCAT line comments from 8139too drivers. ------------------------------------------------------------------------------- diff --git a/TODO b/TODO index 93b5ba346380d4a9ce17c585a7fda4a2d290a95d..c6e3a5dbdea90cbefe10f43a99a5f9f839e6cbb5 100644 --- a/TODO +++ b/TODO @@ -8,7 +8,6 @@ $Id$ * Issues for release 1.3.0: - Take broadcast MAC address to register the first ethernet device. - - Limit EEPROM reading. - Implement ecrt_get_slave() with integer argument as ring position. - Handle missing rc_status in init script. diff --git a/master/fsm_slave.c b/master/fsm_slave.c index e35fb3421f66939aa7bedf951858c8f91e0af947..5c4fccc2798870f58a415fc34f332035720e2f88 100644 --- a/master/fsm_slave.c +++ b/master/fsm_slave.c @@ -366,7 +366,7 @@ void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_t *fsm /**< slave state machi // Start fetching EEPROM size - fsm->sii_offset = 0x0040; // first category header + fsm->sii_offset = EC_FIRST_EEPROM_CATEGORY_OFFSET; // first category header ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset, EC_FSM_SII_NODE); fsm->state = ec_fsm_slave_scan_state_eeprom_size; fsm->state(fsm); // execute state immediately @@ -398,6 +398,13 @@ void ec_fsm_slave_scan_state_eeprom_size(ec_fsm_slave_t *fsm /**< slave state ma if (cat_type != 0xFFFF) { // not the last category fsm->sii_offset += cat_size + 2; + if (fsm->sii_offset >= EC_MAX_EEPROM_SIZE) { + EC_WARN("EEPROM size of slave %i exceeds" + " %i words (0xffff limiter missing?).\n", + slave->ring_position, EC_MAX_EEPROM_SIZE); + slave->eeprom_size = EC_FIRST_EEPROM_CATEGORY_OFFSET * 2; + goto alloc_eeprom; + } ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset, EC_FSM_SII_NODE); ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately @@ -406,6 +413,7 @@ void ec_fsm_slave_scan_state_eeprom_size(ec_fsm_slave_t *fsm /**< slave state ma slave->eeprom_size = (fsm->sii_offset + 1) * 2; +alloc_eeprom: if (slave->eeprom_data) { EC_INFO("Freeing old EEPROM data on slave %i...\n", slave->ring_position); @@ -494,7 +502,7 @@ void ec_fsm_slave_scan_state_eeprom_data(ec_fsm_slave_t *fsm /**< slave state ma EC_READ_U16(slave->eeprom_data + 2 * 0x001C); // evaluate category data - cat_word = (uint16_t *) slave->eeprom_data + 0x0040; + cat_word = (uint16_t *) slave->eeprom_data + EC_FIRST_EEPROM_CATEGORY_OFFSET; while (EC_READ_U16(cat_word) != 0xFFFF) { cat_type = EC_READ_U16(cat_word) & 0x7FFF; cat_size = EC_READ_U16(cat_word + 1); diff --git a/master/globals.h b/master/globals.h index da3c74980652ae18121ce0321ec5d628e406817d..e255c8f44c29742cc610c5c87b8d58d033c51e4d 100644 --- a/master/globals.h +++ b/master/globals.h @@ -65,6 +65,9 @@ /** minimum size of a buffer used with ec_state_string() */ #define EC_STATE_STRING_SIZE 32 +/** maximum EEPROM size in words, to avoid infinite reading. */ +#define EC_MAX_EEPROM_SIZE 512 + /****************************************************************************** * EtherCAT protocol *****************************************************************************/ @@ -82,6 +85,9 @@ #define EC_MAX_DATA_SIZE (ETH_DATA_LEN - EC_FRAME_HEADER_SIZE \ - EC_DATAGRAM_HEADER_SIZE - EC_DATAGRAM_FOOTER_SIZE) +/** word offset of first EEPROM category. */ +#define EC_FIRST_EEPROM_CATEGORY_OFFSET 0x40 + /*****************************************************************************/ /** diff --git a/master/slave.c b/master/slave.c index a5160be9b5b9cc8691198bb52cdcb9ff0b91fda2..2a61afc6576b00ba2562cfdfa2ee7fe7d7451b0b 100644 --- a/master/slave.c +++ b/master/slave.c @@ -925,7 +925,7 @@ ssize_t ec_slave_write_eeprom(ec_slave_t *slave, /**< EtherCAT slave */ return -EINVAL; } - cat_header = request.words + 0x0040; // first category header + cat_header = request.words + EC_FIRST_EEPROM_CATEGORY_OFFSET; cat_type = EC_READ_U16(cat_header); while (cat_type != 0xFFFF) { // cycle through categories if (cat_header + 1 > request.words + request.size) {