ESI (EtherCAT Slave Information) 字典文件解析指南

面向需要手动从 ESI XML 搬运数据到 IgH/SOEM C 代码的工程师,兼顾认知学习与查阅需求。按照“理解结构 → 提取信息 → 填入代码 → 工具验证 → 排障”顺序组织,快速完成从硬件描述到主站配置的闭环。

L6N_V1.08.xml 是 L6N 伺服驱动器的 ESI (EtherCAT Slave Information) 设备描述文件,也称为”设备字典”或”XML 描述文件”。它与 ec_slave_config.h 文件是完全对应的关系。


快速导航


0. 准备与工具

项目 说明 推荐工具
ESI XML 文件 厂商提供的设备描述文件 (通常位于 ../ethercat/master/slaves/ 或驱动光盘) VS Code + XML 插件、xmllint
参考文档 厂商设备手册,确认 PDO/对象含义与单位 PDF 阅读器
命令行工具 IgH ethercat CLI、xmllint/xpath ethercat slaves/pdos/cstruct
主站代码 ec_slave_config.h/cec_domain_reg_pdo_entry_list 注册表等 GCC/Clang

解析前确保 XML 与驱动固件版本一致;部分厂商会在 RevisionNo 变化时更新 PDO 定义。


1. ESI XML 架构总览

典型结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<EtherCATInfo>
<Vendor>
<Id>17185</Id>
<Name>INOVANCE</Name>
</Vendor>
<Descriptions>
<Devices>
<Device>
<Type ProductCode="#xE2" RevisionNo="1">L6N</Type>
<RxPdos>...</RxPdos>
<TxPdos>...</TxPdos>
<SyncManagers>...</SyncManagers>
<Dc>...</Dc>
</Device>
</Devices>
</Descriptions>
</EtherCATInfo>

关键节点:

节点 作用
<Vendor>/<Id> 厂商 ID (十进制)
<Type ProductCode="..." RevisionNo="..."> 产品码、固件版本
<RxPdos>/<TxPdos> 每个 PDO 及其 Entry 定义
<SyncManagers>/<Sm> SM 起始地址、方向、看门狗
<Dc> 分布式时钟设置 (部分驱动提供)

使用 XML XPath (xpath -e "//Device[@Name='L6N']" file.xml) 可快速定位目标设备。


2. 设备识别信息

2.1 XML 示例

1
2
3
4
5
6
<Device>
<Type ProductCode="#xE2" RevisionNo="#x00000001">L6N</Type>
<Vendor>
<Id>17185</Id> <!-- 0x4321 -->
</Vendor>
</Device>

2.2 C 代码

1
2
3
4
5
6
7
8
9
10
11
/* Master 0, Slave 0, "L6N"
* Vendor ID: 0x00004321 ← 对应 XML 的 <Id>17185</Id>
* Product code: 0x000000e2 ← 对应 XML 的 ProductCode="#xE2"
* Revision number: 0x00000001 ← 对应 XML 的 RevisionNo="1"
*/

#define L6N 0x00004321, 0x000000e2 // Vendor ID, Product Code

#define L6N_VENDOR_ID 0x00004321 // 17185 -> 0x4321
#define L6N_PRODUCT_CODE 0x000000e2
#define L6N_REVISION_NO 0x00000001

注意:部分驱动要求 RevisionNo 也匹配;IgH 可传入 ecrt_master_slave_config(master, alias, position, vendor, product | (revision << 32))(若使用扩展接口)。


3. PDO 映射分解

3.1 RxPDO (主站→从站)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<RxPdo Fixed="0" Sm="2">
<Index>#x1600</Index>
<Name>Receive PDO 1</Name>

<Entry>
<Index>#x6040</Index> <!-- 控制字 -->
<SubIndex>0</SubIndex>
<BitLen>16</BitLen>
<Name>Control word</Name>
<DataType>UINT</DataType>
</Entry>

