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在上电或复位后自动读取后写入相应寄存器,并检查校验和。