热连接 (HotConnect)
热连接 (Hot Connect) 允许在网络运行时动态接入或拔出从站, 而不必停机重新扫描. 典型场景:
- 工艺工位可换装的子工装 (按需接入若干 IO 模块)
- 需要随产线节拍快进快出的"附加轴"
- 移动 / 可选诊断设备
每个热连接组在配置时声明 预期 (alias_address, vendor_id, product_code), SDK 在底层周期帧中识别匹配的从站, 不在场时不算错, 在场时自动加入网络.
通过 HotConnect::new(master.index()) 构造管理器.
Alias 必须先烧录
- Alias Address (ESC
0x0012) 必须预先烧录到从站 EEPROM, 非 0 且组内唯一 - Alias=0 的从站不支持 Hot-Connect (ETG.1020 §8.3)
数据结构
HotConnectGroup
pub struct HotConnectGroup {
pub group_id: u16, // 用户分配的组 ID, 1..65535
pub alias_address: u16, // 期望 Alias 地址 (ESC 0x0012)
pub vendor_id: u32, // 期望 VendorID, 0 = 不校验
pub product_code: u32, // 期望 ProductCode, 0 = 不校验
pub is_present: bool, // 是否在当前扫描中探测到
pub detected_slave_index: u16, // 匹配到的从站索引 (1-based), 0 = 未匹配
}
HotConnectStatus
pub enum HotConnectStatus {
Unknown = -1, // 组未注册或底层查询失败
Absent = 0, // 组在当前扫描中未探测到
Present = 1, // 组在当前扫描中探测到
}
HotPlugIdentityMismatch
pub struct HotPlugIdentityMismatch {
pub master_index: u16,
pub slave_index: u16,
pub expected_vendor: u32,
pub expected_product: u32,
pub expected_revision: u32,
pub actual_vendor: u32,
pub actual_product: u32,
pub actual_revision: u32,
}
常量
pub const MAX_GROUPS: usize = 32;
每个主站最多支持的 Hot-Connect 组数.
方法
HotConnect::new()
pub fn new(master_index: u16) -> Self
构造 Hot-Connect 管理器.
参数:
master_index(u16) — 主站编号
add_group()
pub fn add_group(&self, group_id: u16, alias: u16,
vendor_id: u32, product_code: u32) -> bool
注册一个 Hot-Connect 组.
参数:
group_id(u16) — 组 ID (1..65535, 同一主站内唯一)alias(u16) — 期望 Alias 地址 (必须非 0)vendor_id(u32) — 期望 VendorID,0= 不校验product_code(u32) — 期望 ProductCode,0= 不校验
返回值:
bool—true= 组定义已接受
示例:
use ethercat::HotConnect;
let hc = HotConnect::new(master.index());
let ok = hc.add_group(1, 0x1001, 0x0000_0002, 0x044C_2C52);
remove_group()
pub fn remove_group(&self, group_id: u16) -> bool
删除指定 Hot-Connect 组.
group_status()
pub fn group_status(&self, group_id: u16) -> HotConnectStatus
查询某个组的当前 Present / Absent 状态.
clear_all()
pub fn clear_all(&self)
清空当前主站所有 Hot-Connect 组定义.
group_count()
pub fn group_count(&self) -> i32
当前已注册组数.
enumerate()
pub fn enumerate(&self) -> Vec<HotConnectGroup>
枚举所有已注册的 Hot-Connect 组及其当前状态.
示例:
for g in hc.enumerate() {
println!("组 {} alias=0x{:04X} present={} slave_idx={}",
g.group_id, g.alias_address, g.is_present, g.detected_slave_index);
}
HotPlug 自修复事件
热插拔身份不符事件: 同一从站被换成其他设备 / 旧版本固件时触发, 操作员检查 / 更换设备后调用 master.acknowledge_slave_replacement() 让 SDK 重新探测.
on_hotplug()
pub fn on_hotplug<F>(callback: F)
where F: Fn(HotPlugIdentityMismatch) + Send + 'static
注册 HotPlug 自修复事件回调. 多次调用可累加多个订阅者.
示例:
use ethercat::master::hot_connect::on_hotplug;
on_hotplug(|ev| {
println!("从站 {} 身份不符: 期望 V=0x{:08X} P=0x{:08X}, 实际 V=0x{:08X} P=0x{:08X}",
ev.slave_index,
ev.expected_vendor, ev.expected_product,
ev.actual_vendor, ev.actual_product);
});
clear_hotplug_listeners()
pub fn clear_hotplug_listeners()
清空 HotPlug 订阅.
完整示例
use ethercat::{EtherCATMaster, HotConnect};
use ethercat::master::hot_connect::{on_hotplug, HotPlugIdentityMismatch};
let mut master = EtherCATMaster::from_json_file("config.json")?;
let hc = HotConnect::new(master.index());
// 1. 注册热连接组
hc.add_group(1, 0x1001, 0x0000_0002, 0x044C_2C52);
hc.add_group(2, 0x2001, 0x0000_006A, 0x0000_1389);
// 2. 订阅热插拔身份不符事件
on_hotplug(|ev: HotPlugIdentityMismatch| {
println!("[HotPlug] 从站 {} 身份不符", ev.slave_index);
});
// 3. 启动主站
master.start();
// 4. 运行中查询状态
println!("已注册 {} 个组", hc.group_count());
for g in hc.enumerate() {
println!("组 {} alias=0x{:04X} present={}", g.group_id, g.alias_address, g.is_present);
}
// 5. 拆站 / 关机时清理
hc.clear_all();
限制
- DC 主站参考时钟从站不可放进热连接组
- 同一组内 Alias 必须唯一 (alias=0 不支持 Hot-Connect)
参考
- ETG.1020 §8 Hot Connect 与 Alias Address
- ETG.1500 §6.3 Hot Connect Groups