Etherlab原始碼解析----slave_scan狀態機
阿新 • • 發佈:2019-02-05
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的值,如下圖所示: