4. 对象字典文件(OD文件)详解:EDS/DCF/XML与手动创建

对象字典(Object Dictionary)是CANopen设备的灵魂。而OD文件,就是把这个灵魂用标准格式写下来的文档。说白了,你设备能干什么、怎么配置、数据怎么交换,全写在这几个文件里。

我刚开始接触CANopen时,总觉得OD文件就是个配置文件,随便改改就行。直到有一次,一个字节的偏移量写错,整个网络都起不来。嗯,从那以后,我再也不敢小看这些文件了。

4.1 EDS文件:设备的身份证

EDS(Electronic Data Sheet)是最基础的OD文件格式。它用纯文本描述设备的所有对象字典条目。每个从站设备出厂时,厂商都会提供一个EDS文件。

EDS文件的结构很简单,就是标准的INI文件格式。我习惯把它分成三大块:

  • [FileInfo]:文件头,描述版本、创建日期、厂商信息
  • [DeviceInfo]:设备信息,包括ID、波特率、支持的协议
  • [Index]:对象字典条目,每个索引一个段落

核心要点:EDS文件是只读的,描述设备的能力。你不能通过修改EDS来改变设备行为,它只是告诉你设备长什么样。

来看一个实际的EDS片段:

; EDS文件示例 - 某IO模块
[FileInfo]
FileName=IO_Module_V1.eds
FileVersion=1
FileRevision=1
CreationDate=2024-01-15
CreatedBy=MyCompany

[DeviceInfo]
VendorName=MyCompany
ProductName=IO_Module_8DI_8DO
ProductNumber=IM-8801
RevisionNumber=1
BaudRate_10=1
BaudRate_20=1
BaudRate_50=1
BaudRate_125=1
BaudRate_250=1
BaudRate_500=1
BaudRate_800=1
BaudRate_1000=1
SimpleBootUpMaster=0
SimpleBootUpSlave=0

[1000]
ParameterName=Device Type
ObjectType=0x07
DataType=0x0007
AccessType=ro
DefaultValue=0x00000191
PDOMapping=0

[1001]
ParameterName=Error Register
ObjectType=0x07
DataType=0x0005
AccessType=ro
DefaultValue=0
PDOMapping=1

我的经验:写EDS时,AccessType最容易出错。ro/rw/wo一定要和实际硬件设计一致。我曾经把配置参数写成ro,结果现场改不了,只能重新烧固件。

4.2 DCF文件:设备的配置单

DCF(Device Configuration File)和EDS格式一模一样,但多了一个关键字段——DefaultValue可以被覆盖。说白了,DCF就是EDS的"已配置版本"。

为什么需要DCF?你想想看,一个IO模块出厂时默认地址是1,波特率125k。但现场需要地址5、波特率500k。你不可能改EDS(那是只读的),但可以生成一个DCF,把新配置写进去。

特性 EDS DCF
用途 设备描述 设备配置
可写性 只读 可写
DefaultValue 厂商预设 用户自定义
典型场景 选型、开发 现场部署

DCF文件里,每个索引段可以加一个DefaultValue覆盖原始值。比如:

[1010]
ParameterName=Store parameters
ObjectType=0x07
DataType=0x0007
AccessType=rw
DefaultValue=0x00000000  ; 默认不存储
; 现场改为自动存储
; DefaultValue=0x65766173

注意:DCF文件必须和对应的EDS保持结构一致。你不能在DCF里新增EDS没有的索引,否则配置工具会报错。我见过有人直接复制EDS改后缀当DCF用,结果少了一个索引,整个网络配置失败。

4.3 XML对象字典描述:更现代的方式

EDS/DCF虽然简单,但有个硬伤——不支持层级结构。复杂设备(比如伺服驱动器)的对象字典可能有几百个条目,用INI格式写出来就是一锅粥。

XML格式就优雅多了。它用标签嵌套表达层级关系,还支持命名空间、注释、校验。CANopenNode官方推荐用XDD(XML Device Description)格式。

一个典型的XML OD片段长这样:

