SDO 和 PDO 到底有什么区别?从 IgH 看 EtherCAT 配置数据与实时数据
在 EtherCAT 开发中有两个概念几乎绕不开SDO 和 PDO。很多刚接触 EtherCAT 的开发者第一反应是PDO 是过程数据SDO 是参数数据。这个理解不能说错但如果只停留在这里真正进入 IgH EtherCAT Master 源码和工业现场之后很快就会遇到更多问题为什么设备初始化时要通过 SDO 写参数为什么伺服运行之后又主要依赖 PDO为什么修改一个对象字典参数时可以使用ecrt_master_sdo_download()或相关 SDO 接口而控制周期里却不能把所有数据都通过 SDO 读写为什么 PDO 也能通过对象字典中的对象进行配置为什么一个设备明明支持某个对象通过 SDO 可以访问但是应用程序却无法直接从 PDO 中读取这些问题的根源在于SDO 和 PDO 并不是简单的“两种数据格式”而是 EtherCAT 中两种完全不同的数据交换机制。如果把 EtherCAT 从站理解成一台工业设备那么 Object Dictionary 可以看成设备内部的参数和状态数据库Object Dictionary │ ├── 设备参数 ├── 配置参数 ├── 状态信息 ├── 控制参数 ├── 诊断信息 ├── PDO Mapping └── 其他对象SDO 更像是“我要访问对象字典里的某个对象。”而 PDO 更像是“我已经确定这些数据需要周期性交换 请把它们组织成过程数据每个控制周期直接交换。”这两种机制看起来都在传输数据但它们承担的任务完全不同。对于使用 IgH EtherCAT Master 的 Linux 工业控制系统而言这个区别尤其重要。因为一个完整的 EtherCAT 控制系统通常不是简单地启动 → 发送 PDO → 控制而是设备识别 ↓ 设备配置 ↓ SDO 参数访问 ↓ PDO Mapping / Assignment ↓ Master 激活 ↓ PDO 周期通信 ↓ 控制算法也就是说SDO 更多承担“把设备配置好”的任务PDO 更多承担“让设备跑起来”的任务。理解这个区别之后再去看 IgH 的代码和 EtherCAT 主站运行过程就会清晰很多。一、SDO 和 PDO 到底有什么区别先从 Object Dictionary 说起要真正理解 SDO 和 PDO第一步不是看 IgH API而是理解EtherCAT 从站内部的数据到底存在哪里答案通常就是Object Dictionary对象字典。以一个典型的 CiA 402 伺服驱动器为例可能包含0x1000 Device Type 0x1001 Error Register 0x1018 Identity Object 0x1600 RxPDO Mapping 0x1A00 TxPDO Mapping 0x6040 Controlword 0x6041 Statusword 0x6060 Modes of Operation 0x6061 Modes of Operation Display 0x607A Target Position 0x6064 Position Actual Value 0x60FF Target Velocity 0x606C Velocity Actual Value这里需要特别注意这些对象本身并不是 SDO 或 PDO。这是最容易出现的概念混淆。例如0x6040:00 Controlword本质上是对象字典中的一个对象。它既可能被作为 SDO 对象进行访问也可能被映射到 PDO 中作为周期过程数据。所以正确的理解应该是Object Dictionary │ ├── SDO 访问方式 │ └── PDO 映射方式也就是说SDO 和 PDO 是访问对象的不同机制而不是对象本身的分类。1. SDO 是什么SDO 通常通过 EtherCAT 的CoECANopen over EtherCAT机制进行对象字典访问。它的核心逻辑可以理解成主站 ↓ 我要访问 Index/SubIndex ↓ 从站 ↓ 查找 Object Dictionary ↓ 返回数据例如Index 0x6060 SubIndex 0x00主站可以请求0x6060:00从站返回Modes of Operation这是一种典型的对象访问方式。因此SDO 特别适合设备初始化 参数配置 模式设置 设备诊断 读取厂家参数 修改非周期参数 读取错误信息例如设置工作模式 ↓ 写 0x6060 ↓ 配置某个设备参数 ↓ 写对应对象 ↓ 读取设备状态参数 ↓ 读对应对象这些操作通常不是每个控制周期都需要执行。2. PDO 是什么PDO 的思路完全不同。它不是我要读取 0x6064而是提前定义每个周期都需要交换 0x6040 0x607A 0x6041 0x6064然后把这些数据组织成过程数据。例如RxPDO 0x6040 Controlword 0x607A Target PositionTxPDO0x6041 Statusword 0x6064 Actual Position那么每个控制周期就可以直接交换主站 → 从站 Controlword Target Position 从站 → 主站 Statusword Actual Position整个过程中不需要应用程序每次都重新告诉设备“请给我 0x6064。”而是已经通过 PDO Mapping 把数据布局确定下来。这就是 PDO 适合实时控制的根本原因之一。3. 一个简单的比喻如果把从站看成一个仓库Object Dictionary 整个仓库SDO 相当于“请帮我找 0x6064:00 把这个东西拿出来。”PDO 则相当于每天固定时间 把已经打包好的这一箱货直接送过来。所以SDO 随机访问 按对象访问 配置/诊断 PDO 预先组织 周期交换 实时过程数据这就是二者最核心的区别。二、为什么设备初始化大量使用 SDO而运行阶段主要依赖 PDO理解 SDO 和 PDO 的区别之后就可以回答一个实际工程问题为什么 EtherCAT 设备启动的时候经常需要大量 SDO 操作因为设备启动时需要完成的工作和设备正常运行时需要完成的工作并不一样。可以把一个典型伺服设备的生命周期理解成设备上电 ↓ EtherCAT 通信建立 ↓ 读取设备信息 ↓ 配置设备参数 ↓ 配置 PDO ↓ 进入 SAFEOP ↓ 过程数据准备 ↓ 进入 OP ↓ 周期控制前半部分属于Configuration后半部分属于Real-time Process Data两者使用的机制自然不同。1. 初始化阶段SDO 很重要例如伺服驱动器需要配置工作模式 加速度 减速度 某些设备参数 电子齿轮 限位参数 采样参数 厂家参数这些数据通常不会要求每 1 ms都交换。因此没有必要把它们全部放入 PDO。这时候 SDO 非常合适主站 ↓ SDO Download ↓ 写入设备参数或者主站 ↓ SDO Upload ↓ 读取设备参数2. 运行阶段PDO 成为主角设备真正进入控制状态之后控制器可能每1 ms或者500 μs执行一次控制循环。这时候需要Controlword Target Position Statusword Actual Position如果每个变量都通过 SDO 访问控制周期 ↓ 发送请求 ↓ 等待响应 ↓ 解析 ↓ 读取下一个对象 ↓ 继续等待那么周期路径会变得非常复杂。而 PDO 可以提前把数据组织好PDO ↓ EtherCAT Frame ↓ 从站然后应用程序只需要读 Domain ↓ 控制算法 ↓ 写 Domain所以SDO 适合“访问对象”PDO 适合“持续交换过程数据”。3. 为什么不能把 SDO 当作实时控制通道这是一个非常重要的工程结论。假设控制周期1 ms应用程序需要读取Actual Position如果使用 PDO每个周期 ↓ EtherCAT Frame ↓ 获取 Actual Position而如果使用 SDO每个周期 ↓ 发起对象访问 ↓ 从站处理 ↓ 返回响应 ↓ 主站解析 ↓ 应用程序继续执行这个路径显然更加复杂。更重要的是SDO 本身并不是为了提供固定周期的过程数据交换语义而设计的。它更适合一次性配置 偶尔读取 参数修改 诊断而不是1000 次/秒 10000 次/秒持续访问。因此在高性能运动控制系统中通常会把真正参与控制闭环的数据放进 PDO。三、从 IgH 看 SDO主站到底如何访问对象字典理解 EtherCAT 协议概念之后再看 IgH 就会更加直观。IgH EtherCAT Master 为应用程序提供了相应的 SDO 访问机制。其中一个典型思路是通过异步 SDO 请求访问对象。例如可以创建 SDO requestec_sdo_request_t *req; req ecrt_slave_config_create_sdo_request( sc, 0x6060, 0x00, 1 );这里表示创建一个针对0x6060:00的 SDO 请求。之后应用程序可以对请求设置数据并启动访问。典型逻辑可以理解成创建 SDO Request ↓ 设置数据 ↓ 启动 Download / Upload ↓ 等待状态变化 ↓ 检查结果例如ecrt_sdo_request_write(req);或者ecrt_sdo_request_read(req);具体 API 使用时应以所使用 IgH EtherLab 版本的头文件和官方文档为准。这里最重要的不是记住某一个函数而是理解IgH 的 SDO 请求属于对象访问机制与 Domain 中的周期 PDO 数据通道是两个不同的路径。1. SDO Download 和 Upload 是什么在 EtherCAT/CoE 语境中Download通常表示主站 → 从站也就是写入对象。例如0x6060:00设置工作模式。逻辑Master ↓ SDO Download ↓ Slave Object Dictionary ↓ 0x6060而Upload则可以理解为从站 → 主站也就是读取对象。例如Master ↓ SDO Upload ↓ Slave ↓ 0x603F Error Code ↓ Master所以可以简单记忆SDO Download 写对象 SDO Upload 读对象2. 为什么 SDO 通常是异步的这是理解 IgH SDO 的关键。PDO 的运行逻辑通常是周期开始 ↓ Receive ↓ Process ↓ Control ↓ Queue ↓ Send而 SDO 请求通常不需要每个周期都执行。例如启动阶段 ↓ 请求读取设备参数 ↓ 等待响应 ↓ 处理结果它可以在后台完成。因此从程序架构上看实时控制线程 │ └── PDO / Domain 配置或管理逻辑 │ └── SDO这也是为什么在一个设计良好的工业控制程序里经常会把实时任务和配置任务进行逻辑分离。四、PDO 和 SDO 在一个真实伺服控制系统中是怎么配合的现在把前面的知识全部串起来。假设我们需要控制一台 EtherCAT 伺服驱动器。目标是1 ms 位置控制周期启动之后需要设置工作模式 配置 PDO 确认设备状态 进入 OP运行之后每 1 ms 发送目标位置 读取实际位置 更新控制字 读取状态字那么整个过程可以设计成EtherCAT Slave │ ┌───────────┴───────────┐ │ │ SDO PDO │ │ 参数配置/诊断 周期过程数据 │ │ ┌──────┴──────┐ ┌───────┴────────┐ │ │ │ │ 0x6060 其他参数 Controlword Target Position Statusword Actual Position1. 第一步识别设备IgH 首先需要确认Vendor ID Product Code Revision等信息。例如sc ecrt_master_slave_config( master, 0, 0, VENDOR_ID, PRODUCT_CODE );2. 第二步进行 PDO 配置然后配置RxPDO TxPDO Sync Manager例如RxPDO 0x6040 0x607A TxPDO 0x6041 0x6064形成Domain最终应用程序获得control_word_offset target_position_offset status_word_offset actual_position_offset3. 第三步通过 SDO 配置设备参数例如0x6060 Modes of Operation可以通过 SDO 写入。设备可能需要0x6060 某种工作模式例如具体数值需要根据设备支持的 CiA 402 模式确定。这个动作通常发生在设备进入正常控制之前。4. 第四步进入 OP当PDO Mapping ↓ PDO Assignment ↓ Sync Manager ↓ Domain全部准备完成之后主站才进入周期过程数据交换。5. 第五步1 ms 周期控制之后进入while (running)周期ecrt_master_receive() ↓ ecrt_domain_process() ↓ 读取 Statusword ↓ 读取 Actual Position ↓ 控制算法 ↓ 写入 Controlword ↓ 写入 Target Position ↓ ecrt_domain_queue() ↓ ecrt_master_send() ↓ 下一周期这时候SDO 已经不是主要数据通道。真正承担控制闭环的是PDO Domain EtherCAT cyclic communication这就是一个完整的工业控制数据路径。五、SDO、PDO 与实时控制到底应该怎么理解到这里可以把 SDO 和 PDO 放到整个 EtherCAT 架构中重新看一遍。最容易产生的误解是PDO 是实时的所以 EtherCAT 就是实时的。其实还不够准确。PDO 只是提供了一种非常适合周期过程数据交换的机制。真正的系统实时性还取决于应用程序 ↓ 实时调度 ↓ Domain ↓ IgH ↓ 网络驱动 ↓ EtherCAT ↓ 从站所以SDO 解决 “怎么访问设备参数” PDO 解决 “怎么周期交换过程数据” IgH 解决 “怎么在 Linux 上实现 EtherCAT Master” 实时 Linux / 实时操作系统 解决 “怎么让控制任务按照确定的时间执行”这四者不能混为一谈。1. 为什么平均延迟低仍然不等于硬实时假设某个系统平均控制周期1.000 ms看起来非常漂亮。但是如果实际测量结果是999 μs 1001 μs 1000 μs 1002 μs 998 μs 1030 μs 1000 μs那么平均值可能仍然接近1 ms但最大延迟已经出现了30 μs的异常。如果控制系统要求严格周期那么真正应该关注的是Worst-case latency而不是单纯Average latency这也是为什么在工业控制系统中经常需要同时关注周期 抖动 最大延迟 WKC 任务执行时间 IRQ 延迟2. EtherCAT、IgH 和实时 Linux 分别解决什么可以把整个系统分成三个层次第一层通信协议 EtherCAT ↓ 解决工业设备之间如何高效、确定地交换过程数据第二层主站实现 IgH EtherCAT Master ↓ 解决 Linux 系统如何实现 EtherCAT Master第三层操作系统运行环境 Linux / 实时 Linux / 实时操作系统 ↓ 解决控制任务什么时候执行、执行过程中受到多少干扰因此EtherCAT ≠ IgH IgH ≠ 实时 Linux 实时 Linux ≠ EtherCAT真正的工业实时控制系统是实时任务 ↓ 实时调度 ↓ IgH EtherCAT Master ↓ EtherCAT ↓ 伺服 / IO / 编码器最终才能形成完整的数据闭环。3. 这也是为什么不能简单把“Linux IgH”理解成硬实时IgH 可以在 Linux 环境中运行 EtherCAT Master并提供实时应用所需的接口和数据通路。但是使用 IgH 并不自动意味着整个 Linux 系统已经具备硬实时确定性。如果控制任务受到普通任务 IRQ 网络协议栈 CPU 竞争 内存压力 调度延迟 缓存行为 驱动执行时间等因素影响那么最终 EtherCAT 周期仍然可能出现抖动。所以工业控制系统设计时应该从整个时间链路去分析控制任务唤醒 ↓ 读取 Domain ↓ 执行控制算法 ↓ 写入 Domain ↓ IgH ↓ 网卡发送 ↓ EtherCAT 从站 ↓ 返回 ↓ 网卡接收 ↓ IgH ↓ Domain ↓ 控制任务只优化其中一层并不能自动解决全部问题。4. 从这个角度看核心隔离为什么值得关注对于更高要求的工业控制系统问题最终会进一步落到如何避免实时任务受到普通任务干扰例如一台工业控制计算机同时运行实时控制任务 HMI 日志系统 数据库 网络服务 设备管理 数据采集 AI 推理如果这些任务都争抢同一个 CPU 核心那么即使 EtherCAT 本身具有非常好的周期通信能力也可能出现普通任务 ↓ CPU 竞争 ↓ 实时任务延迟 ↓ EtherCAT 控制周期抖动因此进一步的工程优化可能涉及CPU Affinity IRQ Affinity CPU Isolation 实时调度策略 内核抢占 内存与缓存行为也就是从“通信实时”继续走向“系统实时”这也是后续讨论 EtherCAT 实时 Linux 时必须面对的问题。对于需要高确定性控制的场景例如多轴运动控制 工业机器人 数控系统 飞控仿真 高端 PLC 实时仿真 智能制造设备真正需要关注的并不是某一个指标而是整个控制链路的确定性。在这一点上具备硬实时能力和核心隔离能力的实时操作系统方案例如望获 OS 的相关产品可以作为 Linux/EtherCAT 工业控制架构中的一种系统级实现思路。这里的关键并不是“换一个系统就自动实时”而是让 EtherCAT 的确定性通信能力与操作系统层面的任务确定性结合起来。结语SDO 负责“配置设备”PDO 负责“运行设备”如果把今天的内容压缩成一张图可以这样理解EtherCAT Slave │ Object Dictionary │ ┌────────────┴────────────┐ │ │ SDO PDO │ │ 对象级访问 周期过程数据 │ │ ┌─────┴─────┐ ┌─────┴─────┐ │ │ │ │ 参数配置 设备诊断 RxPDO TxPDO │ │ │ └──────────┐ ┌───┴───────────┘ │ │ ↓ ↓ 设备初始化 → 周期控制 │ ↓ IgH Domain │ ↓ Linux Memory │ ↓ 控制算法所以最重要的几个结论是第一Object Dictionary 才是设备对象的基础。0x6040、0x607A、0x6064等本质上是对象而不是天然属于 SDO 或 PDO。第二SDO 和 PDO 是两种不同的数据交换方式。SDO 更适合对象级访问、参数配置和诊断PDO 更适合周期性的过程数据交换。第三PDO 并不是简单地“读取对象”。它需要经过PDO Mapping ↓ PDO Assignment ↓ Sync Manager ↓ EtherCAT Process Data ↓ IgH Domain最终变成应用程序能够周期访问的数据。第四SDO 不应该替代 PDO 成为高频控制通道。尤其是在 1 ms、500 μs 甚至更短的控制周期下把控制闭环中的核心数据通过 SDO 逐个访问会让实时数据路径变得更加复杂。第五EtherCAT 的实时性和操作系统的实时性是两个层次的问题。EtherCAT 负责工业通信的确定性与高效率IgH 负责 Linux 环境下的 EtherCAT Master 实现而最终控制任务能否稳定地按照周期执行还与 Linux 调度、中断、CPU 竞争、驱动以及系统整体架构密切相关。因此一个真正的实时工业控制系统应该关注的是实时工业控制系统 │ ┌───────────────┼────────────────┐ ↓ ↓ ↓ EtherCAT IgH Master OS/Runtime │ │ │ 确定性通信 主站实现 任务确定性 │ │ │ └───────────────┼────────────────┘ ↓ 控制系统确定性下一篇继续进入 EtherCAT 一个非常核心、也是运动控制领域经常讨论的机制Distributed Clocks分布式时钟DC。如果说 PDO 解决的是“控制数据怎么高速交换”那么 DC 解决的就是“多个设备到底应该在什么时候同时动作”尤其对于多轴伺服、机器人、数控和同步运动控制来说仅仅让数据按周期到达还不够还需要尽可能让不同从站的动作时间保持一致。下一篇《EtherCAT 分布式时钟 DC 到底是什么为什么多轴运动控制离不开它》我们将继续从 EtherCAT 原理和 IgH 源码两个角度分析 DC 的工作机制、Reference Clock、SYNC0/SYNC1、时钟偏差以及 DC 与 Linux 控制周期之间的关系。