2. CANopen协议核心机制

在Anybus CANopen设备网关工程中,网关并不是简单地“转发CAN帧”,而是要在CANopen应用层语义上理解从站设备的行为。CANopen把每个节点的可访问数据组织成一张对象字典(Object Dictionary, OD),并用索引(Index,16位)与子索引(Subindex,8位)定位。网关要做的第一件事,就是建立“索引/子索引 → 物理量/状态”的映射表,否则收到的报文只是无意义的字节流。

对象字典中与通信最相关的区域是:0x1000~0x1029的通信参数区(设备类型、错误寄存器、心跳/节点保护时间、PDO映射与通信参数等),0x1400/0x1600的RPDO通信与映射参数,0x1800/0x1A00的TPDO通信与映射参数,以及0x2000以上的制造商自定义区。网关通常只解析自己关心的条目,例如0x1018厂商ID、0x1001错误寄存器、0x1800子索引2的传输类型、0x1A00映射内容等。

CANopen的通信对象分为四类:PDO(过程数据对象,用于实时I/O)、SDO(服务数据对象,用于参数读写)、NMT(网络管理,控制节点状态)、以及心跳/节点保护(用于节点存活监控)。网关必须同时处理这四类报文,才能既保证实时性,又保证配置与诊断能力。

CANopen 核心机制与网关解析关系 对象字典 OD 索引 + 子索引 定位 0x1000–0x1029 通信参数 0x1400/0x1600 RPDO 0x1800/0x1A00 TPDO 0x2000+ 制造商自定义 通信对象 PDO:实时过程数据(1–8字节) SDO:参数读写(分段/加速) NMT:状态控制(启动/停止/复位) 心跳 / 节点保护:存活监控 Anybus 网关解析任务 COB-ID 过滤与功能码识别 PDO 映射解析 → 过程变量 SDO 请求/响应 参数通道 NMT 状态机 + 心跳超时判断 关键报文示例与网关解析要点 PDO 报文 COB-ID: 0x180+NodeID 数据: 8字节过程值 传输类型: 0xFF 事件 映射: 0x1A00 子索引 网关: 按映射拆解为 INT16/UINT8 等变量 SDO 报文 COB-ID: 0x600+NodeID 命令字: 0x40 读 / 0x2F 写 索引+子索引+数据 响应: 0x580+NodeID 网关: 用于配置参数 与读取诊断信息 NMT 报文 COB-ID: 0x000 命令: 0x01 启动 0x02 停止 / 0x80 预操作 0x81 复位节点 / 0x82 复位通信 网关: 控制从站状态 并同步自身状态机 心跳 / 节点保护 心跳: 0x700+NodeID 数据: 状态字节 0x05 运行 / 0x7F 预操作 节点保护: 0x700+NodeID 网关: 超时判定离线 触发告警或安全动作

PDO是实时性最高的通信对象。它由“通信参数”和“映射参数”共同定义:通信参数(如0x1800)决定COB-ID、传输类型和禁止时间;映射参数(如0x1A00)决定这个PDO的1~8字节里,每个字节段对应对象字典中的哪个条目。例如某从站TPDO1映射为:0x2000:01(INT16温度)、0x2001:01(UINT8状态)、0x2002:01(UINT16压力),则网关收到8字节后,按映射顺序拆出2+1+2字节,再按数据类型还原为工程量。若映射顺序或数据类型判断错误,就会出现“数值跳变”或“高低字节颠倒”的典型故障。

SDO用于参数读写,采用客户端/服务器模型。网关作为SDO客户端,向从站发送请求(COB-ID=0x600+NodeID),从站用0x580+NodeID响应。加速SDO可一次传4字节以内数据;超过4字节则进入分段传输,通过“下载/上传”命令字和Toggle位交替完成。网关在配置阶段常用SDO写入0x1800子索引2的传输类型、0x1017的心跳周期等参数,运行阶段则用SDO读取0x1001错误寄存器做诊断。

NMT负责节点状态管理。CANopen节点有初始化、预操作、运行、停止四个主要状态。上电后节点进入预操作,此时只有SDO和心跳可用,PDO被禁止;网关发送NMT启动命令(COB-ID=0x000,数据为0x01+NodeID)后,节点进入运行态,PDO才开始传输。网关自身也要维护一张节点状态表,记录每个从站当前处于哪个状态,避免在预操作态误判PDO丢失。

心跳与节点保护用于存活监控。心跳模式下,从站按0x1017设定的周期主动发送0x700+NodeID,数据字节为状态码(0x00启动、0x04停止、0x05运行、0x7F预操作)。网关为每个节点维护一个超时计时器,若在“心跳周期×超时倍数”内未收到心跳,则判定该节点离线。节点保护则是网关主动轮询(0x700+NodeID发送远程帧),从站响应状态。两者选其一即可,Anybus网关通常优先使用心跳,因为它不需要网关周期性发起请求,网络负载更低。

网关解析关键报文的通用顺序:先按COB-ID判断功能码(0x000=NMT、0x080=SYNC、0x180/0x280/0x380/0x480=TPDO1–4、0x200/0x300/0x400/0x500=RPDO1–4、0x600=SDO请求、0x580=SDO响应、0x700=心跳/节点保护),再按节点号分流到对应从站上下文,最后按对象字典映射还原数据。

实际工程中,网关还需要处理SYNC同步报文(COB-ID=0x080)和紧急报文(EMCY,COB-ID=0x080+NodeID)。SYNC用于触发同步PDO,网关若配置为同步模式,需在收到SYNC后统一刷新过程数据;EMCY则携带错误码和错误寄存器内容,是快速定位从站故障的重要来源。建议网关在启动阶段用SDO读取每个从站的0x1018(厂商ID、产品代码、版本号)建立设备指纹,运行阶段用心跳状态字节和EMCY错误码联合判断节点健康度,而不是仅凭PDO是否刷新来推断。

下面给出一份网关侧“关键报文解析检查表”示例,可用于配置和排障时逐项核对:

报文类型COB-ID关键字段网关动作
NMT0x000命令字 + NodeID更新节点状态表
SYNC0x080无数据触发同步PDO刷新
EMCY0x080+NodeID错误码 + 错误寄存器记录故障并告警
TPDO10x180+NodeID映射数据按0x1A00拆解变量
RPDO10x200+NodeID映射数据按0x1600打包下发
SDO请求0x600+NodeID命令字+索引+子索引发起参数读写
SDO响应0x580+NodeID命令字+数据校验并回填结果
心跳0x700+NodeID状态字节刷新超时计时器

需要特别注意的是,PDO的COB-ID并非固定不变,可通过SDO修改0x1800子索引1来重新分配。若网关与从站的PDO COB-ID配置不一致,就会出现“从站明明在发,网关却收不到”的问题。因此,工程上建议在网关配置文件中显式记录每个从站的PDO COB-ID、映射条目和数据类型,并在上线前用SDO回读0x1800/0x1A00进行一致性校验。只有把对象字典、PDO、SDO、NMT、心跳这五类机制串起来理解,网关才能既做“数据搬运工”,又做“状态管理者”。