<?xml version="1.0" encoding="UTF-8"?>
<OD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Device>
    <VendorName>MyCompany</VendorName>
    <ProductName>ServoDrive_SD200</ProductName>
    <RevisionNumber>1</RevisionNumber>
  </Device>
  
  <Dictionary>
    <Index index="0x1000">
      <Name>Device Type</Name>
      <ObjectType>7</ObjectType>
      <DataType>7</DataType>
      <AccessType>ro</AccessType>
      <DefaultValue>0x00020192</DefaultValue>
    </Index>
    
    <Index index="0x1600">
      <Name>Receive PDO 1 Mapping</Name>
      <ObjectType>8</ObjectType>
      <SubIndex subIndex="0">
        <Name>Number of Entries</Name>
        <DataType>5</DataType>
        <AccessType>rw</AccessType>
        <DefaultValue>3</DefaultValue>
      </SubIndex>
      <SubIndex subIndex="1">
        <Name>Entry 1</Name>
        <DataType>7</DataType>
        <AccessType>rw</AccessType>
        <DefaultValue>0x20000108</DefaultValue>
      </SubIndex>
    </Index>
  </Dictionary>
</OD>

我的建议:如果你用CANopenNode开发新项目,直接用XML格式。它更容易维护,也方便用工具做自动化校验。EDS/DCF更适合对接传统配置工具。

4.4 手动创建OD文件:从零开始

有时候你手头没有现成的OD文件,或者需要快速验证一个想法。这时候手动创建就派上用场了。我一般按这个步骤来:

  1. 确定设备类型:是IO模块、驱动器还是编码器?这决定了强制索引(1000h-100Fh)的内容。
  2. 列出通信参数:波特率、节点ID、PDO数量、SDO通道数。
  3. 定义应用对象:输入输出数据、配置参数、诊断信息。
  4. 分配索引:遵循CiA标准,不要乱用保留区域。
  5. 填写属性:数据类型、访问权限、PDO映射能力。

下面是我手写的一个最小EDS示例,适合一个只有4路数字量输入的简单设备:

[FileInfo]
FileName=Simple_DI_4ch.eds
FileVersion=1
CreationDate=2024-03-01
CreatedBy=HandWritten

[DeviceInfo]
VendorName=Demo
ProductName=DI_4
RevisionNumber=1
BaudRate_125=1
BaudRate_250=1
BaudRate_500=1

[1000]
ParameterName=Device Type
ObjectType=0x07
DataType=0x0007
AccessType=ro
DefaultValue=0x00000191

[1001]
ParameterName=Error Register
ObjectType=0x07
DataType=0x0005
AccessType=ro
DefaultValue=0

[1018]
ParameterName=Identity Object
ObjectType=0x08
SubNumber=4

[1018sub0]
ParameterName=Max SubIndex
ObjectType=0x07
DataType=0x0005
AccessType=ro
DefaultValue=4

[1018sub1]
ParameterName=Vendor ID
ObjectType=0x07
DataType=0x0007
AccessType=ro
DefaultValue=0x00000001

[6000]
ParameterName=Read Inputs 8-bit
ObjectType=0x07
DataType=0x0005
AccessType=ro
DefaultValue=0
PDOMapping=1

避坑指南:我曾经手写EDS时漏了SubNumber字段,结果配置工具死活不认。记住,所有复合对象(ObjectType=8)都必须显式声明子索引数量。

4.5 三种格式的对比与选择

我把三种格式的优缺点整理了一下,方便你根据场景选择:

格式 优点 缺点 适用场景
EDS 简单、兼容性好 无层级、难维护 简单设备、传统工具
DCF 可配置、现场友好 依赖EDS、易出错 批量部署、现场调试
XML 结构清晰、可校验 文件大、工具要求高 复杂设备、新项目

我个人习惯是:原型阶段用EDS快速验证,产品化后转XML。DCF只在现场部署时用,平时不碰。

4.6 OD文件的核心结构图

下面这张图展示了OD文件从设备描述到具体索引的完整层级关系。你可以看到,不管是EDS还是XML,最终都映射到同一个对象字典结构。

OD文件结构层级图 OD文件 EDS格式 DCF格式 XML格式 [FileInfo] 文件头 [FileInfo] 文件头 <Device> 设备信息 [DeviceInfo] 设备信息 [DeviceInfo] 设备信息 <Dictionary> 字典 [1000] 设备类型 [1000] 设备类型 <Index index="0x1000"> ObjectType/DataType ObjectType/DataType <ObjectType>/<DataType> DefaultValue=0x... DefaultValue=0x... <DefaultValue>0x...</DefaultValue> 三种格式最终都映射到相同的对象字典结构,只是表达方式不同

从这张图可以看得很清楚:不管用哪种格式,最终描述的都是同一个东西——索引、子索引、数据类型、访问权限、默认值。格式只是载体,内容才是核心。

总结一下:EDS是身份证,DCF是配置单,XML是更现代的身份证+配置单。手动创建时,先确定设备类型,再列通信参数,最后填应用对象。别漏了SubNumber,别写错AccessType——这些都是我踩过的坑。