SDO 协议详解 -- Client/Server 模型与帧格式

SDO 基本概念

SDO(Service Data Object,服务数据对象)是 CANOpen 中用于非实时、参数访问的通信机制。它采用 Client/Server 模型:

  • Client:发起请求的一方(通常是主站/上位机)
  • Server:响应请求的一方(通常是设备/从节点)

典型应用场景:

  • 配置设备参数(波特率、节点 ID、PDO 映射)
  • 读取设备信息(固件版本、制造商信息)
  • 诊断和调试(读取错误记录)
  • 非实时的控制参数调整

与 PDO 的对比:

特性SDOPDO
模型Client/Server(请求-响应)Producer/Consumer(发布-订阅)
实时性非实时实时
数据量任意大小(分段传输)最多 8 字节
确认机制有(确认/错误响应)无(广播)
典型用途参数配置、诊断实时控制、状态反馈

SDO 通信参数

每个 CANOpen 节点有一对 SDO 通信参数:

方向COB-ID 计算公式说明
Client -> Server(SDO Request)0x600 + node_id客户端发送请求
Server -> Client(SDO Response)0x580 + node_id服务端发送响应

示例(节点 ID = 3):

  • 请求 COB-ID:0x600 + 3 = 0x603
  • 响应 COB-ID:0x580 + 3 = 0x583
  Client (主站)                 Server (节点 3)
     │                              │
     │─── SDO Request ────────────>│
     │    COB-ID = 0x603           │
     │                              │
     │<── SDO Response ───────────│
     │    COB-ID = 0x583           │
     │                              │

默认节点 0 的 SDO: CANOpen 预留了节点 0 的 SDO 用于特殊用途:

  • SDO 0 Request: 0x600
  • SDO 0 Response: 0x580

SDO 帧格式

SDO 使用 CAN 标准帧(11 位 ID),数据场最多 8 字节。

SDO Request 帧格式(Client -> Server)

┌────────┬─────┬──────┬────────┬────────┬────────┬────────┬────────┐
│ Byte 0 │ B 1 │ B 2  │ B 3    │ B 4    │ B 5    │ B 6    │ B 7    │
├────────┼─────┼──────┼────────┼────────┼────────┼────────┼────────┤
│ CCS+ 0 │Index │Index │SubIdx  │ Data... │ Data... │ Data... │ Data... │
│ (命令)  │ (Lo) │ (Hi) │        │        │        │        │        │
└────────┴─────┴──────┴────────┴────────┴────────┴────────┴────────┘

字节 0 格式:

  Bit 7  Bit 6  Bit 5  Bit 4  Bit 3  Bit 2  Bit 1  Bit 0
  ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
  │ CCS │  0  │  0  │  0  │  0  │  0  │  0  │  0  │
  └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
   ╰─ Command Specifier

SDO Response 帧格式(Server -> Client)

┌────────┬─────┬──────┬────────┬────────┬────────┬────────┬────────┐
│ Byte 0 │ B 1 │ B 2  │ B 3    │ B 4    │ B 5    │ B 6    │ B 7    │
├────────┼─────┼──────┼────────┼────────┼────────┼────────┼────────┤
│ SCS+ 0 │Index │Index │SubIdx  │ Data... │ Data... │ Data... │ Data... │
│ (命令)  │ (Lo) │ (Hi) │        │        │        │        │        │
└────────┴─────┴──────┴────────┴────────┴────────┴────────┴────────┘

字节 0 格式:

  Bit 7  Bit 6  Bit 5  Bit 4  Bit 3  Bit 2  Bit 1  Bit 0
  ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
  │ SCS │  0  │  0  │  0  │  0  │  0  │  0  │  0  │
  └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
   ╰─ Server Command Specifier

CCS(Client Command Specifier)– 客户端命令码

