2. 对象字典索引、子索引与数据类型
对象字典是CANopen从站的“数据与行为总目录”。主站并不直接访问从站内存,而是通过“索引(Index)+ 子索引(Subindex)”这一对地址来定位一个对象,再配合通信服务完成读写。理解索引分区、子索引寻址和数据类型编码,是读懂EDS文件、编写从站协议栈、排查SDO/PDO映射问题的前提。
索引0x1000~0x9FFF的分配规则
CiA 301把16位索引空间按功能划分为若干区段,每个区段承担不同职责。工程中最常打交道的区段如下:
| 索引范围 | 用途 | 典型对象 |
|---|---|---|
| 0x1000–0x1029 | 通信参数 | 0x1000设备类型、0x1005 SYNC COB-ID、0x1018厂商ID |
| 0x1200–0x12FF | SDO服务器参数 | 0x1200 SDO服务器参数 |
| 0x1400–0x1BFF | PDO通信与映射参数 | 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中通过数据类型名引用。常用基本类型:
| 类型名 | 位数 | 说明 |
|---|---|---|
| BOOLEAN | 1位(占1字节) | 0/1 |
| INTEGER8/16/32 | 8/16/32 | 有符号整数 |
| UNSIGNED8/16/32 | 8/16/32 | 无符号整数 |
| REAL32 | 32 | IEEE 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并重新导入主站。