EtherCAT 中的 Alias 是一個 16 位的數值,用于在拓撲結構中唯一標識從站(除 Position 外的輔助定位方式)
IGH查看別名
“0:0”, 第一個0是別名(alias),后面是位置(position)
sudo ethercat slave -p 0
0 0:0 PREOP + SV660_1Axis_00916
設置別名
sudo ethercat alias -p 0 0x1001
sudo ethercat slave -p 0
0 4097:0 PREOP + SV660_1Axis_00916
別名設置成功之后如何以別名去訪問EtherCAT從站, 在之前的文章中,都是使用-p命令,而現在可以使用-a來訪問。
sudo ethercat cstruct -a 4097
/* Master 0, Slave 0, "InoSV660N"* Vendor ID: 0x00100000* Product code: 0x000c010d* Revision number: 0x00010000*/ec_pdo_entry_info_t slave_0_pdo_entries[] = {{0x6040, 0x00, 16},{0x607a, 0x00, 32},{0x60b8, 0x00, 16},{0x60fe, 0x01, 32},{0x603f, 0x00, 16},{0x6041, 0x00, 16},{0x6064, 0x00, 32},{0x6077, 0x00, 16},{0x60f4, 0x00, 32},{0x60b9, 0x00, 16},{0x60ba, 0x00, 32},{0x60bc, 0x00, 32},{0x60fd, 0x00, 32},
};ec_pdo_info_t slave_0_pdos[] = {{0x1701, 4, slave_0_pdo_entries + 0},{0x1b01, 9, slave_0_pdo_entries + 4},
};ec_sync_info_t slave_0_syncs[] = {{0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},{1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},{2, EC_DIR_OUTPUT, 1, slave_0_pdos + 0, EC_WD_ENABLE},{3, EC_DIR_INPUT, 1, slave_0_pdos + 1, EC_WD_DISABLE},{0xff}
};
IGH編程如何設置別名
在IGH源碼中找到CommandAlias.cpp
/** Writes the Secondary slave address (alias) to the slave's SII.*/
void CommandAlias::writeSlaveAlias(MasterDevice &m,const ec_ioctl_slave_t &slave,uint16_t alias)
{ec_ioctl_slave_sii_t data;stringstream err;uint8_t crc;if (slave.sii_nwords < 8) {err << "Current SII contents are too small to set an alias "<< "(" << slave.sii_nwords << " words)!";throwCommandException(err);}// read first 8 SII wordsdata.slave_position = slave.position;data.offset = 0;data.nwords = 8;data.words = new uint16_t[data.nwords];try {m.readSii(&data);} catch (MasterDeviceException &e) {delete [] data.words;err << "Failed to read SII: " << e.what();throwCommandException(err);}// write new alias address in word 4data.words[4] = cpu_to_le16(alias);// calculate checksum over words 0 to 6crc = calcSiiCrc((const uint8_t *) data.words, 14);// write new checksum into first byte of word 7*(uint8_t *) (data.words + 7) = crc;// write first 8 words with new alias and checksumtry {m.writeSii(&data);} catch (MasterDeviceException &e) {delete [] data.words;err << "Failed to read SII: " << e.what();throwCommandException(err);}delete [] data.words;
}
首先,函數會檢查目標從站的 SII(Slave Information Interface)數據區長度是否足夠(至少8個word),如果不足,則拋出異常,防止后續操作越界。
接著,函數準備一個 ec_ioctl_slave_sii_t 結構體,設置要讀取的從站位置、偏移量(從0開始)、讀取長度(8個word),并為數據分配內存。通過 m.readSii(&data) 讀取從站SII的前8個word,如果讀取失敗,會釋放內存并拋出異常。
讀取成功后,代碼將新的別名地址寫入到第4個word(data.words[4]),并使用 cpu_to_le16 保證字節序正確。然后,調用 calcSiiCrc 計算前7個word(共14字節)的校驗和(CRC),并將結果寫入第7個word的第一個字節,以保證SII數據的完整性。
最后,函數通過 m.writeSii(&data) 將修改后的8個word寫回從站SII。如果寫入失敗,同樣會釋放內存并拋出異常。無論成功或失敗,最后都確保釋放分配的內存,防止內存泄漏。
注意點:
- 該方法對SII數據的操作非常底層,需確保數據結構和協議細節正確無誤。
- 校驗和的計算和寫入是保證SII數據有效性的關鍵步驟。
- 異常處理和內存釋放做得較為嚴謹,避免資源泄漏和未定義行為。
地址空間概要
從站設備的配址由已設置的站地址或站別名地址的節點地址進行,配址方式為自動遞增配址。
位置地址/自動遞增地址
數據報保持為已配址從站位置地址的負值,各從站地址逐漸遞增。
讀取到地址“0”的從站將被配址,并接收數據。
位置地址主要用于在啟動EtherCAT系統時通過掃描現場總線把握系統的連接狀況
節點地址/站地址設置及站別名設置
站地址在啟動時由主站進行分配,不能通過EtherCAT從站進行更改。站別名的參數將保存在ESI EEPROM中,可
以通過EtherCAT從站進行變更。設置站別名必須經過主站許可。只有站地址或站別名與節點地址相符時,才會
開始執行相應的命令動作。
答疑
站別名地址設置是0x0012~0x0013, 為什么data.offset = 0, 這是寫到別名的地方嗎?
EtherCAT SII(Slave Information Interface)中,站別名地址(Alias Address)確實位于 SII 的物理地址 0x0012~0x0013(以字節為單位),也就是 SII 的第4個word(每個word為2字節,0x0012/2=0x0009,第4個word的偏移是4)。
在代碼中:
data.offset = 0;
data.nwords = 8;
這表示一次性讀取SII的前8個word(16字節,地址0x0000~0x000F),而不是只讀/寫別名地址本身。
隨后,代碼通過:
data.words[4] = cpu_to_le16(alias);
將別名寫入第4個word(即SII的0x0008~0x0009字節),這正是SII規范中別名地址的位置。
ESC寄存器配置區
字0-7,由ESC在上電或復位后自動讀取后寫入相應寄存器,并檢查校驗和。