CCS命令说明
000 (0x0)SDO Initiate Download客户端写请求
001 (0x1)SDO Initiate Upload客户端读请求
010 (0x2)SDO Segment Transfer分段传输(客户端继续发送/接收)
011 (0x3)SDO Initiate Block Download块写请求
100 (0x4)SDO Initiate Block Upload块读请求
101 (0x5)SDO Block Transfer块传输
110 (0x6)SDO Abort Transfer终止传输

SCS(Server Command Specifier)– 服务端命令码

SCS命令说明
010 (0x2)SDO Initiate Download Response写请求确认
011 (0x3)SDO Initiate Upload Response读响应(携带数据)
100 (0x4)SDO Segment Transfer Response分段传输响应
101 (0x5)SDO Initiate Block Download Response块写响应
110 (0x6)SDO Initiate Block Upload Response块读响应
111 (0x7)SDO Abort Transfer终止传输(错误)

三种传输模式

1. Expedited Transfer(快速传输)

适用于 ≤ 4 字节 的小数据。

特点:

  • 单次请求 + 单次响应
  • 数据直接嵌入帧中(字节 4-7)
  • 无需后续分段

2. Segmented Transfer(分段传输)

适用于 > 4 字节 的大数据。

特点:

  • 多次请求 + 多次响应
  • 每段最多 7 字节(字节 1-7)
  • Toggle 位机制(防止丢包)
  • 有明确的开始、中间、结束阶段

3. Block Transfer(块传输)

适用于 大量数据(固件更新等)。

特点:

  • 一次确认后连续发送多个数据块
  • 减少通信开销
  • CANopenNode 基本实现中不常用

Abort Transfer(终止传输)

当 SDO 传输中出现错误时,服务端发送 Abort 帧:

┌────────┬─────┬──────┬────────┬────────┬────────┬────────┬────────┐
│ 0x80   │Index │Index │SubIdx  │ Abort Code (4 bytes)            │
│        │ (Lo) │ (Hi) │        │                                │
└────────┴─────┴──────┴────────┴────────┴────────┴────────┴────────┘

常见 Abort 码:

Abort 码含义
0x05030000Toggle 位不匹配
0x05040000SDO 同步超时
0x05040001Client/Server 命令码无效
0x06010000不支持的访问类型
0x06010002尝试写入只读对象
0x06020000对象字典中不存在该索引
0x06040041对象不兼容(子索引无效)
0x06040043一般内部错误
0x06040047数据类型不匹配
0x08000000一般错误
0x08000020数据无法传输

Expedited Upload 详解

帧格式

Request(Client -> Server):

┌────────┬─────┬──────┬────────┬────────┬────────┬────────┬────────┐
│ 0x40   │Index │Index │SubIdx  │ 0x00   │ 0x00   │ 0x00   │ 0x00   │
│        │ (Lo) │ (Hi) │        │        │        │        │        │
└────────┴─────┴──────┴────────┴────────┴────────┴────────┴────────┘
  • 字节 0 = 0x40 = CCS=1(Upload)+ e=0(非 Expedited 标记,实际由服务端决定)
  • 字节 1-2 = 索引(小端模式)
  • 字节 3 = 子索引

Response(Server -> Client):

┌────────┬─────┬──────┬────────┬────────┬────────┬────────┬────────┐
│ Byte 0 │Index │Index │SubIdx  │ Data   │ Data   │ Data   │ Data   │
│        │ (Lo) │ (Hi) │        │        │        │        │        │
└────────┴─────┴──────┴────────┴────────┴────────┴────────┴────────┘

字节 0 格式(Expedited Upload Response):

  Bit 7  Bit 6  Bit 5  Bit 4  Bit 3  Bit 2  Bit 1  Bit 0
  ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
  │  0  │  1  │  1  │  0  │ n   │ n   │ s   │ e   │
  └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
                       ╰─ 未传输字节数 ╰─ 有数据 ╰─ Expedited
  • s=1, e=1 = Expedited 传输
  • nn = 未传输的字节数(0-3)
  • SCS = 011 = 0x3

