2. 对象字典索引、子索引与数据类型

对象字典是CANopen从站的“数据与行为总目录”。主站并不直接访问从站内存,而是通过“索引(Index)+ 子索引(Subindex)”这一对地址来定位一个对象,再配合通信服务完成读写。理解索引分区、子索引寻址和数据类型编码,是读懂EDS文件、编写从站协议栈、排查SDO/PDO映射问题的前提。

索引0x1000~0x9FFF的分配规则

CiA 301把16位索引空间按功能划分为若干区段,每个区段承担不同职责。工程中最常打交道的区段如下:

索引范围用途典型对象
0x1000–0x1029通信参数0x1000设备类型、0x1005 SYNC COB-ID、0x1018厂商ID
0x1200–0x12FFSDO服务器参数0x1200 SDO服务器参数
0x1400–0x1BFFPDO通信与映射参数0x1400 RPDO通信、0x1600 RPDO映射、0x1800 TPDO通信、0x1A00 TPDO映射
0x2000–0x5FFF制造商特定参数厂商自定义配置、标定参数
0x6000–0x9FFF标准化设备子协议(CiA 401/402等)0x6040控制字、0x6060运行模式、0x6064位置实际值

记忆要点:0x1000段管“通信怎么走”,0x2000–0x5FFF管“厂商怎么定”,0x6000段管“设备怎么动”。0x0000–0x0FFF保留给数据类型定义,0xA000以上留给未来扩展。写从站时,通信参数必须落在0x1000段,否则主站按标准扫描时无法识别。

子索引寻址方式

索引定位“哪个对象”,子索引定位“对象内的哪个元素”。子索引为8位,取值0x00–0xFF。规则是:

  • 简单变量:只有一个值,子索引固定为0x00。例如0x1000设备类型,读0x1000:00即可。
  • 数组(ARRAY):子索引0x00存放元素个数,数据从0x01开始顺序排列。例如0x1018厂商信息,0x1018:00=4,0x1018:01厂商ID、0x1018:02产品代码、0x1018:03修订号、0x1018:04序列号。
  • 记录(RECORD):子索引0x00同样存放元素个数,但各子索引语义不同、可含不同数据类型。例如0x1400 RPDO通信参数:0x01 COB-ID、0x02传输类型、0x03禁止时间、0x04兼容时间。

关键区别:数组元素类型一致、可循环访问;记录元素类型和含义各异,必须逐项定义。子索引0x00在数组和记录中都是“元素个数”,但它是只读的,不能通过写0x00来增删元素。若访问不存在的子索引,从站应返回SDO中止码0x06090011(子索引不存在)。

基本数据类型与复合数据类型的编码

CANopen数据类型用16位索引在0x0001–0x001F区段定义,EDS中通过数据类型名引用。常用基本类型:

类型名位数说明
BOOLEAN1位(占1字节)0/1
INTEGER8/16/328/16/32有符号整数
UNSIGNED8/16/328/16/32无符号整数
REAL3232IEEE 754单精度浮点
VISIBLE_STRING可变可见字符,无结束符
OCTET_STRING可变任意字节序列

复合类型包括ARRAY、RECORD和PDO映射用的PDO_MAPPING。编码时注意字节序:CANopen规定多字节数值采用小端(Little-Endian),低字节在前。例如UNSIGNED32值0x12345678在线路上传输顺序为78 56 34 12。字符串不补结束符,长度由对象的数据长度决定。

PDO映射条目本身是UNSIGNED32,编码格式为:位31–16为索引,位15–8为子索引,位7–0为数据长度(位)。例如把0x6040:00控制字(16位)映射进TPDO,映射值为0x60400010。若映射长度与实际对象长度不符,从站应拒绝该映射并报错。

用EDS文件描述对象字典条目

EDS是INI格式文本,主站靠它离线获知从站对象字典。每个对象用一段[索引]描述,关键字段包括:ParameterName、ObjectType(7=VAR、8=ARRAY、9=RECORD)、DataType、AccessType(ro/rw/wo/const)、DefaultValue、PDOMapping(0/1)。数组和记录还要为每个子索引单独建段,段名形如[1018sub1]。

[1018]
ParameterName=Identity Object
ObjectType=9
DataType=0x0009
AccessType=ro
DefaultValue=4

[1018sub0]
ParameterName=Number of Entries
ObjectType=7
DataType=0x0005
AccessType=ro
DefaultValue=4

[1018sub1]
ParameterName=Vendor ID
ObjectType=7
DataType=0x0007
AccessType=ro
DefaultValue=0x00000123

上例中0x1018是记录,子索引0声明有4个元素,子索引1为UNSIGNED32厂商ID。EDS写完后,主站配置工具会解析这些段并生成对象字典视图;若EDS中DataType与从站固件实际类型不一致,SDO读取时可能返回长度错误或中止码0x06070010(数据类型不匹配)。因此EDS必须与固件对象字典严格同步,修改对象后要同步更新EDS并重新导入主站。

CANopen 索引分区 · 子索引寻址 · 数据类型编码 16位索引空间分区 0x1000–0x1029 通信参数 0x1400–0x1BFF PDO通信/映射 0x2000–0x5FFF 制造商特定 0x6000–0x9FFF 标准化设备子协议 0x0000–0x0FFF / 0xA000+ 数据类型定义 / 保留扩展 子索引寻址:索引定位对象,子索引定位元素 VAR 简单变量 0x1000:00 设备类型 仅子索引0x00 单值,无元素个数 ARRAY 数组 0x1018:00 = 4(个数) 0x1018:01…04 同类型 元素类型一致 RECORD 记录 0x1400:00 = 4(个数) :01 COB-ID :02 传输类型 各元素类型/含义不同 数据类型与编码 基本类型 BOOLEAN / INTEGER8/16/32 UNSIGNED8/16/32 / REAL32 VISIBLE_STRING / OCTET_STRING 多字节:小端,低字节在前 复合类型 ARRAY / RECORD PDO_MAPPING 映射值 = 索引<<16 | 子索引<<8 | 位长 0x6040:00 16位 → 0x60400010 EDS 条目描述 [1018] ObjectType=9 DataType=0x0009 AccessType=ro [1018sub0] 元素个数 [1018sub1] Vendor ID DataType 必须与固件对象字典一致 不一致 → SDO 中止码 0x06070010
工程习惯:新增或修改对象后,先改固件对象字典,再同步EDS,最后用主站配置工具重新导入并做一次SDO读回验证,避免EDS与固件“两张皮”。