排错专题:SDO Abort 与超时
SDO 失败主要有两类:电机明确返回 0x80 Abort,或者程序等到超时仍没有收到匹配响应。两者的排查方向不同。
Abort 和超时先分开
| 现象 | 已经证明什么 | 下一步 |
|---|---|---|
收到 0x581 DATA 80 ... | CAN-ID、Node-ID 和位速率基本正确,电机主动拒绝本次访问 | 解码 Abort Code |
没有匹配 0x581,最终 timeout | 尚不能证明电机看到了请求 | 查总线、Node-ID、接收过滤和并发 |
收到 Abort 其实比完全没响应更接近答案:通信路径已经通了。
Abort 帧怎样拆
示例:
CAN-ID 0x581
DLC 8
DATA 80 7D 60 00 00 00 02 06
| 字节 | 内容 |
|---|---|
| 0 | 0x80,SDO Abort 响应 |
| 1~2 | Index 小端序:7D 60 → 0x607D |
| 3 | Sub-index:0x00 |
| 4~7 | Abort Code 小端序:00 00 02 06 → 0x06020000 |
所以这帧表示:访问 0x607D:00 时,Server 返回“对象不存在”。
本课程常用 Abort Code
| Abort Code | 常见含义 | 应对 |
|---|---|---|
0x05040000 | SDO protocol timed out | 检查节点在线、处理循环和总线拥塞 |
0x06010001 | 尝试读取只写对象 | 查对象权限 |
0x06010002 | 尝试写只读对象 | 停止写入,查设备文档 |
0x06020000 | 对象不存在 | 设备可能没实现这个可选对象 |
0x06090011 | Sub-index 不存在 | 核对记录/数组的子索引数量 |
0x06070010 | 数据类型或长度不匹配 | 核对 1、2、4 字节和有无符号类型 |
0x06090030 | 参数值范围错误 | 查允许范围和单位 |
0x08000022 | 当前设备状态不能访问 | 先核对 NMT/CiA 402 状态和厂家条件 |
同一数字在不同上下文中不要混淆:0x06020000 是 32 位 Abort Code,0x602 则可能被人看成一个 CAN-ID,日志应明确标签。
对象不存在不一定是电机故障
CiA 402 定义大量对象,但具体设备只需实现与其功能相关的部分。厂家没有实现 0x607D 时,返回 0x06020000 是规范化拒绝,不是总线损坏。
程序应:
- 打印对象地址和 Abort Code;
- 标记本对象不可用;
- 继续测试其他互不依赖的对象;
- 若它是当前功能必需对象,则停止该功能;
- 不用猜测的私有对象替代。
超时从四层排查
1. CAN 总线层
- 是否能收到
0x701Heartbeat; - 发送
0x601是否得到 ACK; - TEC 是否持续增加;
- 位速率是否都是 500 kbit/s。
2. Node-ID 和 CAN-ID
电机 Node 0x01 的默认 SDO:
请求 0x600 + 0x01 = 0x601
响应 0x580 + 0x01 = 0x581
若电机 Node-ID 已被厂家软件改成别的值,这两条编号也会一起改变。
3. 响应匹配
收到 0x581 还不够。客户端要核对 Index 和 Sub-index,不能把上一条请求或其他任务的响应当作当前结果。
同一时间只允许一个活动 SDO 请求,是本课程简化并发设计的重要规则。
4. 协议状态机是否持续运行
CANopenNode SDO API 返回大于 0 时,程序必须继续调用 CO_SDOclientUpload() 或 CO_SDOclientDownload(),并给它正确的时间增量。只调用 Initiate 后就长时间阻塞,状态机不会自己完成。
写入超时后不要盲目重发
读取超时通常可以谨慎重试;控制字、目标位置等写入超时则存在不确定性:报文可能已经被设备执行,只是响应丢失。
运动写入超时后应:
- 停止自动重发;
- 读取
0x6041和0x6064; - 观察电机是否已经开始或完成动作;
- 根据真实状态决定后续操作。
对非幂等命令不停重发,可能造成重复动作。
一份有用的失败日志
TX 0x601 [8] 40 7D 60 00 00 00 00 00
RX 0x581 [8] 80 7D 60 00 00 00 02 06
SDO 0x607D:00 failed: abort=0x06020000 (object does not exist)
三行把请求、原始响应和程序解释连在一起。只有一句 read failed 几乎无法排错。
CANopenNode 官方 SDO Client 说明:SDO client