诊断
真正用法是西门子式诊断系统:先看设备是否在线、通道诊断、报警和过程数据质量,再决定要不要读写过程数据。
活动报警与确认见 报警。本页覆盖运行态、诊断快照、通道诊断、数据质量和复位。
功能概览
| 功能 | 说明 |
|---|---|
| 运行态 | 是否在换周期数据、状态机、错误码、待机 vs 掉线 |
| 诊断快照 | 一次取回链路、帧计数、看门狗、抖动、报警统计 |
| 现场问题对照 | 按症状选字段 |
| 通道诊断 | 向 IO 控制器上报 / 更新 / 清除通道故障(主站侧能看见) |
| 过程数据质量 | IOPS / IOCS:数据 GOOD 还是 BAD |
| I&M 标识 | 订货号、序列号、站名,供 TIA 核对 |
| 复位 | 通信复位 / 工厂复位 |
运行态
通过 DarraPnS 实例直接读属性。服务不可达时见各属性说明,不伪装成正常。
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
Connected | bool | 诊断 | 只读 | 是否已与 IO 控制器建立周期数据交换 |
State | PnSState | 诊断 | 只读 | 运行态。服务不可达为 Unknown |
ErrorCode | PnSRuntimeErrorCode | 诊断 | 只读 | 最近一次运行错误。未识别值 Unknown |
ErrorCodeRaw | int | 诊断 | 只读 | 运行错误原值(0 = 无)。未识别值仍透传 |
ErrorMessage | string | 诊断 | 只读 | 运行错误中文消息 |
StatusMessage | string | 诊断 | 只读 | 配置失败等原因文案;正常态为空 |
EverConnected | bool | 诊断 | 只读 | 是否曾经连上过控制器 |
LastServiceError | string | 诊断 | 只读 | 最近一次服务调用错误(成功则清空) |
PnSState 取值见 错误码。
var device = DarraPnS.Connect();
device.Start();
if (!device.Connected)
{
Console.WriteLine("未进入周期数据交换: " + device.State);
Console.WriteLine(device.ErrorMessage);
if (!string.IsNullOrEmpty(device.StatusMessage))
Console.WriteLine(device.StatusMessage);
if (device.EverConnected)
Console.WriteLine("曾经连上过,当前是掉线");
else
Console.WriteLine("从未连上,仍在待机");
}
诊断快照
DiagSnapshot
public PnSDiagSnapshot DiagSnapshot { get; }
一次调用取回当前诊断快照,适合界面刷新和日志。设备尚未启动时 Ok == false,读 Message,不视为异常。
取快照失败(服务不可达 / 响应无法解析)抛 PnSServiceException。错误码必须透出,见 错误码。
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
Ok | bool | 快照 | 只读 | 诊断是否可用。false = 设备未启动 |
Message | string | 快照 | 只读 | 不可用时的原因;可用时为空 |
State | string | 快照 | 只读 | 驱动状态文案 |
LinkUp | bool | 快照 | 只读 | 网卡链路是否 Up |
Connected | bool | 快照 | 只读 | 周期数据是否正常 |
Heartbeat | ulong | 快照 | 只读 | 心跳计数 |
CycleCounter | ulong | 快照 | 只读 | 周期循环计数 |
LastError | ulong | 快照 | 只读 | 最近错误码(0 = 无) |
RxFrames / TxFrames | ulong | 快照 | 只读 | 收 / 发总帧数 |
DroppedFrames | ulong | 快照 | 只读 | 被丢弃的帧 |
InvalidFrames | ulong | 快照 | 只读 | 非法帧 |
WatchdogTrips | ulong | 快照 | 只读 | 看门狗超时次数 |
ActiveIocrCount | uint | 快照 | 只读 | 已激活的 IO 连接数 |
IocrActive | uint | 快照 | 只读 | IO 连接激活位图 |
IocrHealthy | uint | 快照 | 只读 | IO 连接健康位图 |
InputAreaLength / OutputAreaLength | uint | 快照 | 只读 | 过程区长度(字节) |
StackCycles | ulong | 快照 | 只读 | 协议栈周期计数 |
StackFramesRx / StackFramesTx | ulong | 快照 | 只读 | 协议栈收 / 发帧 |
StackMissedTicks | ulong | 快照 | 只读 | 错过的节拍 |
StackMaxJitterUs | ulong | 快照 | 只读 | 最大抖动(微秒) |
StackAlarmRxCount | ulong | 快照 | 只读 | 收到控制器报警总数 |
StackAlarmTxAckOk | ulong | 快照 | 只读 | 本设备报警被控制器确认数 |
StackAlarmTxAckFail | ulong | 快照 | 只读 | 本设备报警确认失败数 |
StackAlarmAckPending | ulong | 快照 | 只读 | 在途过程报警(0 / 1) |
StackAlarmMaintState | ulong | 快照 | 只读 | 当前维护请求状态 |
StackAlarmLastSlot / LastSubslot | uint | 快照 | 只读 | 最近控制器报警的槽 / 子槽 |
StackAlarmLastType | uint | 快照 | 只读 | 最近控制器报警类型 |
ErrorCode | int | 快照 | 只读 | 服务端错误码原值 |
ErrorCodeEnum | PnSRuntimeErrorCode | 快照 | 只读 | 上项的枚举形态 |
Timestamp | DateTime | 快照 | 只读 | 快照生成时刻 |
PnSDiagSnapshot snap = device.DiagSnapshot;
if (!snap.Ok)
{
Console.WriteLine("诊断不可用: " + snap.Message);
return;
}
Console.WriteLine("链路: " + (snap.LinkUp ? "Up" : "Down"));
Console.WriteLine("周期交换: " + (snap.Connected ? "正常" : "未建立"));
Console.WriteLine("收/发: " + snap.RxFrames + " / " + snap.TxFrames);
Console.WriteLine("看门狗超时: " + snap.WatchdogTrips);
Console.WriteLine("最大抖动: " + snap.StackMaxJitterUs + " µs");
if (snap.StackMissedTicks > 0)
Console.WriteLine("错过节拍: " + snap.StackMissedTicks);
现场问题对照
| 现场症状 | 看哪些字段 |
|---|---|
| 控制器连不上? | Connected + State + StatusMessage + EverConnected |
| 是待机还是掉线? | EverConnected(false = 从未连;true 且 Connected==false = 掉线) |
| 网线没插好? | DiagSnapshot.LinkUp |
| 看门狗反复跳? | DiagSnapshot.WatchdogTrips |
| 帧在丢? | DroppedFrames + InvalidFrames |
| 周期稳不稳? | StackMaxJitterUs + StackMissedTicks |
| 过程数据能不能信? | IoStatus.AllGood / InputDataGood / OutputDataGood |
| 控制器侧看不看得见故障? | 通道诊断 + 报警 |
| 站名 / 订货号对不对? | ImData |
通道诊断
向 IO 控制器上报标准格式通道诊断。控制器工程(TIA 诊断缓冲 / 模块诊断)能看到这些条目。这是设备把故障告诉主站的主接口。
插拔类报警由栈在模块插拔时自动发送,应用不必自己发。
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
DiagStdAdd(slot, subslot, ch, chBits, severity, chErrorType, extChErrorType = 0, extChAddValue = 0) | void | 诊断 | 写 | 添加通道诊断,触发诊断报警上控制器 |
DiagStdUpdate(slot, subslot, ch, chErrorType, extChErrorType = 0, extChAddValue = 0) | void | 诊断 | 写 | 更新扩展附加值。规范要求更新频率不高于 1 Hz |
DiagStdRemove(slot, subslot, ch, chErrorType, extChErrorType = 0) | void | 诊断 | 写 | 移除通道诊断,触发诊断清除 |
参数边界(越界抛 ArgumentOutOfRangeException,不到达协议栈):
| 参数 | 合法范围 |
|---|---|
slot / subslot | 0–65534(65535 规范保留) |
ch | 0–0x8000。0x8000 = 整子模块 |
chBits | 0 / 1 / 2 / 4 / 8 / 16 / 32 / 64(0 = 未指定;仅 Add) |
severity | 0 故障 / 1 需要维护 / 2 要求维护 / 3 合格化 |
chErrorType | 通道错误类型(PROFINET 通道诊断编码,如 0x0B10) |
同一位置重复 Add 由服务端拒绝,抛 PnSServiceException(带服务端错误码)。
// 上报整子模块故障,控制器侧能看见
device.DiagStdAdd(
slot: 0,
subslot: 1,
ch: 0x8000,
chBits: 0,
severity: (byte)PnSSeverity.Fault,
chErrorType: 0x0B10);
// 故障恢复:清除同一条
device.DiagStdRemove(0, 1, 0x8000, 0x0B10);
PnSSeverity:
| 值 | 名称 | 说明 |
|---|---|---|
| 0 | Fault | 故障 |
| 1 | MaintenanceRequired | 需要维护 |
| 2 | MaintenanceDemanded | 要求维护 |
| 3 | Qualified | 合格化诊断 |
过程数据质量
IoStatus
public PnSIoStatus IoStatus { get; }
过程数据每个字节对应一个状态字节:0x80 = GOOD(有效),0x00 = BAD(无效 / 未连接 / 看门狗超时)。掉线时如实全 BAD,不虚构 GOOD。
未启动或取快照失败返回 PnSIoStatus.Empty(全部 GOOD 判据为 false)。原因记在 LastServiceError。
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
InputIops | byte[] | 质量 | 只读 | 控制器提供的输入区状态 |
InputIocs | byte[] | 质量 | 只读 | 本设备消费后回报的输入区状态 |
OutputIops | byte[] | 质量 | 只读 | 本设备提供的输出区状态 |
OutputIocs | byte[] | 质量 | 只读 | 控制器消费后的输出区状态 |
InputValid | bool | 质量 | 只读 | 本轮是否从控制器收到过输入 |
OutputValid | bool | 质量 | 只读 | 本轮是否有应用写过输出 |
InputDataGood | bool | 质量 | 只读 | 收到过输入且输入 IOPS 全 GOOD |
OutputDataGood | bool | 质量 | 只读 | 写过输出且输出 IOPS 全 GOOD |
OutputConsumed | bool | 质量 | 只读 | 输出 IOCS 全 GOOD(控制器已消费) |
AllGood | bool | 质量 | 只读 | 输入有效 + 输出有效 + 输出已消费 |
IsGood(byte) | bool | 质量 | 静态 | 单字节是否 GOOD |
Empty | PnSIoStatus | 质量 | 静态 | 空状态(未启动 / 不可达) |
PnSIoStatus io = device.IoStatus;
if (!io.AllGood)
{
Console.WriteLine(io.ToString());
if (!io.InputDataGood)
Console.WriteLine("控制器送来的数据不可用");
if (!io.OutputConsumed)
Console.WriteLine("控制器尚未消费本设备输出");
}
过程数据读写本身见 过程数据。
I&M 标识
ImData
public PnSImData ImData { get; }
设备标识观测,供 TIA 识别核对。未写过的 I&M1–4 字段为空,不虚构。失败抛 PnSServiceException。
| 成员 | 类型 | 说明 |
|---|---|---|
VendorId / DeviceId | uint | 厂商 / 设备 ID |
OrderId | string | 订货号 |
SerialNumber | string | 序列号 |
HardwareRevision / SoftwareRevision | string | 硬件 / 软件版本 |
StationName | string | 站点名(须与 TIA 设备名一致) |
ProductName | string | 产品名 |
ImSupported | string | 已启用的 I&M 记录集 |
Im14Supported | bool | I&M1–4 是否启用 |
Im1TagFunction / Im1TagLocation | string | 功能标签 / 安装位置 |
Im2Date | string | 日期 |
Im3Descriptor | string | 描述 |
Im4SignatureHex | string | 签名(十六进制) |
ProjectOrderNumber | string | 工程订货号 |
Timestamp | DateTime | 快照时刻 |
PnSImData im = device.ImData;
Console.WriteLine("站名: " + im.StationName);
Console.WriteLine("订货号: " + im.OrderId);
Console.WriteLine("序列号: " + im.SerialNumber);
Records
public PnSUserRecords Records { get; }
用户区记录表。缺字段默认 0 / 空,不虚构。
| 成员 | 类型 | 说明 |
|---|---|---|
Records | PnSUserRecord[] | 记录数组 |
Count | int | 服务端计数 |
Timestamp | DateTime | 快照时刻 |
PnSUserRecord:Slot / Subslot / Index / Length / DataHex。
复位
ResetDevice
public void ResetDevice(string mode)
mode | 行为 |
|---|---|
"communication" | 通信复位:软停止后重启,应用参数保留 |
"factory" | 工厂复位:销毁后全新启动,应用参数清空 |
mode 非法抛 ArgumentException。失败抛 PnSServiceException。这是慢操作,超时按启停口径,不要当失败误杀。
device.ResetDevice("communication");
通讯参数 / IP 的工厂复位仍由控制器侧复位请求触发。