<Entry>
<Index>#x607a</Index> <!-- 目标位置 -->
<SubIndex>0</SubIndex>
<BitLen>32</BitLen>
<Name>Profile target position</Name>
<DataType>DINT</DataType>
</Entry>

<Entry>
<Index>#x60b8</Index> <!-- 探针功能 -->
<SubIndex>0</SubIndex>
<BitLen>16</BitLen>
<Name>Touch Probe Function</Name>
<DataType>UINT</DataType>
</Entry>
</RxPdo>
1
2
3
4
5
6
7
8
9
10
11
12
13
ec_pdo_entry_info_t slave_0_pdo_entries[] = {
// RxPDO 入口 (主站 → 从站)
{0x6040, 0x00, 16}, // 控制字, 16位
{0x607a, 0x00, 32}, // 目标位置, 32位
{0x60b8, 0x00, 16}, // 探针功能, 16位

// ... 其他入口
};

ec_pdo_info_t slave_0_pdos[] = {
{0x1600, 3, slave_0_pdo_entries + 0}, // PDO索引0x1600, 3个入口
// ...
};
XML 字段 对应 C 代码
<RxPdo>/<Index> ec_pdo_info_t.index (0x1600)
<Entry>/<Index> ec_pdo_entry_info_t.index
<Entry>/<SubIndex> ...subindex
<Entry>/<BitLen> ...bit_length
<RxPdo Fixed="0" Sm="2"> ec_sync_info_tindex=2、方向 OUTPUT

3.2 TxPDO (从站→主站)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<TxPdo Fixed="0" Sm="3">
<Index>#x1a00</Index>
<Name>Transmit PDO 1</Name>

<Entry>
<Index>#x603F</Index> <!-- 错误代码 -->
<SubIndex>#x00</SubIndex>
<BitLen>16</BitLen>
<Name>Last error code</Name>
<DataType>UINT</DataType>
</Entry>

<Entry>
<Index>#x6041</Index> <!-- 状态字 -->
<SubIndex>0</SubIndex>
<BitLen>16</BitLen>
<Name>Status word</Name>
<DataType>UINT</DataType>
</Entry>

<Entry>
<Index>#x6061</Index> <!-- 运行模式显示 -->
<SubIndex>#x00</SubIndex>
<BitLen>8</BitLen>
<Name>Modes of operation display</Name>
<DataType>SINT</DataType>
</Entry>

<!-- 还有更多入口... -->

<Entry>
<Index>#x6064</Index> <!-- 实际位置 -->
<SubIndex>0</SubIndex>
<BitLen>32</BitLen>
<Name>Actual motor position</Name>
<DataType>DINT</DataType>
</Entry>
</TxPdo>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ec_pdo_entry_info_t slave_0_pdo_entries[] = {
// ... RxPDO入口 (前3个)

// TxPDO 入口 (从站 → 主站)
{0x603f, 0x00, 16}, // 错误代码
{0x6041, 0x00, 16}, // 状态字
{0x6061, 0x00, 8}, // 运行模式显示
{0x6064, 0x00, 32}, // 实际位置
{0x60b9, 0x00, 16}, // 探针状态
{0x60ba, 0x00, 32}, // 探针位置1
{0x60fd, 0x00, 32}, // 数字输入
};

ec_pdo_info_t slave_0_pdos[] = {
{0x1600, 3, slave_0_pdo_entries + 0}, // RxPDO
{0x1a00, 7, slave_0_pdo_entries + 3}, // TxPDO, 7个入口
};

注意: TxPDO 在 XML 中有 9 个入口,但 ec_slave_config.h 只使用了其中 7 个(根据实际需求选择)。

3.3 位宽与类型映射

BitLen 常用类型 IgH 宏
8 uint8_t/int8_t EC_READ_U8/EC_WRITE_U8
16 uint16_t/int16_t EC_READ_U16/EC_WRITE_U16
32 uint32_t/int32_t EC_READ_U32/EC_WRITE_S32