示例: Expedited Upload 0x1000sub0,返回 4 字节数据

Request:  603  [8]  40 00 10 00 00 00 00 00
          │    │   │   │   │   │   └─ 填充
          │    │   │   │   │   └───── 子索引 0
          │    │   │   │   └───────── 索引 0x1000(小端)
          │    │   │   └───────────── CCS=1 (Upload)
          │    │   └───────────────── 命令字节
          │    └───────────────────── COB-ID 0x603
          └────────────────────────── CAN DLC=8

Response: 583  [8]  4B 00 10 00 92 01 01 00
          │    │   │   │   │   │   │   └─ 数据字节 3
          │    │   │   │   │   │   └───── 数据字节 2
          │    │   │   │   │   └───────── 数据字节 1
          │    │   │   │   └───────────── 数据字节 0
          │    │   │   └───────────────── 子索引 0
          │    │   └───────────────────── 索引 0x1000
          │    └───────────────────────── SCS=011, e=1, s=1, n=0 (4字节数据)
          └────────────────────────────── COB-ID 0x583
  • 0x4B = 0100 1011 = SCS=011, n=00, s=1, e=1
  • 数据 = 0x00010192(小端模式)= 设备类型

Expedited Download 详解

帧格式

Request(Client -> Server):

┌────────┬─────┬──────┬────────┬────────┬────────┬────────┬────────┐
│ Byte 0 │Index │Index │SubIdx  │ Data   │ Data   │ Data   │ Data   │
│        │ (Lo) │ (Hi) │        │        │        │        │        │
└────────┴─────┴──────┴────────┴────────┴────────┴────────┴────────┘

字节 0 格式:

  Bit 7  Bit 6  Bit 5  Bit 4  Bit 3  Bit 2  Bit 1  Bit 0
  ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
  │  0  │  0  │  1  │ n   │ n   │ n   │ s   │ e   │
  └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
             ╰─ CCS=0 (Download)
  • e=1 = Expedited 传输
  • nnn = 未传输的字节数

Response(Server -> Client):

┌────────┬─────┬──────┬────────┬────────┬────────┬────────┬────────┐
│ 0x60   │Index │Index │SubIdx  │ 0x00   │ 0x00   │ 0x00   │ 0x00   │
│        │ (Lo) │ (Hi) │        │        │        │        │        │
└────────┴─────┴──────┴────────┴────────┴────────┴────────┴────────┘
  • 字节 0 = 0x60 = SCS=010(Download Response)

示例:Expedited Download 0x1005sub0,写入 COB-ID = 0x80000080

Request:  603  [8]  2B 05 10 00 80 00 00 80
          │    │   │   │   │   │   │   └─ 数据字节 3
          │    │   │   │   │   │   └───── 数据字节 2
          │    │   │   │   │   └───────── 数据字节 1
          │    │   │   │   └───────────── 数据字节 0
          │    │   │   └───────────────── 子索引 0
          │    │   └───────────────────── 索引 0x1005
          │    └───────────────────────── CCS=0, e=1, n=00 (4字节数据)
          └────────────────────────────── COB-ID 0x603

Response: 583  [8]  60 05 10 00 00 00 00 00
          │    │   │   │   └─ 填充
          │    │   │   └───── 子索引 0
          │    │   └───────── 索引 0x1005
          │    └───────────── SCS=010 (Download Response)
          └───────────────── COB-ID 0x583

Segmented 传输概述

详见 05-sdo-segmented-transfer.md。

总结

维度说明
模型Client(请求)/ Server(响应)
COB-IDRequest=0x600+node_id, Response=0x580+node_id
帧格式8 字节,字节 0 为命令码
Expedited≤4 字节,单次请求+响应
Segmented>4 字节,多段传输,Toggle 位
Abort字节 0=0x80,后跟 4 字节错误码
如果这篇文章对你有帮助,欢迎请我喝杯咖啡 ☕
Cygnus Yang 支付宝支付宝
Cygnus Yang 微信微信