抖音粉丝群1
『7x24小时有问必答』

很多人学完 EtherCAT 三种寻址后,
很容易顺着往下想:

真到写代码时,是不是要把自动增量寻址、物理寻址、逻辑寻址一套一套全展开写出来?

很多项目里,
实际并不是这么做的。

真实工程里更常见的做法是:

• 启动前先把从站配置关系准备好   
• 初始化时逐站完成识别和配置   
• 运行时按过程映像统一收发 PDO   
• 底层扫描和报文细节交给主站库

所以这篇不再讲“名词怎么分”,
而是讲:

如果你真要把 EtherCAT 主站做出来,真实项目里通常会采用一种什么实现逻辑。

1.png
一句话先讲明白

这类实现的核心思路是:先把从站配置关系定下来,初始化阶段逐站精确配置,运行阶段再按逻辑过程映像整块交换数据。

这样做的好处是结构清晰、落地快、维护方便;
代价是对底层机制感知会变弱,也更依赖主站库和前期配置正确。

把这句记住,
这篇后面就都顺了。

第一,真实项目里最重要的不是命令名,而是实现怎么分层

很多人一看 EtherCAT 代码,
就先去找 APRD、FPWR、LRW 这些命令。

但真实工程里,
更该先看的是:

这类主站实现到底怎么组织。

真实项目里,常见的是这样一条路线:

• 先准备系统里有哪些从站   
• 每个从站是什么类型   
• 顺序怎么排   
• 各自对应哪个轴或哪类 IO

然后初始化时,
按这个配置逐站建对象、逐站配置。

等主站激活后,
再统一拿过程映像做周期收发。

也就是说,
这种实现路线的重点不是把三种寻址概念逐条摊给你看,
而是:

先把配置阶段和运行阶段分开。

这才是它最值得借鉴的地方。

第二,这类实现第一步,是先把从站配置关系定下来

这类项目通常不会一上来就完全盲扫。

它更像是:

我先知道系统大概要接哪些设备。

比如:

• 哪些是驱动器   
• 哪些是 IO 模块   
• 每个设备顺序是什么   
• 每个设备对应哪个轴   
• 设备厂家和产品类型大概是什么

这样做的意义很大。

因为后面初始化时,
主站就不是一边扫一边临时做决策,
而是按已有配置往下走。

这会让整个系统结构更稳定。

尤其在机器人、运动控制、产线设备这类场景里,
现场拓扑通常不是天天变。

这时候,
先把配置关系定下来,
再进入初始化,
是非常常见的工程做法。

你可以把这一步理解成:

先把系统视图建立起来。

这一步解决的,
还不是通信效率问题,
而是系统组织问题。

第三,这类实现第二步,是初始化时逐站去配置设备

配置关系有了以后,
主站初始化就开始逐站展开。

这一阶段做的事情通常包括:

• 建立从站配置对象   
• 识别产品码   
• 按设备类型决定 PDO 结构   
• 注册 PDO entry   
• 配 SDO 参数   
• 配 DC 同步参数

这一步的核心特征很明确:

它是面向单个从站的。

也就是说,
主站在这里关心的是:

我现在要把这一台设备配好。

而不是:

我现在要把整条链的数据一次搬完。

所以这一阶段最适合的思路就是:

逐站处理。

这样做有几个明显好处。

第一,结构清楚。

不同厂家驱动器、不同 IO 模块,
都可以各配各的。

第二,问题好查。

哪台从站产品码不对,
哪个设备 PDO 不匹配,
哪个从站 SDO 写失败,
都容易定位。

第三,符合工程现场思维。

现场排查问题时,
本来也是按“哪台设备有问题”去查,
不是按抽象协议层去查。

所以这一步非常实用。

第四,这类实现第三步,是运行时统一按过程映像跑数据

如果说初始化阶段是在“配设备”,
那正式运行以后,
重点就变成了:

跑数据。

这类实现在这一点上很典型。

它没有在周期线程里继续大量做逐站访问,
而是先把需要周期交换的数据,
按方向整理进独立的输出域和输入域。

你也可以把它们理解成两块不同方向的过程映像。

输出过程映像(Output Process Image)

放的是主站这一周期准备下发给各个从站的数据,
比如控制字、目标位置、IO 输出。

输入过程映像(Input Process Image)

放的是各个从站这一周期返回给主站的数据,
比如状态字、实际位置、编码器反馈、IO 输入。

一旦进入周期运行,
不少主站实现会把这两块过程映像和从站 PDO 的映射关系固定下来。

对上层看,
它们像两块连续内存;
对底层看,
它们已经对应到具体从站的具体 PDO 偏移。

为了避免一轮里读到前后不一致的数据,
很多系统会在收发边界做同步保护,
常见做法是底层临界区或双缓冲。

目的很简单:

尽量让这一轮输入对应同一个采样窗口,这一轮输出对应同一个生效时刻。

这也是为什么过程映像不是普通全局变量,
而是一种按周期、成批量交换数据的机制。

这样整理以后,
周期线程里做的事情就很直接:

• 往输出过程映像写控制量   
• 发出一轮 EtherCAT 周期数据   
• 收回一轮 EtherCAT 周期数据   
• 再从输入过程映像读反馈量

这其实就是 EtherCAT 最适合工程使用的方式。

因为一旦进入周期运行阶段,
主站关心的就不再是:

“我要单独访问 3 号站哪个寄存器。”

而是:

这一轮输出过程映像发出去没有,输入过程映像收回来没有。

这就是为什么很多 EtherCAT 工程代码看起来更像“内存读写”。

因为从应用层看,
它确实已经被收敛成过程映像操作了。

