ENI 配置加载与保存
ENI(EtherCAT Network Information,ETG.2100)是描述整张 EtherCAT 网络的标准 XML:周期、从站列表、PDO 映射、SyncManager、DC 配置等。Darra C++ SDK 在 ethercat.hpp 中提供两个对称函数:
LoadENI(...)— 从磁盘加载 ENI XML 解析为EniConfiguration结构SaveENI(...)— 把EniConfiguration写回 XML 文件
两者由 C++ 端通过 pugixml 直接生成 / 解析,不依赖 DLL 导出,因此即使旧版 Darra.Core.dll 没有 ENI 相关入口也可以使用。
LoadENI / SaveENI 的实现走 pugixml。在包含 SDK 头文件之前需要:
#define ENABLE_ESI_XML
#include <pugixml.hpp>
#include "ethercat.hpp"
未启用 ENABLE_ESI_XML 宏时,LoadENI / SaveENI 不参与编译(避免强制依赖 pugixml)。
数据结构
EniMasterConfig
struct EniMasterConfig {
std::string Name; // 主站名
int CycleTimeUs = 1000; // 主周期 (微秒)
int DcCycleTimeUs = 1000; // DC 周期 (微秒)
int ExpectedSlaveCount = 0; // 期望从站数 (=Slaves.size())
};
EniSlaveConfig
struct EniSlaveConfig {
int PhysicalAddress = 0; // ESC 物理地址
int AutoIncAddress = 0; // 自动递增地址
uint32_t VendorId = 0;
uint32_t ProductCode = 0;
uint32_t RevisionNumber = 0;
std::string Name;
int DcAssignActivate = 0; // DC AssignActivate (0=不使用 DC)
// SM2 输出 / SM3 输入 偏移与长度 (字节)
int Sm2Offset = 0, Sm2Length = 0;
int Sm3Offset = 0, Sm3Length = 0;
};
EniConfiguration
struct EniConfiguration {
EniMasterConfig Master;
std::vector<EniSlaveConfig> Slaves;
std::string Version = "3.0";
};
完整 ENI 配置:主站段 + 从站列表 + 版本号。
LoadENI()
namespace darra::ethercat {
bool LoadENI(const std::string& filePath, EniConfiguration& outConfig);
}
加载 ENI XML 文件并解析为 EniConfiguration。
参数:
filePath— ENI XML 文件路径(UTF-8)outConfig— 输出配置结构(成功时填充,失败时未定义)
返回值:
true— 解析成功false— 文件不存在 / 根节点不匹配 / XML 解析失败
行为说明:
- 仅识别
<EtherCATConfig>根(ETG.2100 标准) - 旧版
<DarraEtherCATConfiguration>根(DENI 私有格式)不在本函数处理范围,需要使用 IDE 配置工具导出 - 数值字段同时支持
0xABCD/#xABCD/#ABCD/ 十进制四种写法 Master.CycleTimeUs/DcCycleTimeUs为 0 时自动回退为1000(1ms)
示例:
#define ENABLE_ESI_XML
#include <pugixml.hpp>
#include "ethercat.hpp"
darra::ethercat::EniConfiguration cfg;
if (darra::ethercat::LoadENI("C:/EtherCAT/network.eni", cfg)) {
printf("主站: %s, 周期 %d us, %zu 个从站\n",
cfg.Master.Name.c_str(),
cfg.Master.CycleTimeUs,
cfg.Slaves.size());
for (auto& s : cfg.Slaves) {
printf(" [%d] %s VID=0x%08X PID=0x%08X RevID=0x%08X\n",
s.PhysicalAddress, s.Name.c_str(),
s.VendorId, s.ProductCode, s.RevisionNumber);
}
} else {
printf("ENI 加载失败\n");
}
SaveENI()
bool SaveENI(const std::string& filePath, const EniConfiguration& config);
把 EniConfiguration 写回 ENI XML 文件,与 LoadENI 形成对称(保存的文件可由 LoadENI 重新读回)。
参数:
filePath— 输出 ENI 文件路径(UTF-8)config— 已填充的 ENI 配置
返回值:
true— 写入成功false— 路径为空或写入失败
生成结构:
<?xml version="1.0" encoding="UTF-8"?>
<EtherCATConfig>
<Config>
<Master>
<Info>
<Name>...</Name>
<Source>DarraEtherCAT C++ SDK SaveENI</Source>
</Info>
<CycleTime>...</CycleTime>
<DcCycleTime>...</DcCycleTime>
</Master>
<Slave> ... </Slave>
<Slave> ... </Slave>
</Config>
</EtherCATConfig>
SaveENI 输出的 XML 还会带 DENI 扩展命名空间 http://www.darra-tech.com/schemas/eni/v3.0,承载 CycleTime / DcCycleTime / ExpectedSlaveCount 等 IDE 扩展信息(LoadENI 解析时识别)。
示例:
darra::ethercat::EniConfiguration cfg;
cfg.Master.Name = "Line-A Master";
cfg.Master.CycleTimeUs = 1000;
cfg.Master.DcCycleTimeUs = 1000;
darra::ethercat::EniSlaveConfig s;
s.PhysicalAddress = 0x03E9;
s.VendorId = 0x00000002;
s.ProductCode = 0x07D81052;
s.RevisionNumber = 0x00120000;
s.Name = "EL2008";
s.Sm2Offset = 0x1000;
s.Sm2Length = 1;
cfg.Slaves.push_back(s);
if (darra::ethercat::SaveENI("C:/EtherCAT/exported.eni", cfg)) {
printf("已写入 ENI\n");
}
| 格式 | 根节点 | 说明 |
|---|---|---|
| ENI | <EtherCATConfig> | ETG.2100 标准, 跨主站通用 |
| DENI | <DarraEtherCATConfiguration> | Darra IDE 私有, 包含完整配置 + 厂家扩展 |
LoadENI / SaveENI 处理 ENI;master.SetENI(...) 同时接受两种格式。一般"导出给第三方主站"用 ENI,"自己 Master + IDE 闭环"用 DENI。
完整示例 (导入 → 修改 → 导出)
#define ENABLE_ESI_XML
#include <pugixml.hpp>
#include "ethercat.hpp"
using namespace darra::ethercat;
int main() {
EniConfiguration cfg;
if (!LoadENI("C:/EtherCAT/source.eni", cfg)) {
printf("加载失败\n");
return -1;
}
// 调整主周期
cfg.Master.CycleTimeUs = 500; // 500us
cfg.Master.DcCycleTimeUs = 500;
// 给所有从站统一启用 DC SYNC0
for (auto& s : cfg.Slaves) {
if (s.DcAssignActivate == 0) s.DcAssignActivate = 0x0300; // SYNC0+SYNC1
}
if (!SaveENI("C:/EtherCAT/tuned.eni", cfg)) {
printf("保存失败\n");
return -1;
}
printf("已生成 tuned.eni\n");
return 0;
}
ETG.2100 EtherCAT Network Information 标准;pugixml 1.13+ 与 C++17 编译要求。