设计动机
工业现场设备出问题,最怕的是”不知道发生了什么”。设备在几百公里外的磨坊里,运维人员不可能随时跑现场接调试器。
这套诊断体系的设计目标就是:通过 Modbus 远程读取,还原设备”经历了什么”。从固件版本、运行时长、重启原因,到通信异常分类、非法操作记录、升级快照,全部通过只读寄存器暴露。
诊断区寄存器总览
诊断区占用 0x0038 ~ 0x0059,共 34 个寄存器(17 个 32 位值 + 17 个 16 位值),分为五大类:
读取命令
0A 03 00 38 00 22 45 65
一次性读取全部 34 个寄存器。
一、版本与编译信息
| 地址 | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0038 | FW_VERSION | uint16 | 固件版本号,当前 0x0100 |
0x0039 | PROTOCOL_VERSION | uint16 | 协议版本号,当前 0x0100 |
0x003A | BUILD_YEAR | uint16 | 编译年份 |
0x003B | BUILD_MONTH_DAY | uint16 | 编译月/日,month<<8 | day |
0x003C | BUILD_HOUR_MIN | uint16 | 编译时/分,hour<<8 | minute |
编译时间从 __DATE__ 和 __TIME__ 宏自动提取,不需要手动维护。现场排查时,先读这 6 个寄存器确认设备运行的是哪个版本。
二、运行统计
| 地址 | 名称 | 类型 | 说明 |
|---|---|---|---|
0x003D~3E | UPTIME | uint32 | 运行时长,单位秒 |
0x003F~40 | POWER_ON_COUNT | uint32 | 上电次数 |
0x0041 | RESET_REASON | uint16 | 最近一次重启原因 |
重启原因编码
| 值 | 含义 | 说明 |
|---|---|---|
0 | 未知 | 无法确定复位源 |
1 | 上电复位 | 正常上电 |
2 | NRST 引脚复位 | 外部复位引脚触发 |
3 | 软件复位 | NVIC_SystemReset() 调用 |
4 | 独立看门狗复位 | IWDG 超时 |
5 | 窗口看门狗复位 | WWDG 超时 |
6 | 低功耗复位 | 从待机模式唤醒 |
排障价值:如果看到 POWER_ON_COUNT 在短时间内异常增长,配合 RESET_REASON = 4(IWDG 复位),说明设备正在反复看门狗复位——很可能是新固件有问题或某个任务阻塞过久。
三、通信异常统计
这是诊断区最核心的部分,直接反映现场总线的通信质量。
汇总统计
| 地址 | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0045~46 | MODBUS_CRC_ERR | uint32 | Modbus CRC 错误累计次数 |
0x0047~48 | UART_ERR_TOTAL | uint32 | UART 异常总次数(ORE+FE+NE) |
分类统计
| 地址 | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0052~53 | UART_ORE | uint32 | Overrun 错误次数 |
0x0054~55 | UART_FE | uint32 | 帧错误次数 |
0x0056~57 | UART_NE | uint32 | 噪声错误次数 |
0x0058~59 | RX_OVERFLOW | uint32 | 接收缓冲溢出次数 |
读取通信异常分类计数:
0A 03 00 52 00 08 E4 A6
关键说明
UART_ERR_TOTAL统计的是ORE + FE + NE总数,不包含RX_OVERFLOWRX_OVERFLOW需要单独读取0x0058~0x0059RX_OVERFLOW是”软件接收缓冲打满后继续收到字节”的累计次数,不等同于”发送字节数 / 缓冲长度”
排障价值:如果 CRC_ERR 很高但 UART_FE 不高,说明数据完整性有问题但帧格式正常——可能是 RS485 总线终端电阻不匹配或共模干扰。如果 ORE 很高,说明中断响应不及时,可能是某个高优先级任务阻塞了串口中断。
四、非法操作记录
| 地址 | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0042 | LAST_BAD_ADDR | uint16 | 最近一次非法写入的寄存器地址 |
0x0043 | LAST_BAD_VALUE | uint16 | 最近一次非法写入的值 |
0x004A | LAST_BAD_READ_ADDR | uint16 | 最近一次非法读取的起始地址 |
0x0049 | LAST_CMD_RESULT | uint16 | 最近一次维护命令的执行结果 |
排障价值:当远程修改参数失败时,先读 0x0042~0x0043 看是哪个地址、什么值被拒绝,再读 0x0033(错误码)看拒绝原因。这两组寄存器联动可以直接定位问题。
五、配置与升级快照
配置快照
| 地址 | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0044 | LAST_CFG_SOURCE | uint16 | 当前配置来源 |
0x004B~4C | LAST_SAVE_UPTIME | uint32 | 最近一次成功保存时的运行秒数 |
0x004D~4E | LAST_SAVE_SEQ | uint32 | 最近一次成功保存的配置序号 |
0x0034 | CFG_VERSION | uint16 | 配置结构版本号 |
0x0035~36 | CFG_SEQUENCE | uint32 | 当前生效配置序号 |
配置来源编码
| 值 | 含义 |
|---|---|
1 | 默认配置 |
2 | 从 Flash 加载 |
3 | 远程保存生效 |
4 | 恢复默认参数后生效 |
升级快照
| 地址 | 名称 | 类型 | 说明 |
|---|---|---|---|
0x004F | LAST_UPGRADE_SOURCE | uint16 | 最近一次升级请求来源 |
0x0050 | LAST_UPGRADE_STATE | uint16 | 最近一次升级状态 |
0x0051 | LAST_UPGRADE_ERROR | uint16 | 最近一次升级失败原因 |
升级来源编码
| 值 | 含义 |
|---|---|
0 | 无 |
1 | 本地维护电脑 |
2 | G780S 远程维护命令 |
3 | 预留远程 OTA |
升级状态编码
| 值 | 含义 |
|---|---|
0 | IDLE |
1 | REQUESTED |
2 | ERASING |
3 | PROGRAMMING |
4 | VERIFYING |
5 | DONE |
6 | FAILED |
排障价值:升级后设备异常,先读 0x004F~0x0051。常见正常表现:
- 本地串口升级完成:
0001 0005 0000(来源=本地,状态=DONE,错误=无) - G780S 请求但未完成升级:
0002 0006 000C(来源=G780S,状态=FAILED,错误=超时恢复)
实战排障流程
场景一:设备频繁重启
1. 读 0x003F~40 (POWER_ON_COUNT) → 确认重启频率
2. 读 0x0041 (RESET_REASON) → 确认重启原因
3. 如果是 IWDG 复位 → 检查固件版本,排查是否有任务阻塞
4. 如果是 NRST 复位 → 检查供电和硬件
场景二:数据上报异常
1. 读 0x0045~46 (CRC_ERR) → 通信质量
2. 读 0x0052~59 (ORE/FE/NE/RX_OVERFLOW) → 异常分类
3. 如果 FE 高 → 检查波特率匹配和终端电阻
4. 如果 ORE 高 → 检查中断优先级
5. 如果 RX_OVERFLOW 高 → 检查是否有大量无效数据灌入总线
场景三:升级后设备不工作
1. 读 0x004F~51 (UPGRADE_SOURCE/STATE/ERROR) → 升级快照
2. 读 0x0038~39 (FW_VERSION) → 确认当前版本
3. 读 0x0041 (RESET_REASON) → 确认是否因升级触发复位
4. 读 0x0044 (CFG_SOURCE) → 确认配置是否丢失
设计约束
- 所有诊断寄存器为只读,不提供写入接口
- 诊断数据在设备重启后保持(持久化在 Flash 诊断页),但运行时长和上电次数会重置
RX_OVERFLOW不计入UART_ERR_TOTAL,需单独查看- 如果通过 G780S 请求进入 Bootloader 但实际升级由本地串口完成,
UPGRADE_SOURCE可能显示为1(本地)而非2(G780S),这是符合当前实现的预期行为