所以这类实现最该学的一点就是:

配置阶段按设备思考,运行阶段按数据思考。

这句话非常重要。

很多人代码越写越乱,
本质上就是没把这两层分开。

第五,这种实现方式为什么好用?

第一个好处,

是结构清楚。

配置就是配置,
运行就是运行。

设备初始化逻辑和周期收发逻辑不会搅在一起。

第二个好处,

是维护方便。

后面你要换驱动器、改 PDO 映射、加设备参数,
通常都能在初始化层改,
不容易把周期线程搞乱。

第三个好处,

是排错更顺。

初始化出问题,
大概率看从站识别、PDO、SDO、DC。

运行期出问题,
大概率看过程映像、周期线程、同步和反馈。

层次很清楚。

第四个好处,
是实时性更容易做好。

因为周期线程里做的事比较瘦:

收发、读写过程映像、更新业务变量。

不容易塞进太多杂事。

这对运动控制系统特别重要。

第五个好处,

是适合借助成熟主站库。

很多项目并不想自己从零实现底层 EtherCAT 报文调度。

它们更现实的选择是:

底层交给主站库,工程重点放在设备配置和业务流程。

很多成熟项目,走的就是这种思路。

你也可以把这种方式理解成:

主站和从站之间摆了两块黑板。

主站把目标值写进输出黑板,
下一轮再从输入黑板读回反馈。

这种模式实时性很高,
代码也干净,
但它天然意味着数据不是“写完立刻就看到最终反馈”。

第六,这种实现方式的缺点也得说清楚

第一个缺点,

是对底层机制感知会变弱。

因为很多扫描、报文组织、状态推进细节,
都被主站库封装掉了。

平时开发可能没问题,
但到了抓包、兼容性、疑难现场问题时,
如果底层理解不够,
就会吃亏。

第二个缺点,

是灵活性受主站库限制。

主站库怎么组织对象、
怎么注册 PDO、
怎么处理 SDO、
怎么管理过程域,
你很多时候得跟着它走。

开发效率更高,
但掌控力会弱一点。

第三个缺点,

是很依赖前期配置正确。

这种实现方式的前提是:

从站关系、设备类型、PDO 映射这些东西,
前面得先理顺。

如果配置表和现场实际不一致,
初始化阶段就容易反复出问题。

第四个缺点,

是容易让新手把配置期和运行期混起来。

表面上看都是在调 EtherCAT API,
但本质上做的不是一回事。

如果这两层分不清,
系统一复杂,
代码还是会乱。

第五个缺点,

是过程映像这层通常会带来周期级延迟感。

因为应用层看到的,
往往不是“刚写下去立刻返回”的数据,
而是上一轮或当前收发边界整理好的输入输出快照。

所以在高动态场景下,
你会明显感觉到:

PI 很像缓存黑板,而不是寄存器直通。

具体是 1 个周期还是 2 个周期,
要看主站实现、缓存策略、线程节拍和同步方式。

这类系统一旦要追极限动态性能,
这一层就得专门调。

再给一个最常见的反面教材。

新手写法(周期线程里)
for  each slave:       read_register(0x6040);       write_register(0x607A);
这种写法的问题不是“语法不对”,
而是它把周期线程又写回了逐站、逐寄存器访问的思路。

更稳的写法(周期线程里)
ecrt_master_receive(master);ecrt_domain_process(domain);/* 应用层只读写 PI */
也就是说,

周期线程尽量做整块收发,应用层尽量只围着 PI 读写。

所以这种方式虽然好用,
前提是你得守住分层。

第七,如果你以后自己做 EtherCAT 主站,这类实现最值得学什么?

最值得学的不是某个具体 API,
而是这条实现路线。

第一步,先建立设备配置视图。

先把设备类型、顺序、轴对应关系、PDO 需求理清楚。

第二步,初始化阶段逐站完成识别和配置。

包括建从站对象、识别产品、配 PDO、配 SDO、配 DC。

第三步,把运行期需要的数据统一收敛到过程映像。

不要让周期线程里到处散着单站访问逻辑。

这里尤其要注意:

输出过程映像负责“主站发什么”,输入过程映像负责“从站回什么”。

这两个方向一旦分清,
运行期代码会清楚很多。

第四步,周期线程只做收发、读写过程映像和必要的通信侧更新。

成熟一点的架构里,
周期线程负责的是:

• PI 和总线之间的数据交换   
• 触发这一轮周期通信   
• 把最新输入快照交给上层

而更上面的应用层,
再去做这些事:

• 根据控制算法算目标位置、目标速度   
• 把结果写进 Output PI   
• 从 Input PI 读反馈后更新状态机、日志、界面

也就是说:

通信线程尽量只管 PI,业务逻辑尽量放在应用层。

让实时线程尽量瘦。

第五步,把诊断、参数修改、低频配置动作尽量和周期线程分开。

别把所有事情都塞进实时循环。

如果你按这个思路去做,
系统通常会清楚很多。

第八,如果你只看这一篇,请记住这三句话

如果前面细节你没有全跟住,
至少把这三句带走:

• 配置期按设备配,运行期按数据跑   
• Output PI 是下发黑板,Input PI 是回收黑板   
• 实时线程只碰 PI,业务逻辑别挤进来

这三句一旦立住,
你后面再去看主站初始化、过程映像、周期线程和应用层分工,
就不容易乱。

最后怎么一句话记住?

EtherCAT 主站精髓:先按设备逐站配置,再依托过程映像(PI)做周期流转。输出 PI 负责下发,输入 PI 负责回传。架构清晰稳定,但较依赖主站库与前期配置。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码