保持与驱动文档相同的有符号/无符号类型,避免溢出。若 BitLen 不是 8 的倍数,需确认厂商自定义位域并按位操作。

3.4 多 PDO/多 Entry 的数组布局

1
2
3
4
5
6
7
8
9
10
11
static ec_pdo_entry_info_t l6n_pdo_entries[] = {
{0x6040, 0x00, 16}, // Control Word
{0x607A, 0x00, 32}, // Target Position
{0x6041, 0x00, 16}, // Status Word
{0x6064, 0x00, 32}, // Actual Position
};

static ec_pdo_info_t l6n_pdos[] = {
{0x1600, 2, l6n_pdo_entries + 0}, // entries[0..1]
{0x1A00, 2, l6n_pdo_entries + 2}, // entries[2..3]
};

n_entries 必须与 XML 中 <Entry> 数量一致;指针偏移按顺序累加。

3.5 Domain 注册所需数据

1
2
3
4
5
6
7
8
9
10
11
12
static unsigned int off_ctrl_word;
static unsigned int off_target_pos;
static unsigned int off_status_word;
static unsigned int off_actual_pos;

const ec_pdo_entry_reg_t domain_regs[] = {
{0, 0, L6N_VENDOR_ID, L6N_PRODUCT_CODE, 0x6040, 0x00, &off_ctrl_word},
{0, 0, L6N_VENDOR_ID, L6N_PRODUCT_CODE, 0x607A, 0x00, &off_target_pos},
{0, 0, L6N_VENDOR_ID, L6N_PRODUCT_CODE, 0x6041, 0x00, &off_status_word},
{0, 0, L6N_VENDOR_ID, L6N_PRODUCT_CODE, 0x6064, 0x00, &off_actual_pos},
{}
};

ec_pdo_entry_reg_t 与 XML 的对应:VendorId、ProductCode、Index、SubIndex。alias/position 默认 0 表示匹配所有。


4. Sync Manager (SM) 配置

4.1 XML 示例

1
2
3
4
5
6
7
8
9
<Sm Enable="1" StartAddress="#x1000" ControlByte="#x26"
DefaultSize="124" MinSize="40" MaxSize="256">MBoxOut</Sm>
<Sm Enable="1" StartAddress="#x1100" ControlByte="#x22"
DefaultSize="124" MinSize="40" MaxSize="256">MBoxIn</Sm>
<Sm Enable="1" StartAddress="#x1200" ControlByte="#x64"
MaxSize="100">Outputs</Sm>
<Sm Enable="1" StartAddress="#x1400" ControlByte="#x20"
MaxSize="100">Inputs</Sm>

1
2
3
4
5
6
7
8
ec_sync_info_t slave_0_syncs[] = {
{0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE}, // SM0: 邮箱输出
{1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE}, // SM1: 邮箱输入
{2, EC_DIR_OUTPUT, 1, slave_0_pdos + 0, EC_WD_ENABLE}, // SM2: PDO输出 (RxPDO)
{3, EC_DIR_INPUT, 1, slave_0_pdos + 1, EC_WD_DISABLE}, // SM3: PDO输入 (TxPDO)
{0xff} // 终止符
};

XML 字段 IgH 参数
Sm 顺序 sync_index (0,1,2,3)
ControlByte 位 2 (0x04) 方向 (Output/Input)
Enable 是否启用 SM,通常 1
PdoCount & <Pdo> n_pdos + ec_pdo_info_t 指针
<Watchdog> (若有) EC_WD_ENABLE/EC_WD_DISABLE

某些厂商会提供 SM4/SM5(如附加诊断 PDO),需按 XML 顺序追加;若 ControlByte 显示与默认不同,请保持一致。

对应关系:

  • SM0/SM1: 邮箱通信 (CoE, SDO)
  • SM2: RxPDO (主站 → 从站数据)
  • SM3: TxPDO (从站 → 主站数据)

