Etherlab在IDLE状态下,扫描从站状态机(fsm_scan_slave)作为master状态机的一个重要子状态机,主要完成以下工作:
1. 读取EEPROM中的内容, 包括Vendor ID、Productcode、邮箱通信的地址和长度, rxpdo和txpdo等;
2. 使从站进入preop;
3. 在preop状态下,通过邮箱读取pdo配置信息,若读取成功,将覆盖从EEPROM中读取的PDO信息。
1、进入从站扫描状态机
master状态机在broadcast时,将周期性发送读130寄存器的广播帧,一旦发现返回的wkc的值发生变化,
将使状态机进入ec_fsm_master_enter_clear_addresses,进而切换到ec_fsm_master_state_scan_slave。
// bus topology change?
if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
fsm->rescan_required = 1;
2、函数调用关系
扫描从站时,master状态机将一直停留在ec_fsm_master_state_scan_slave,直到扫描完成转入write_system_times。
3、读取EEPROM信息
从站扫描状态机在ec_fsm_slave_scan_state_sii_size状态时,将从站EEPROM中的信息全部读取到slave->sii_words中,并在随后的状态ec_fsm_slave_scan_state_sii_data中对EEPROM的内容逐个进行解析:
slave->sii.alias =
EC_READ_U16(slave->sii_words + 0x0004);
slave->effective_alias = slave->sii.alias;
slave->sii.vendor_id =
EC_READ_U32(slave->sii_words + 0x0008);
slave->sii.product_code =
EC_READ_U32(slave->sii_words + 0x000A);
slave->sii.revision_number =
EC_READ_U32(slave->sii_words + 0x000C);
slave->sii.serial_number =
EC_READ_U32(slave->sii_words + 0x000E);
slave->sii.boot_rx_mailbox_offset =
EC_READ_U16(slave->sii_words + 0x0014);
slave->sii.boot_rx_mailbox_size =
EC_READ_U16(slave->sii_words + 0x0015);
slave->sii.boot_tx_mailbox_offset =
EC_READ_U16(slave->sii_words + 0x0016);
slave->sii.boot_tx_mailbox_size =
EC_READ_U16(slave->sii_words + 0x0017);
slave->sii.std_rx_mailbox_offset =
EC_READ_U16(slave->sii_words + 0x0018);
slave->sii.std_rx_mailbox_size =
EC_READ_U16(slave->sii_words + 0x0019);
slave->sii.std_tx_mailbox_offset =
EC_READ_U16(slave->sii_words + 0x001A);
slave->sii.std_tx_mailbox_size =
EC_READ_U16(slave->sii_words + 0x001B);
slave->sii.mailbox_protocols =
EC_READ_U16(slave->sii_words + 0x001C);
switch (cat_type) {
case 0x000A:
if (ec_slave_fetch_sii_strings(slave, (uint8_t *) cat_word,
cat_size * 2))
goto end;
break;
case 0x001E:
if (ec_slave_fetch_sii_general(slave, (uint8_t *) cat_word,
cat_size * 2))
goto end;
break;
case 0x0028:
break;
case 0x0029:
if (ec_slave_fetch_sii_syncs(slave, (uint8_t *) cat_word,
cat_size * 2))
goto end;
break;
case 0x0032:
if (ec_slave_fetch_sii_pdos( slave, (uint8_t *) cat_word,
cat_size * 2, EC_DIR_INPUT)) // TxPDO
goto end;
break;
case 0x0033:
if (ec_slave_fetch_sii_pdos( slave, (uint8_t *) cat_word,
cat_size * 2, EC_DIR_OUTPUT)) // RxPDO
goto end;
break;
default:
EC_SLAVE_DBG(slave, 1, "Unknown category type 0x%04X.\n", //igh没有解析EEPROM中的DC配置(cat_type为0x3c)
cat_type);
}
4、读取PDO配置信息
从站扫描状态机在ec_fsm_slave_scan_state_pdos状态时,将通过CoE读取pdo配置信息,以读取松下某驱动器为例,RxPDO依次读取0x1c12, 0x1600:00至0x1600:04的值,TxPDO依次读取0x1c13, 0x1a00:00至0x1a00:08的值,如下图所示: