1. 程式人生 > >Etherlab原始碼解析----slave_scan狀態機

Etherlab原始碼解析----slave_scan狀態機

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的值,如下圖所示:
這裡寫圖片描述