5. 从 XML 到 C 代码的映射流程

  1. 定位设备:在 XML 中搜索 <Type> 名称或 ProductCode。
  2. 抄写 ID:记录 <Vendor>/<Id>ProductCodeRevisionNo
  3. 整理 PDO
    • 分别列出 <RxPdo><TxPdo>
    • 逐条摘取 Entry (Index/SubIndex/BitLen/Name)。
    • 计算累计位宽,确认 8-bit 对齐。
  4. 生成数组
    • ec_pdo_entry_info_t:按顺序填入所有 Entry。
    • ec_pdo_info_t:每个 PDO 记录索引、条目数、entries 起始指针。
  5. 配置 SM:按照 <Sm> 顺序创建 ec_sync_info_t
  6. 注册 Domain:为需要读写的 Entry 填写 ec_pdo_entry_reg_t,获取偏移量。
  7. 验证:与 ethercat cstruct -p 输出或 ethercat pdos -p 结果对比,确保一致。

5.1. 设备识别信息

1
2
3
4
<Vendor>
<Id>17185</Id> ← Vendor ID (0x4321)
</Vendor>
<Type ProductCode="#xE2" RevisionNo="1"> ← Product Code & Revision

用途: 用于在程序中识别和配置从站设备


5.2. PDO 映射信息 (最重要!)

RxPDO - 控制命令
1
2
3
4
5
6
7
8
9
<RxPdo>
<Index>#x1600</Index> ← PDO映射索引
<Entry>
<Index>#x6040</Index> ← 对象字典索引
<SubIndex>0</SubIndex> ← 子索引
<BitLen>16</BitLen> ← 数据长度(位)
<DataType>UINT</DataType> ← 数据类型
</Entry>
</RxPdo>

提取内容:

  • PDO 索引 (0x1600, 0x1601…)
  • 每个 Entry 的对象索引、子索引、位长度
  • 数据类型(用于正确读写)
TxPDO - 状态反馈
1
2
3
4
5
6
7
8
<TxPdo>
<Index>#x1a00</Index> ← PDO映射索引
<Entry>
<Index>#x6041</Index> ← 状态字
<Index>#x6064</Index> ← 实际位置
<!-- 等等 -->
</Entry>
</TxPdo>

5.3. 对象字典详细信息

在 XML 的 <Dictionary> 部分可以找到每个对象的详细说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<Object>
<Index>#x6040</Index>
<Name>Control word</Name>
<Type>UINT</Type>
<BitSize>16</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Entry>
<Index>#x6040</Index>
<SubIndex>0</SubIndex>
<BitLen>16</BitLen>
<Name>Control word</Name>
<DataType>UINT</DataType>
<Flags>
<Access>rw</Access> ← 读写权限
<PdoMapping>r</PdoMapping> ← PDO映射方式
</Flags>
</Entry>
</Object>

重要字段说明:

  • Access: 访问权限 (ro=只读, rw=读写, wo=只写)
  • PdoMapping: PDO 映射类型 (r=RxPDO, t=TxPDO)
  • DefaultValue: 默认值
  • MinValue/MaxValue: 取值范围

5.4. 支持的运行模式

1
2
3
4
5
6
7
8
9
<Entry>
<Index>#x6060</Index>
<Name>Modes of operation</Name>
<!-- 可能的值 -->
<!-- 1: PP (Profile Position) -->
<!-- 3: PV (Profile Velocity) -->
<!-- 8: CSP (Cyclic Sync Position) -->
<!-- 9: CSV (Cyclic Sync Velocity) -->
</Entry>

5.5. 编码器参数

1
2
3
4
5
6
7
<Object>
<Index>#x608F</Index>
<Name>Position encoder resolution</Name>
<SubIndex>1</SubIndex>
<Name>Encoder increments</Name>
<!-- 用于了解编码器分辨率 -->
</Object>

