PROFINET IO 设备
概述
Darra PLC 通过 P-Net 协议栈 实现 PROFINET IO Device 功能, 支持 RT Class 1 通讯, 可将 Darra PLC 作为 PROFINET IO 设备接入西门子或第三方 PROFINET 控制器。
PROFINET IO 是西门子主导的工业以太网标准 (IEC 61158/61784), 广泛用于汽车、物流、食品饮料等行业。
协议栈架构
┌─────────────────────────────────────────┐
│ Darra PLC Service │
│ ┌─────────────────────────────────┐ │
│ │ PROFINET IO Device 接口层 │ │
│ │ (IO 数据映射, 诊断, 报警) │ │
│ └──────────────┬──────────────────┘ │
│ │ │
│ ┌──────────────┴──────────────────┐ │
│ │ P-Net 协议栈 │ │
│ │ ┌───────┬──────┬───────────┐ │ │
│ │ │ RTC │ RTA │ DCP/LLDP │ │ │
│ │ └───────┴──────┴───────────┘ │ │
│ └──────────────┬──────────────────┘ │
│ │ │
│ ┌──────────────┴──────────────────┐ │
│ │ NDIS / 以太网驱动 │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
P-Net 是开源 PROFINET 协议栈, Darra 在 P-Net 基础上封装了 IO 数据映射层, 使其与 PLC 变量空间无缝集成。
支持的 PROFINET 功能
| 功能 | 支持 | 说明 |
|---|---|---|
| RT Class 1 | ✅ | 周期实时通讯, 1~10 ms |
| IO Device | ✅ | 作为从设备接入控制器 |
| 多槽/子槽 | ✅ | 模块化设备描述 |
| 多模块 | ✅ | 多个 IO 模块组合 |
| 共享设备 | — | 单一设备被多个控制器共享 |
| I-Device | — | IO Device 同时提供 IO Controller 功能 |
| IRT | — | 等时实时, 需专用 ASIC |
| MRP | — | 介质冗余协议 |
| 系统冗余 (S2) | — | 双控制器冗余 |
设备配置
设备名称与 IP
PROFINET 通过 设备名称 (Station Name) 识别设备, 而非 IP 地址。IP 地址由 DCP 协议自动分配。
var profinet = new ProfinetIoDevice();
profinet.Configure(new ProfinetConfig {
StationName = "darra-plc-line1", // 设备名称 (PROFINET 唯一标识)
VendorId = 0x1234, // 厂商 ID (从 PI 申请)
DeviceId = 0x0001, // 设备 ID (厂商自定义)
IpAddress = "192.168.1.100", // 推荐固定 IP (DCP 也可动态分配)
SubnetMask = "255.255.255.0",
DefaultGateway = "192.168.1.1",
MinDeviceInterval = 1, // 最小周期 (ms)
NumberOfSlots = 4 // 槽位数量
});
使用 DCP 设置设备名称
通过 DCP (Discovery and Configuration Protocol) 设置设备名称:
// 扫描网络上的 PROFINET 设备
var devices = profinet.DcpProbe();
foreach (var d in devices)
{
Console.WriteLine($"MAC: {d.Mac}, Name: {d.StationName}, IP: {d.IpAddress}");
}
// 设置设备名称
profinet.DcpSetName("darra-plc-line1", macAddress: "00:11:22:33:44:55");
GSDML 文件
GSDML (Generic Station Description Markup Language) 是 PROFINET 设备的描述文件, 由控制器侧导入, 用于识别设备功能和 IO 配置。
Darra PLC 会生成对应的 GSDML 文件, 供 PROFINET 控制器 (如西门子 S7-1500) 导入:
<?xml version="1.0" encoding="utf-8"?>
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003">
<ProfileHeader>
<ProfileIdentification>GSDML</ProfileIdentification>
<ProfileRevision>2.35</ProfileRevision>
</ProfileHeader>
<ProfileBody>
<DeviceIdentity VendorID="1234" DeviceID="0001" />
<DeviceFunction>
<ApplicationProcess>
<ModuleList>
<!-- 数字输入模块, 16 通道 -->
<Module ModuleIdentNumber="0x00000001">
<Name>16 DI</Name>
<ModuleInfo>
<Name TextId="IDT_DI_16" />
</ModuleInfo>
<VirtualSubmoduleList>
<VirtualSubmodule SubmoduleIdentNumber="0x00000001">
<IOData>
<Input>
<DataItem DataType="BIT" />
<!-- 16 位, 对应 16 个 DI -->
</Input>
</IOData>
</VirtualSubmodule>
</VirtualSubmoduleList>
</Module>
<!-- 数字输出模块, 16 通道 -->
<Module ModuleIdentNumber="0x00000002">
<Name>16 DO</Name>
<VirtualSubmoduleList>
<VirtualSubmodule SubmoduleIdentNumber="0x00000001">
<IOData>
<Output>
<DataItem DataType="BIT" />
<!-- 16 位, 对应 16 个 DO -->
</Output>
</IOData>
</VirtualSubmodule>
</VirtualSubmoduleList>
</Module>
</ModuleList>
</ApplicationProcess>
</DeviceFunction>
</ProfileBody>
</ISO15745Profile>
GSDML 文件在 IDE 中通过 "PROFINET → 导出 GSDML" 生成, 然后拷贝到控制器工程。
IO 数据映射
槽/子槽映射
PROFINET IO 使用 槽 (Slot) / 子槽 (Subslot) 结构组织 IO 数据。Darra PLC 将槽映射到 PLC 地址空间:
PROFINET 设备 Darra PLC (IO Device):
Slot 0: 设备接入点 (DAP)
Subslot 0x8000: 设备接口诊断
Slot 1: 16 DI 模块
Subslot 0x0001: 输入数据 → %IX100.0~%IX101.7
Slot 2: 16 DO 模块
Subslot 0x0001: 输出数据 → %QX100.0~%QX101.7
Slot 3: 4 AI 模块
Subslot 0x0001: 输入数据 → %IW200, %IW202, %IW204, %IW206
Slot 4: 4 AO 模块
Subslot 0x0001: 输出数据 → %QW200, %QW202, %QW204, %QW206
映射配置
在 IDE 中通过 "PROFINET → IO 映射" 配置:
{
"profinetMapping": {
"stationName": "darra-plc-line1",
"slots": [
{
"slotNumber": 1,
"moduleIdentNumber": "0x00000001",
"direction": "input",
"plcAddress": "%IX100",
"bitLength": 16
},
{
"slotNumber": 2,
"moduleIdentNumber": "0x00000002",
"direction": "output",
"plcAddress": "%QX100",
"bitLength": 16
}
]
}
}
数据模型
PROFINET IO 数据在 PLC 中表现为标准 IEC 61131-3 变量:
(* SCL — 读取 PROFINET 控制器发来的数据 *)
IF %IX100.0 THEN (* Slot 1, DI 0 *)
Valve_Status := TRUE;
END_IF;
(* SCL — 写数据给 PROFINET 控制器 *)
%QX100.0 := Sensor_Ready; (* Slot 2, DO 0 *)
(* 模拟量 *)
Temperature := %IW200 / 10.0; (* Slot 3, AI 0, 0~27648 → 0~100°C *)
RT Class 1 通讯
通讯周期
RT Class 1 是标准实时通讯, 基于以太网优先级 (VLAN 优先级 6) 实现确定性:
| 设置周期 | 实际周期 | 适用场景 |
|---|---|---|
| 1 ms | 1 ms ± 0.5 ms | 快速 IO, 小数据量 (≤ 256 字节) |
| 2 ms | 2 ms ± 1 ms | 混合 IO, 中等数据量 |
| 4 ms | 4 ms ± 1 ms | 慢速 IO, 大数据量 |
| 8~10 ms | 8~10 ms ± 2 ms | 监控、诊断 |
数据交换流程
IO Controller (PLC) IO Device (Darra PLC)
│ │
│ 1. CR 建立 (连接建立) │
│ Connect Request ──────────────────► │
│ Connect Response ◄────────────────── │
│ │
│ 2. 参数分配 (参数化) │
│ Write Request (参数) ──────────────► │
│ Write Response ◄─────────────────── │
│ │
│ 3. 应用就绪 │
│ Write Request (应用就绪) ───────────► │
│ Write Response ◄─────────────────── │
│ │
│ 4. 数据交换 (周期运行) │
│ ┌─────────────────────────────┐ │
│ │ 周期: 1 ms │ │
│ │ 输出数据 ──────────────────► │ │
│ │ 输入数据 ◄────────────────── │ │
│ └─────────────────────────────┘ │
│ │
│ 5. 断开 (停止) │
│ Disconnect Request ───────────────► │
│ Disconnect Response ◄─────────────── │
│ │
周期抖动
RT Class 1 的周期抖动取决于网络负载和交换机处理能力:
抖动来源:
- 控制器侧周期精度 (软件定时器误差)
- 交换机帧排队 (避免与非实时帧竞争)
- 设备侧处理时间 (IO 读写的微抖动)
典型抖动:
- 直连 (无交换机): < 100 μs
- 1 层交换机: < 200 μs
- 2 层交换机: < 500 μs
- 3+ 层交换机: 1~2 ms (不建议)
诊断与调试
诊断信息
PROFINET IO 设备定期上报诊断信息, IDE 诊断面板显示:
| 诊断项 | 来源 | 说明 |
|---|---|---|
| 设备状态 | DAP | 正常运行 / 故障 / 不可用 |
| 模块状态 | 子槽 | 每个模块/子槽的独立状态 |
| 通道诊断 | 通道 | 逐通道的故障状态 |
| 通讯状态 | CR | 连接资源状态 |
| IOPS 评价 | 数据交换 | 提供者/消费者状态 |
诊断 API
// 获取设备诊断
var diag = profinet.GetDiagnosis();
Console.WriteLine($"Device State: {diag.State}"); // Normal / Fault / NotAvailable
Console.WriteLine($"IOPS Provider: {diag.IopsProvider}"); // Good / Bad / Uncertain
Console.WriteLine($"IOPS Consumer: {diag.IopsConsumer}");
// 通道级诊断
foreach (var channel in diag.Channels)
{
Console.WriteLine($"Slot {channel.Slot}, Subslot {channel.Subslot}: {channel.ErrorType}");
}
诊断报警
PROFINET 支持三种报警类型:
| 报警类型 | 触发 | 处理 |
|---|---|---|
| 诊断报警 (Diagnosis Alarm) | 模块故障、通道故障 | 控制器读取诊断信息 |
| 过程报警 (Process Alarm) | 工艺事件 (如限位到达) | 触发 PLC 中断 OB |
| 拔出报警 (Pull Alarm) | 模块被拔出 | 控制器停止数据交换 |
诊断状态码
| 状态码 | 含义 | 处理 |
|---|---|---|
| 0x0000 | 正常 | — |
| 0x0001 | 模块故障 | 检查模块, 重新上电 |
| 0x0002 | 子模块故障 | 检查子槽配置 |
| 0x0003 | 通道故障 | 检查具体通道 |
| 0x0004 | 通讯故障 | 检查网络连接 |
| 0x0005 | 参数错误 | 控制器侧参数配置错误 |
排错指南
| 症状 | 处理 |
|---|---|
| 控制器找不到设备 | 设备名称未设置或错配, 用 DCP 重新设置名称 |
| 连接建立失败 | 检查 GSDML 文件版本, 确认模块配置一致 |
| 数据交换不启动 | 参数分配未完成, 检查控制器侧的参数配置 |
| 数据交换抖动 > 1 ms | 交换机 QOS 配置不当, 确认 VLAN 优先级 6 启用 |
| 周期性 IOPS Bad | 设备负载过高, 延长周期或减少 IO 数据量 |
| 诊断报警频繁 | 检查通道级故障, 排除传感器/执行器硬件问题 |
| 设备重启后不可用 | 确认 DCP 设备名称持久化 (非仅内存) |
| 无法分配 IP | DCP 被防火墙阻挡, 确认网络允许 DCP 广播帧 |
调试工具
IDE 内置 PROFINET 调试工具:
- DCP 浏览器: 扫描网络上的 PROFINET 设备, 查看/修改设备名称
- IO 数据监视: 实时显示每个槽/子槽的 IO 数据值
- 诊断日志: 记录所有诊断报警, 按时间线展示
- 通讯统计: 周期计数、错误计数、IOPS 统计
- 抓包分析: 导出 PCAP 格式的 PROFINET 帧, 可用 Wireshark 分析
限制
- IRT 需要专用 ASIC (如 ERTEC 200), Darra PLC 基于软件 P-Net 栈, 不支持 IRT
- 不支持 I-Device 和共享设备, 每个 Darra PLC 只能作为一个 IO Device 接入一个控制器
- 最大 IO 数据 = 每个 AR 约 1024 字节输入 + 1024 字节输出 (受 P-Net 栈限制)
- 周期抖动在网桥/交换机多跳场景下会累积, 建议直连或 1 层交换机
- 目前仅支持 RT Class 1, 不支持 RT Class 2/3 (AR 数据)