做 EtherCAT 从站开发,绕不开 LAN9252 这颗片子。芯片本身是好东西,内部集成了 EtherCAT 从站控制器的全部硬件逻辑,外部 MCU 通过 SPI 接口读写寄存器就能把整个从站撑起来。但真正让人头疼的从来不是芯片,而是配套的协议栈工程怎么收敛:SSC 工具确实能帮你生成一大半代码,可剩下的对象字典、PDO 映射、同步管理参数,依然是一堆让人头皮发麻的表格。手动填过一次 100 点以上的 IO 映射之后,我彻底倒向了“用 Excel 批量生成 XML”这条路。
这篇文章就是我实际项目里踩了一轮坑之后沉淀下来的完整做法。主要围绕三件事展开:一是为什么用 SSC 工具搭 LAN9252 从站工程,二是如何用 Excel 把 IO 映射表批量转成可被 SSC 解析的 XML,三是在整个链路里最容易翻车的 XML 编码、对象字典、Sync Manager、FMMU 这些细节。适合正在做 EtherCAT 从站开发、被 0x6000/0x1A00/0x1600 这些地址绕晕的工程师参考,也适合想从主站侧反向理解 PDO 映射的入门读者。
1. 为什么我要用Excel来配LAN9252的IO映射
1.1 LAN9252从站开发的基本路径
LAN9252 在 EtherCAT 从站里的角色很明确:它不跑应用逻辑,只负责处理 EtherCAT 通信帧。主站发过来的报文在芯片内部经过 FMMU 单元完成逻辑地址到本地物理地址的映射,数据落到过程数据 RAM 里,外部 MCU 再通过 SPI 或 SQI 接口把这些数据读走,同时把自己采集的 IO 状态写回 RAM,由芯片拼装成回程帧发给主站。
所以开发一套完整的从站,硬件设计只是一部分,更重的是软件协议栈。实际开发路径一般是下面几步:
- 用 SSC 工具(Slave Stack Code,官方从站协议栈代码生成工具)选择 LAN9252 和对应的 MCU 型号,比如 STM32F405、AT32F435 等,生成初始工程。
- 在 SSC 的图形化界面里配置对象字典、PDO 映射、邮箱通信(CoE/SoE)、分布式时钟 DC、同步管理器 SM 和 FMMU 数量。
- 把生成的协议栈代码移植到自己的 IDE 工程里,和应用逻辑一起编译。
- 写入 LAN9252 外挂的 EEPROM,配置厂商 ID、产品码、SII 信息等。
- 用主站(TwinCAT、IGH、汇川 PLC 等)扫描总线,验证从站能否正常进入 OP 状态。
这个流程里,第 2 步是最繁琐也是最容易出错的。因为 SSC 的界面虽然友好,但每一个 PDO 映射项都要手动添加,IO 一多,工作量立刻上来。而且这些配置最终会序列化到 ESI XML 文件里,如果主站加载这个文件时解析失败,整个从站连扫描都过不去。
1.2 手工填PDO映射的切肤之痛
简单场景:项目需要 16 路数字输入、16 路数字输出、8 路模拟输入和 4 路模拟输出。按常规设计,数字量可以打包成两个对象,模拟量每个通道单独一个子索引。这时候你至少需要维护:
- 4 个输入对象(数字输入包、模拟输入通道组等),对应 0x6000 系列;
- 3 个输出对象,对应 0x7000 或 0x6800 系列;
- 至少 2 个 PDO(RxPDO 和 TxPDO),每个 PDO 里塞若干映射项;
- 每个映射项要写对象索引、子索引、数据长度三个字段。
SSC 工具里点开 PDO Mapping 页面,看到的是一行行空白表格,Add 一个,选索引,选手子索引,选 bit 长度,保存,再 Add 下一个。几十个映射项填下来,眼睛都花了。更别提中途甲方改需求,把模拟量通道数量从 8 路改成 12 路,你又得重新返工一遍。
这种机械重复操作有几个隐藏风险。一个是人工填错,比如子索引写重复了、bit 长度和实际数据类型对不上。另一个是修改之后,SSC 界面里的对象字典、PDO 映射、SM 缓存三方数据不一致,最后导出的 XML 文件带着“内伤”,主站解析时不会告诉你哪里逻辑不对,只会给一个冷冰冰的“PDO configuration invalid”。
我当时的第一反应是:能不能像写配置表一样,把 IO 映射需求整理成一张 Excel 表格,由程序自动生成 XML 片段?试了几天之后,这套流程被彻底固定下来了,效果非常稳。说白了,手工填 PDO 映射就像搬家时一件一件搬箱子,又累又容易漏;Excel 批量生成相当于提前盘点货物、写好装箱清单,再统一打包发货,效率和准确率都高一个量级。
2. 方案整体设计:SSC出代码,Excel出XML
2.1 方案分工:谁负责干什么
整套方案里,三个工具各有分工,谁也不替代谁:
- SSC 工具负责生成协议栈代码、校验配置、维护工程结构。它是从站软件的主心骨,所有 EtherCAT 协议相关代码都从这里产出。
- Excel负责把 IO 映射关系表格化、批量化。它不直接生成可运行的代码,但它生成的 XML 片段是 SSC 工程和主站识别从站能力的中间介质。
- XML 文件(ESI 文件)是数据和配置的载体。Excel 表格最终要转成规范的 XML 节点,SSC 导入这个 XML 时才能正确重建对象字典和 PDO。主站软件读的也是这份 XML。
用这么一套组合,核心逻辑在于:把“密集的、结构化的重复数据”交给表格工具,把“语法和语义校验”交给 SSC,把“协议解析”交给主站。每个环节只做自己最擅长的事。
需要注意的是,SSC 工具本身也提供对象字典的导入导出功能,很多工程师直接用文本编辑器改 XML,改完再导回 SSC。这个方法不是不行,但纯手工在 XML 里定位标签、写索引,非常容易出结构性问题。Excel 至少能利用筛选、排序、条件格式把数据整理得明明白白,改起来有据可循。
2.2 ESI XML是什么,为什么总在这里卡住
ESI(EtherCAT Slave Information)文件是从站对主站的“自我介绍”。主站软件扫描到从站后,第一件事就是根据 EEPROM 里的厂商 ID、产品码、产品版本,去本地配置目录里找对应的 ESI 文件。如果匹配上了,就按照里面的对象字典和 PDO 定义去建立过程数据映射;匹配不上或文件解析失败,从站直接显示“Unknown Device”。
ESI XML 文件里承载的内容大致包括:
- 设备信息:厂商名、设备名、版本、Group 等;
- 对象字典定义:从 0x1000 到 0xFFFF 的所有 CoE 对象;
- PDO 映射定义:RxPDO(主站到从站)和 TxPDO(从站到主站)的映射条目;
- 同步管理器和 FMMU 相关配置;
- DC 分布式时钟能力和参数;EtherCAT 主站解析 XML 的时候,要求文件必须同时满足三个层面的要求:
- 语法层面:well-formed,标签配对正确,不能有非法字符,编码必须是主站能识别的格式。
- 结构层面:节点顺序和 schema 定义一致,Index、SubIndex、数据类型这些属性的取值有严格约束。
- 语义层面:PDO 映射项指向的对象必须真实存在于对象字典里,数据类型和 bit 长度要匹配,Sync Manager 的配置要和 PDO 方向吻合。
前两个问题比较容易被发现,因为 XML 解析器在加载阶段就会报错。最坑的是第三个层面,语法和结构都合法,但逻辑矛盾,主站加载后不会拒绝解析,而是在运行阶段表现异常,比如数据错位、无法进入 OP 状态、看门狗超时。这也是为什么后来我把注意力重点放在语义一致性的检查上。
2.3 Excel表格如何设计映射表
既然要用 Excel 做数据源,表格设计就得提前规划好。我常用的工作表结构如下:
| 列 | 字段 | 示例 | 说明 |
|---|---|---|---|
| A | 方向 | Input | Input 表示主站到从站,Output 表示从站到主站 |
| B | 对象索引 | 0x6000 | 对象字典索引,用四位十六进制表示 |
| C | 子索引 | 01 | 对象的子索引,00 一般作为计数或保留 |
| D | 数据名称 | DI_Channel_01 | 信号用途,方便写注释 |
| E | 数据类型 | BOOL | 决定 bit 长度,BOOL 对应 8bit |
| F | Bit长度 | 8 | 映射项占用长度,必须和数据类型匹配 |
| G | 所属PDO | RxPDO_1 | 这条映射项挂在哪个 PDO 下 |
| H | 备注 | 接按钮输入 | 附加说明 |
这样一个表的好处是,所有映射关系一目了然,后期要加通道,直接复制几行改编号即可。顺便说一句,如果数据是从别的系统复制过来的,Excel 经常会把数字识别成文本格式,单元格左上方出现绿色的小三角。这种看起来不影响显示,但后面用 DEC2HEX、VLOOKUP 这类函数时,结果完全不对。处理办法是选中整列后点击感叹号按钮,选择“转换为数字”,或者用 N() 函数包一层。这个细节必须留意,否则后面生成的 XML 索引全是错的。
3. 实操:从Excel表格到可用的从站工程
3.1 第一步:把IO分配表用Excel整理规整
假设项目需求是 16 路 DI、16 路 DO、8 路 AI(12bit 精度,按 16bit 存储)、4 路 AO。我一般把数字量和模拟量分开规划对象字典:
- 数字输入统一放在 0x6000 对象下,子索引 0x01~0x10 对应 16 路;
- 数字输出统一放在 0x7000 对象下,子索引 0x01~0x10 对应 16 路;
- 模拟输入从 0x6400 开始,每个通道一个子索引;
- 模拟输出从 0x6800 开始,每个通道一个子索引。
在 Excel 里录入时,方向列和所属 PDO 列要提前填好。比如 0x6000 和 0x6400 都是 Input,挂在 TxPDO_1 下;0x7000 和 0x6800 是 Output,挂在 RxPDO_1 下。这样后面自动生成 XML 时,可以通过筛选分块处理,避免一条条去改。
我习惯在表的最右边增加一个辅助列,用公式拼出每个映射项对应的 XML 注释,方便最后核对。比如:
="<Comment>"&D2&"</Comment>"这样生成 XML 的时候,注释也一并带出来,调试时能直接看懂每一段映射对应的是什么信号。
3.2 第二步:用公式批量合成XML节点
把映射表填好之后,最关键的操作来了:用 Excel 公式把每一行数据拼成 XML 节点。列 B 是“对象索引”,列 C 是“子索引”,列 F 是“Bit长度”,列 G 是“所属PDO”。我在第 J 列写一个拼接公式:
="<PDO Index=""0x"&DEC2HEX(GA,4)&""" />"不过,更常用的是直接生成 PDO 映射项的完整 XML 块。把 PDO 的 Index、映射条目的 Index、SubIndex、BitLen 都拼出来:
="<MappedEntry><Index>0x"&TEXT(B2,"0000")&"</Index><SubIndex>0x"&DEC2HEX(C2,2)&"</SubIndex><BitLen>"&F2&"</BitLen></MappedEntry>"这里有两个细节容易被坑。第一,Excel 里DEC2HEX函数要求参数不能大于 549755813887,但对象索引一般都在 0xFFFF 以内,所以没问题;第二,TEXT(B2,"0000")会把数字格式化成四位数文字,但如果 B2 本身就是文本类型且已经显示成十六进制,再套函数反而出错。所以前面说“把数据转换为真数字”真的很关键。
公式写好后,直接往下拖,几十行映射条目几秒钟就出来了。然后把“所属 PDO”分组筛选,把每个 PDO 下的映射节点单独复制到文本编辑器里,准备嵌入完整的 ESI 文件。
如果项目更大,几百个 IO,公式法依然可行,只是后缀校验容易看漏。这种情况下可以写一段简单的 VBA 宏,循环遍历每一行,拼接字符串并写入 txt 文件。逻辑不复杂,但一次成型,效率和可靠性更高。代码大致如下:
Sub GenerateXmlNodes() Dim i As Long Open "C:\Temp\pdos.txt" For Output As #1 For i = 2 To Range("A" & Rows.Count).End(xlUp).Row Print #1, "<MappedEntry><Index>0x" & Format(Cells(i, 2), "0000") & _ "</Index><SubIndex>0x" & Format(Cells(i, 3), "00") & _ "</SubIndex><BitLen>" & Cells(i, 6) & "</BitLen></MappedEntry>" Next i Close #1 End Sub宏生成的只是映射条目,PDO 的外层结构和对象字典定义还是需要嵌到 ESI 文件里。别指望 Excel 能生成完整的 ESI,它没那个上下文。
3.3 第三步:把XML喂给SSC工具并生成工程
SSC 工具创建工程时,可以直接“Load ESI File”来导入已有的从站信息文件。我的操作顺序一般是:
- 先让 SSC 基于 LAN9252 和当前 MCU 生成一个空白模板工程。
- 用 File -> Save 把模板工程里默认的 ESI XML 导出来。
- 用记事本或 Notepad++ 打开这个 XML,找到
DictionaryList区域,在对象字典末尾追加我需要的 0x6000、0x7000、0x6400、0x6800 对象定义。 - 再找到 RxPDO 和 TxPDO 分布定义的地方,把 Excel 生成的 MappedEntry 节点逐个插入对应 PDO 下面。
- 保存 XML 文件,回到 SSC,用 Load ESI File 重新导入。
- 如果导入成功,对象字典页面和 PDO 映射页面会自动显示我加的内容。检查一遍,确认数据没有错位。
这个过程里,SSC 工具能不能正确解析 XML 是关键。如果 XML 有问题,SSC 会在加载时报错,提示第几行第几列有异常。这时不要急着改 XML,先回到 Excel 检查数据源,把对应行的公式输出和拼好的 XML 片段对比一下,往往很快就能找到问题。
3.4 第四步:编译验证与主站对接
SSC 生成协议栈代码之后,还要把代码放到自己的工程里编译。这一步我一般会先留一个最简版的从站应用,只做初始化、状态机循环和 SPI 通信,不接入真实 IO。先把协议栈跑通,再加应用逻辑。
编译烧录完成后,用主站软件验证。如果你手头是 TwinCAT,把 ESI 文件拷贝到C:\TwinCAT\3.1\Config\Io\EtherCAT目录下,然后激活配置,扫描 I/O 设备。如果从我之前写的流程走过来,从站名字应该能正常识别,并且能开关状态机:从 INIT 到 PREOP,再到 SAFEOP,最后到 OP。如果某个环节卡住,优先检查对象字典和 PDO 是否和主站解析出来的 ESI 一致。
如果用的是 Linux 主站,比如在 RK3568 这类板子上跑 EtherCAT IGH,操作方式略有不同。IGH 主站启动后会从/opt/etherlab/etc或指定的 ESI 目录加载从站信息文件,通过ethercat slaves命令能看到从站是否被识别。最常见的问题是 ESI 文件版本和 EEPROM 里的产品版本不匹配,IGH 会直接显示版本不兼容。
4. XML解析避坑点与排查实录
4.1 编码与BOM:最隐蔽的第一坑
第一次用 Excel 配合 XML 时,我花了一晚上查“SSC 工具无法解析 XML”的问题。错误提示只有一句话:“XML parsing failed”,没有任何行号。后来用 Notepad++ 打开 XML 才发现,Excel 另存出来的文件是 UTF-8 with BOM 格式,而 SSC 工具内部的 XML 解析器要求的是 UTF-8 no BOM。BOM 是文件开头多出来的三个字节 EF BB BF,多数现代浏览器能容忍,但老旧的解析器会直接报错。
处理办法很简单:用 Notepad++ 打开文件,在“编码”菜单里选择“转为 UTF-8 编码(无 BOM)”,保存,再导入 SSC。从那以后,这套流程里所有 XML 文件我都会确认一遍编码,包括最终发给主站的 ESI 文件。如果你习惯用 VS Code,也可以直接点击右下角的编码状态栏,选择“Save with Encoding”为 UTF-8。
另外提醒一句,不要为了省事把 XML 存成 UTF-16 或其他编码。EtherCAT 社区和各大主站厂商对 ESI 文件的编码要求就是 UTF-8,别特立独行。
4.2 对象字典与PDO映射的结构性错误
第二种坑比编码隐蔽得多,属于“结构合法但语义不对”。常见的有这么几类:
- 索引冲突:用户对象定义用了 0x1400 之类的保留区,或者和厂商另作他用的对象重叠,导致映射混乱。
- 子索引 00 的含义:在 EtherCAT 对象字典里,子索引 00 经常被用作数组长度或通道数量。如果你定义了 0x6000 有 16 个子索引,但子索引 00 没设置或者设置错误,主站可能会认为这个对象是空的。
- 映射项引用的对象不存在:PDO 的 MappedEntry 里写了
<Index>0x6400</Index>,但实际上 DictionaryList 里根本没有 0x6400 这个对象,主站直接报错。 - BitLen 和数据类型不匹配:对象定义是 UINT16,PDO 映射项 BitLen 却写成了 8,这样协议栈和主站对长度的理解不一致,轻则数据截断,重则状态机进不了 OP。
这些问题如果靠眼睛去查几千行的 ESI 文件,效率极低。我的做法是在 Excel 里加两个辅助表:一个是对象字典清单,一个是 PDO 映射列表,然后用COUNTIF和VLOOKUP做交叉校验,确保每个 PDO 里引用的 Index 都在对象字典清单里,BitLen 也和数据类型一致。这套校验做完以后再生成 XML,基本能把 90% 的结构性错误提前挡在门外。
4.3 Sync Manager和FMMU配置核对
EtherCAT 从站的通信靠同步管理器(Sync Manager)和工作内存管理单元(FMMU)。SM0/SM1 一般用于邮箱通信,SM2 用于主站到从站的过程数据(RxPDO),SM3 用于从站到主站的过程数据(TxPDO)。如果 ICC 配置里 SM2 和 SM3 的通道方向搞反了,主站那边会看到数据完全对不上。
这里面有个常见的“新手必踩”点:很多人只改了 PDO 映射,忽略了 SM 配置。其实 SM 是对应 PDO 的物理通道,PDO 是逻辑描述,两者必须一致。比如我用 Excel 生成的是“输出 0x7000 挂在 RxPDO_1”,但 SSC 工程里 SM2 绑定的却是 TxPDO,这就产生了矛盾。主站加载 ESI 时,可能因为这个直接断定从站配置无效。
FMMU 则负责把主站发布的逻辑地址映射到从站本地 RAM。LAN9252 内部集成了多个 FMMU 单元,SSC 生成的工程一般会默认分配几个。但如果你把过程数据拆分成很多 PDO 组,每组都需要独立 FMMU,数量不够就会出问题。我和我同事碰到过模拟量点数比较多、把 AI 和 DI 拆成了 4 个 TxPDO 的情况,结果从站一直无法进入 OP,后台一看是 FMMU 耗尽。最后把多个 PDO 合并成一个 PDO,FMMU 数量就够用了。
所以配置完成后,务必去 SSC 的“Sync Manager”和“FMMU”页面核对两件事:SM 的方向是否和 PDO 方向一致,FMMU 数量是否满足 PDO 映射段数。
4.4 主站侧“识别不到从站”的排查清单
主站加载 ESI 失败,现象千奇百怪,有的报“Device not found”,有的是设备名能显示但无法激活,还有的是能激活但数据全乱。我把这几种常见情况整理成了一张速查表:
| 现象 | 优先检查 | 解决办法 |
|---|---|---|
| 主站扫描不到从站 | EEPROM 里的厂商 ID、产品码是否匹配 | 重新烧写 LAN9252 EEPROM,确保 SII 信息正确 |
| 从站能识别但报 ESI 版本不匹配 | ESI 文件版本号和 EEPROM 产品版本不一致 | 修改 ESI 文件的版本字段,或重新烧写匹配版本 |
| 能进 PREOP 但进不了 SAFEOP | PDO 映射项引用了不存在的对象 | 回 Excel 校验对象字典清单,重新生成映射项 |
| 能进 SAFEOP 但进不了 OP | SM 配置与 PDO 方向不一致 | 检查 SM2/SM3 方向和 FMMU 分配,重新导入 SSC |
| 数据能通但数值错位 | BitLen 和实际数据类型不匹配 | 全局检查映射表,统一数据类型定义 |
| TwinCAT 扫描时设备名显示空白 | ESI 文件保存格式异常 | 用 Notepad++ 另存为 UTF-8 无 BOM |
这个表现在被我打印出来贴在工位上,每次做新项目都要过一遍。别小看这些细节,EtherCAT 从站调试里 80% 的时间都耗在这里,尤其当你同时用汇川 PLC 做主站、又用 IGH 做验证主站的时候,两个主站对 ESI 的校验严格程度还不完全一样,经常是一边通过一边报错,最后发现是 XML 里一个无伤大雅的格式差异。
再补一个独家心得:我会在 Excel 工作簿里把“版本修订记录”作为一个隐藏 Sheet,记录每次映射表改了哪些对象、谁改的、哪天改的。项目移交和生产追溯的时候,这套记录比什么都管用。毕竟从站开发是个迭代活,不是一次配置完就一劳永逸,甲方改需求、换 IO 模块、加通信协议板,都是常态。有了清晰的配置表和历史记录,再碰上新需求,半天就能改完,不用再从头“手动填坑”了。