用途: 确定 MOTOR_ENCODER_BITS 的值


5.6. 速度和加速度限制

1
2
3
4
5
6
7
8
9
10
11
<Object>
<Index>#x6080</Index>
<Name>Max motor speed</Name>
<DataType>UDINT</DataType>
</Object>

<Object>
<Index>#x60C5</Index>
<Name>Max acceleration</Name>
<DataType>UDINT</DataType>
</Object>

用途: 设置合理的控制参数上限


5.7. 分布时钟配置

1
2
<Fmmu Sm="2">Outputs</Fmmu>
<Fmmu Sm="3">Inputs</Fmmu>

用途: 了解哪些 SM 支持分布时钟


5.8. 错误代码定义

1
2
3
4
5
<Object>
<Index>#x603F</Index>
<Name>Error code</Name>
<!-- 可能还有错误码含义的枚举 -->
</Object>

5.9. 数字 I/O 配置

1
2
3
4
5
<Entry>
<Index>#x60FD</Index>
<Name>Digital inputs</Name>
<BitLen>32</BitLen>
</Entry>

5.10 单位转换信息

1
2
3
4
<Object>
<Index>#x6089</Index>
<Name>Position notation index</Name>
</Object>

6、如何从 XML 生成 ec_slave_config.h

方法 1: 手动提取 (当前方法)

步骤:

  1. 打开 XML 文件
  2. 找到 <RxPdo><TxPdo> 部分
  3. 提取每个 <Entry> 的索引和位长度
  4. 按照 IgH EtherCAT Master 的格式编写 C 代码

优点: 精确控制,只包含需要的对象
缺点: 繁琐,容易出错


方法 2: 使用 ethercat 命令行工具

IgH EtherCAT Master 提供了自动工具:

1
2
3
4
5
6
7
8
9
# 1. 从实际硬件读取配置
ethercat cstruct -p 0

# 输出类似:
# ec_pdo_entry_info_t slave_0_pdo_entries[] = {
# {0x6040, 0x00, 16},
# {0x607a, 0x00, 32},
# ...
# };

优点: 自动生成,快速准确
缺点: 需要硬件连接


方法 3: 使用 TwinCAT/CODESYS 工具

使用图形化工具:

  1. 导入 XML 文件到 TwinCAT
  2. 配置 PDO 映射
  3. 导出为 C 代码或使用工具生成

7、XML 中的核心对象字典 (CiA 402)

常用对象索引对照表

索引 名称 类型 访问 说明
通信控制
0x6040 Controlword UINT16 RW 控制字
0x6041 Statusword UINT16 RO 状态字
0x603F Error Code UINT16 RO 错误代码
运行模式
0x6060 Modes of Operation INT8 RW 运行模式设置
0x6061 Modes Display INT8 RO 运行模式显示
位置控制
0x607A Target Position INT32 RW 目标位置 (PP/CSP)
0x6064 Position Actual INT32 RO 实际位置
0x60F4 Position Error INT32 RO 位置误差
速度控制
0x60FF Target Velocity INT32 RW 目标速度 (PV/CSV)
0x606C Velocity Actual INT32 RO 实际速度
转矩控制
0x6071 Target Torque INT16 RW 目标转矩
0x6077 Torque Actual INT16 RO 实际转矩
限制参数
0x6080 Max Motor Speed UINT32 RW 最大速度
0x607F Max Profile Velocity UINT32 RW 轮廓最大速度
0x60C5 Max Acceleration UINT32 RW 最大加速度
探针功能
0x60B8 Touch Probe Function UINT16 RW 探针功能
0x60B9 Touch Probe Status UINT16 RO 探针状态
0x60BA Touch Probe Pos1 INT32 RO 探针位置 1
数字 I/O
0x60FD Digital Inputs UINT32 RO 数字输入
0x60FE Digital Outputs UINT32 RW 数字输出

