热连接 (HotConnect)
Hot-Connect 把「扫描时可能不在场」的从站登记成一组。组表是扫描期登记:必须在 set_network / 扫描前调用 add_group。扫描按 Alias 匹配,把组标成 present / absent。不调用 add_group 时所有从站仍是 mandatory(缺失即 AL_ERROR)。扫描时某组缺席不再算错,其余从站可以继续进 OP。
运行中插回不会自动进 OP。 主站可报 Offline/Online;应用层要自己处理状态机。不要指望插回去就自动进 OP;断电重连、换同型号也不会由主站自动拉回 OP。
典型场景:
- 工艺工位可换装的子工装 (扫描时可不在场的 IO 模块)
- 需要按产线节拍选用的附加轴
- 移动 / 可选诊断设备
每个热连接组在配置时声明 预期 (alias_address, vendor_id, product_code)。SDK 在扫描阶段按 Alias 匹配,不在场时不算错。在场也不会在运行中自动加入 OP。
通过 HotConnect::new(master.index()) 构造管理器。
add_group必须在set_network/ 扫描前调用- 不要用
from_json_file一步启动后再登记组表(内部已经跑过set_network) - 运行中插回不会自动进 OP;主站可报 Offline/Online,应用层自己处理状态机
- 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 组。 须在 set_network / 扫描前调用。 运行中插回不会因本组登记而自动进 OP.
参数:
group_id(u16) — 组 ID (1..65535, 同一主站内唯一)alias(u16) — 期望 Alias 地址 (必须非 0)vendor_id(u32) — 期望 VendorID,0= 不校验product_code(u32) — 期望 ProductCode,0= 不校验
返回值:
bool—true= 已写入组表;false= 未登记
示例:
use darra_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 自修复事件
运行中插回不会自动进 OP。身份不符事件: 同一从站被换成其他设备 / 旧版本固件时触发, 操作员检查 / 更换设备后调用 master.acknowledge_slave_replacement()。应用层要自己处理状态机。
on_hotplug()
pub fn on_hotplug<F>(callback: F)
where F: Fn(HotPlugIdentityMismatch) + Send + 'static
注册 HotPlug 自修复事件回调。 多次调用可累加多个订阅者。
示例:
use darra_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 darra_ethercat::{EtherCATMaster, HotConnect};
use darra_ethercat::master::hot_connect::{on_hotplug, HotPlugIdentityMismatch};
// 手动配置模式:AddGroup → set_network。不要用 from_json_file 一步启动后再登记
let mut master = EtherCATMaster::new()?;
let hc = HotConnect::new(master.index());
// 1. 扫描前登记组表(必须在 set_network / 扫描前)
hc.add_group(1, 0x1001, 0x0000_0002, 0x044C_2C52);
hc.add_group(2, 0x2001, 0x0000_006A, 0x0000_1389);
// 2. 订阅身份不符事件(插回不会自动进 OP,应用层自己处理状态机)
on_hotplug(|ev: HotPlugIdentityMismatch| {
println!("[HotPlug] 从站 {} 身份不符", ev.slave_index);
});
// 3. set_network 扫描按 Alias 匹配,缺席组标 absent
master.set_network(r"\Device\NPF_{YOUR-GUID}", "")?;
master.start();
// 4. Present/Absent 是扫描结果,不是自动进 OP
println!("已注册 {} 个组", hc.group_count());
for g in hc.enumerate() {
println!("组 {} alias=0x{:04X} present={}", g.group_id, g.alias_address, g.is_present);
}
// 5. 切换工艺前清空(通常在重新 set_network 前)
hc.clear_all();
- DC 主站参考时钟从站不可放进热连接组
- 同一组内 Alias 必须唯一 (alias=0 不支持 Hot-Connect)
- ETG.1020 §8 Hot Connect 与 Alias Address
- ETG.1500 §6.3 Hot Connect Groups