8、实际应用示例

示例 1: 添加速度反馈到 PDO

步骤 1: 在 XML 中查找

1
2
3
4
5
6
7
<!-- 在 <Dictionary> 中搜索 -->
<Object>
<Index>#x606C</Index>
<Name>Velocity actual value</Name>
<Type>DINT</Type>
<BitSize>32</BitSize>
</Object>

步骤 2: 检查是否可以映射到 PDO

查找 <Flags> 部分:

1
2
3
4
<Flags>
<Access>ro</Access>
<PdoMapping>t</PdoMapping> ← "t" 表示可以映射到 TxPDO
</Flags>

步骤 3: 添加到 ec_slave_config.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ec_pdo_entry_info_t slave_0_pdo_entries[] = {
// ... 现有入口

// 添加速度反馈
{0x606C, 0x00, 32}, // Velocity actual value
};

// 更新 PDO 配置
ec_pdo_info_t slave_0_pdos[] = {
{0x1600, 3, slave_0_pdo_entries + 0},
{0x1a00, 8, slave_0_pdo_entries + 3}, // 从7改为8
};

// 添加到偏移结构
typedef struct {
// ... 现有字段
unsigned int velocity_actual_value; // 新增
} EC_SERVO_offset;

// 添加到注册表
static ec_pdo_entry_reg_t domain0_regs[] = {
// ... 现有注册
{POS_SERVO_0, EC_SERVO_DEVICE, 0x606C, 0, &offsetOfEC_SERVO_0.velocity_actual_value},
{}
};

示例 2: 修改为速度控制模式

步骤 1: 在 XML 中找到速度模式的 PDO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<RxPdo Fixed="0">
<Index>#x1601</Index>
<Name>Receive PDO 2</Name>
<Entry>
<Index>#x6040</Index> <!-- 控制字 -->
...
</Entry>
<Entry>
<Index>#x60ff</Index> <!-- 目标速度 -->
<SubIndex>0</SubIndex>
<BitLen>32</BitLen>
<Name>Target velocity</Name>
<DataType>DINT</DataType>
</Entry>
<Entry>
<Index>#x6060</Index> <!-- 运行模式 -->
...
</Entry>
</RxPdo>

步骤 2: 修改 ec_slave_config.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ec_pdo_entry_info_t slave_0_pdo_entries[] = {
// RxPDO - 速度模式
{0x6040, 0x00, 16}, // 控制字
{0x60ff, 0x00, 32}, // 目标速度 (替换目标位置)
{0x6060, 0x00, 8}, // 运行模式

// TxPDO
{0x6041, 0x00, 16}, // 状态字
{0x606C, 0x00, 32}, // 实际速度 (替换实际位置)
// ...
};

// 更新 PDO 映射索引
ec_pdo_info_t slave_0_pdos[] = {
{0x1601, 3, slave_0_pdo_entries + 0}, // 使用 0x1601 而非 0x1600
{0x1a01, 2, slave_0_pdo_entries + 3},
};

9. 常见问题排障

Q1: XML 中有多个 RxPDO/TxPDO,用哪个?

A:

  • 不同的 PDO 对应不同的运行模式
  • 0x1600/0x1a00: 通常是位置模式 (CSP/PP)
  • 0x1601/0x1a01: 通常是速度模式 (CSV/PV)
  • 0x1602/0x1a02: 可能是转矩模式 (CST)

选择方法: 根据你的应用需求选择


Q2: ec_slave_config.h 中的 PDO 数量和 XML 不一致?

A:

  • 这是正常的
  • XML 列出了所有可能的 PDO 入口
  • C 代码中只需要包含实际使用的入口
  • 可以减少通信数据量,提高效率

Q3: 如何验证配置是否正确?

A: 使用 ethercat 命令行工具:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 查看 PDO 配置
ethercat pdos -p 0

# 输出应该与你的配置匹配:
# SM2: RxPdo
# PDO 0x1600
# 0x6040:00, 16 bit
# 0x607a:00, 32 bit
# SM3: TxPdo
# PDO 0x1a00
# 0x6041:00, 16 bit
# 0x6064:00, 32 bit

# 2. 实时监控 PDO 数据
ethercat pdos -v -p 0

Q4: XML 中没有找到某个对象?

A:

  1. 使用 XML 编辑器搜索索引 (如 0x6040)
  2. 检查 <Dictionary> 部分
  3. 某些对象可能通过 SDO 访问,不在 PDO 中
  4. 查阅驱动器手册确认是否支持

Q5: 如何添加 SDO 配置参数?

A: SDO 不在 PDO 中,需要在初始化时配置:

1
2
3
// 在 main() 函数的初始化部分
uint8_t mode = 8; // CSP 模式
ecrt_master_sdo_download(master, 0, 0x6060, 0, &mode, sizeof(mode), NULL);

或在 XML 中查看 <InitCmd> 部分的示例。


现象 可能原因 检查命令/方法 解决建议
Failed to configure slave: vendor/product mismatch ID/产品码写错(十进制/十六进制混淆) ethercat slaves、XML 对照 printf("0x%08X\n", vendor) 验证;注意大小写和填充
PDO entry size mismatch BitLen 与代码类型不符、指针偏移错 ethercat pdosdmesg 逐条核对 BitLen,确保 n_entries 正确;重新生成数组
SM watchdog 报警 EC_WD_ENABLE 配置不当或任务周期过长 dmesg、驱动面板 若应用未实现看门狗,设置 EC_WD_DISABLE 或在周期任务内喂狗
Config PDO failed XML 中的 PDO 被厂商锁定 (Fixed=1) 或不支持重映射 ethercat pdos 查看 Fixed 标志 若 Fixed=1,必须按厂家默认映射使用;考虑通过 SDO 启用可编程映射
数据错位/值异常 Domain 注册顺序与写入顺序不匹配、大小端问题 打印 offset 值、Wireshark 抓包 确保读写宏与 BitLen/符号匹配,必要时在代码中添加 static_assert
设备无法进入 OP SM/ PDO 未全部配置或 DC 设置错误 ethercat diag -pdmesg 先禁用 DC,确认 PDO 映射与 SM 对应正确,再逐项恢复

通过以上步骤,便可将任意厂商的 ESI XML 转换为主站可用的 C 结构体,并借助工具快速验证和排错。如需自动化,可进一步编写脚本解析 XML 并生成 ec_pdo_entry_info_t/ec_sync_info_t 代码模板。

总结

XML 字典文件的作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
┌─────────────────────────────────────────┐
│ L6N_V1.08.xml │
│ (厂商提供的设备描述) │
└─────────────────┬───────────────────────┘

│ 提取信息

┌─────────────────────────────────────────┐
│ 我们需要获取的关键信息: │
│ │
│ 1. Vendor ID & Product Code (识别) │
│ 2. PDO 映射 (数据交换配置) │
│ 3. 对象字典 (参数说明) │
│ 4. 数据类型和范围 │
│ 5. 访问权限 │
│ 6. 默认值和限制 │
└─────────────────┬───────────────────────┘

│ 转换为

┌─────────────────────────────────────────┐
│ ec_slave_config.h │
│ (C代码配置文件) │
│ │
│ - ec_pdo_entry_info_t │
│ - ec_pdo_info_t │
│ - ec_sync_info_t │
│ - EC_SERVO_offset │
│ - domain_regs[] │
└─────────────────────────────────────────┘

关键要点

  1. XML 是源头: 所有配置信息的权威来源
  2. 完全对应: ec_slave_config.h 必须与 XML 一致
  3. 可以裁剪: 只包含实际需要的 PDO 入口
  4. 验证重要: 使用工具验证配置正确性