CANOpen对象字典的分析与具体实现
CANopen是基于CAN总线的开放的、标准化的应用层协议,对象字典是其核心概念。本文在对CANopen对象字典进行介绍与分析后,给出了一种数组形式的对象字典具体实现方法;对不同保存属性对象的存储策略进行了讨论,并给出了对象字典的存储与读写访问方法。关键词:CANopen;对象字典;静态数组中图分类
CANopen协议是在CAN总线的基础上定义的应用1 对象字典的协议规范分析层协议,是具有高度灵活配置能力的标准化嵌入式网络协议。因其协议精练、透明、便于理解,又具有实时性和可靠1.1 对象字典的概念性高、数据传输速率高、组网成本低等优点,在多个领域中对象字典(Object Dictionary,OD)是一个有序的对象
组,用来提供对设备所有重要数据、参数和功能的访问(无得到了广泛的应用。论远程或本地)。这种访问是基于一种索引和子索引的逻对象字典是CANopen协议的重要组成部分,CAN-辑地址体系实现的。对于每一个CANopen设备,对象字
open网络中每个节点都有一个对象字典。对象字典包含典结构都是相同的,这为通信参数、制造商定义对象和设了描述这个设备和它的网络行为的所有参数,以标准化的备对象提供了一套标准化的地址空间。方式描述了CANopen设备,是通信网络与应用程序之间1.2 对象字典中对象的结构的接口。
在CANopen协议栈的实现中,对象字典的构建与访对象字典中的元素,即各种通信对象和应用对象,使
问是其中的重点与难点。良好的对象字典实现是CANo-用标准的方式描述,对象的结构如下所示:
pen协议栈高效稳定运行的基础。但在CANopen的协议规范中,只有eds与dcf文件用来描述对象字典的构成与
具体的对象数据,而对具体程序中的对象字典实现没有规范。目前国内学者对CANopen协议的研究和使用中,较少涉及到对象字典的具体实现方法。
本文的对象字典实现采用了静态数组的形式,在国外开源协议栈CanFestival的对象字典实现基础上,增加了对象字典的存储方法;并分析了不同对象的存储与访问策 可以看出,描述对象字典中对象的结构有6个属性。 “索引”表示对象在对象字典中的位置;“对象类型”的定义如表1所列,在对象字典中,“VAR”、“ARRAY”和“RECORD”为常用的对象类型,子索引主要用来访问“ARRAY”和“RECORD”中的子项,“VAR”类型的子索引为0;“对象名称”以简单的文字描述了对象的功能;“数据类型”给出了对象所属的数据的类型;“访问属性”给出了对象的被访问权限;“必选/可选”定义了对象在对象字典中的实现要求。
索引 |
对象类型 |
对象名称 |
数据类型 |
访问属性 |
必选/可选 |
表1 对象类型的定义
对象类型 |
注 释 |
NULL |
没有数据 |
DOMAIN |
具有大量变量的数据,例如可执行程序代码 |
DEFTYPE |
类型的定义,如Boolean、UNSIGNED16等 |
DEFSTRUCT |
定义新的RECORD类型 |
VAR |
一个单一值 |
ARRAY |
数组类型的数据 |
RECORD |
由多种单一数据组成的结构类型 |
1.3 对象字典的布局
对象字典的布局如表2所列。其中,0x0001~0x009F是对数据类型的定义,不必在程序中具体实现。0x1000~0x1FFF是通信子协议区域,描述设备在CANopen网络中通信及交换数据所必须具备的基本功能。其内容包括设备类型、制造商信息、PDO通信参数及映射参数、SDO服务器及客户端的参数等。这个范围内定义的通信参数适用于所有的CANopen设备。0x2000~0x5FFF是预留给制造商定义的区域,用来描述在标准设备子协议中没有规定的设备对象。0x6000~0x9FFF为标准设备子协议区域,描述了如I/O设备、传感器、驱动和运动控制等设备接入CANopen网络的标准化规范。目前,CANopen标准设备子协议还在不断丰富和完善中。
表2 对象字典布局
索引(hex) |
对 象 |
0000 |
保留 |
0001~001F |
基本数据类型 |
0020~003F |
复杂数据类型 |
0040~005F |
制造商规定的数据类型 |
0060~007F |
设备子协议的基本数据类型 |
0080~009F |
设备子协议的复杂数据类型 |
00A0~0FFF |
保留 |
1000~1FFF |
通信子协议区域 |
2000~5FFF |
制造商特定子协议区域 |
6000~9FFF |
标准设备子协议区域 |
A000~BFFF |
标准接口子协议区域 |
C000~FFFF |
保留 |
具体的CANopen节点设备开发中,只需实现自己应用相关的对象字典条目,而不必实现全部内容。即便是在通信子协议区域,强制实现的对象也仅有几个。
2 对象字典的具体实现
对象字典是CANopen设备模型的核心,是连接通信与应用的接口。但在具体开发中,对象字典的实现有很大的自由度。对于一些简单的节点设备,甚至不需要在程序中实现对象字典的实体,只把对象字典的概念留在逻辑层面。良好的对象字典的实现,有利于发挥CANopen协议便于配置、灵活高效的优势,有利于节点设备的开发与升级。
对象字典的逻辑结构为线性结构,若以数组形式建立
完整的对象字典表格,则可以通过索引快速地访问对象条
目。但在具体的节点设备中建立完整的数据字典表格是
不太现实的,因为一般嵌入式系统存储资源有限,而且具
体的CANopen设备也只用到有限的对象字典条目。本文
参考了国外开源协议栈CanFestival的对象字典实现思
想,即将使用的对象字典条目按照静态数组结构存储,再
建立一个索引表,通过查找索引表定位到要访问的对象字
典条目。
对于CANopen从站设备,对象字典结构在运行前已确定,运行时无需动态改变对象字典结构,所以采用静态数组结构的对象字典实现可以满足大多数CANopen应用开发的要求。
2.1 对象字典的建立
对象字典的实体采用静态数组加对象条目索引表的
方式,描述语言为C语言。首先给出相关结构体的定义。
对象字典中一个子索引对应的数据条目的结构体定义如下:typedef uct s_ODEntry{
ui AeType;
uin DataType;
uint3 size;
storeAribute*storeAri;
void*pObject;
}ODEntry;
其中AeType为对象的访问权限;DataType为对象条目的数据类型;size为数据大小;storeAri为对象条目的存储属性;pObject为指向对象数据的指针。本文所使用的外部非易失性存储器为AT45DB系列Flash存储器,存储属性有4个,分别为对象存储类型、外部Flash的页地址、页内偏移地址和存储空间大小。
对象字典中一个对象索引条目的结构体定义如下:typedef struct s_indexTable{
ODEntry*pEntry;
uint8_t subCount;uint16_t Index;}indextable;其中pEntry指向数据字典条目;subCount为子索引个数;Index为条目的索引号。
利用“ODEntry ”类型可以构建索引对象的条目,以建立索引号为0x1000的设备类型对象为例,如下所示:/*index 0x1000:设备类型*/const uint32_t DeviceType=0x06000000;storeAribute store_obj1000={0,0,0,0};ODEntry ObjDict_Index1000[]={ {RO,uint32,sizeof(uint32_t),&store_obj1000,(void*)
&DeviceType}};
利用“indextable ”类型可以构建整个对象字典的数组形式的实体,如下所示:indextable ObjDict_objdict[]={
{ObjDict_Index1000,1,0x1000}//0 {ObjDict_Index1001,1,0x1001}1 {ObjDict_Index1008,1,0x1008},2
......
};
然后建立一个对象字典条目索引和在对象字典实体中实际存储位置相对应的索引表。通过条目索引查找整个索引表,根据实际的存储位置,定位到要访问的对象条目。
2.2 对象字典的存储与访问
上一小节中构建了对象字典的数组存储结构。对象字典条目所属的数据对象有着不同的存储与访问要求,读写属性上有只读、只写和可读写3种类型,存储属性上分为掉电丢失和掉电保存2种类型。
在上述定义的对象字典对象条目的结构体中,有一项为数据保存属性,具体定义数据的存储类型以及在外部非易失性存储器中的存储位置及存储空间的大小。存储类型指明了对象字典条目的保存类别,存储位置则只对需要掉电丢失的对象数据起作用,表明了数据在非易失性存储器中的存储位置。
下面给出不同存储类型对象的存储方法:
- ①只读属性的数据,如设备类型、制造商标识等对象数据,变量直接定义为const类型,随程序存储在片内Flash区域。
- ②不需要掉电保存的过程数据,以普通变量的形式存储在RAM中。
③简单的系统配置数据,如SDO客户端的通信参数,存储于片外Flash中,并在RAM中建立变量,便于应用程序与协议程序的使用。这类变量在系统初次运行时将默认的参数载入到片外Flash中,以后每次上电从片外Flash中读取,覆盖掉RAM中的初始默认值。
④复杂的系统配置数据。可以直接存储到片外Flash中,不在RAM中建立相应变量。应用程序可直接从片外Flash中读取相应配置数据。
对象字典的访问通过建立一个读取与写入对象字典接口进行。首先根据索引定位到要访问的对象条目,再根据数据类型与访问属性等信息对对象数据进行读写访问。但不是所有的数据访问都要经过这个接口,在应用程序端,对象字典数据的访问可以直接通过数据对象所指向的内存中的变量进行,或者直接读写对象在外部存储器中的数据。在通信端,对象字典的访问主要通过服务数据对象(SDO)进行。其他网络节点通过被访问节点的SDO服务器读写被访问节点的对象字典。SDO的数据传输方式有3种:加速传输(用于传输少于4个字节的数据)、分段传输(用于传输大于4个字节的数据)和分块传输(比分段传输更高的传输效率)。对传输少量数据的加速传输和分段传输来说,可以建立通信数据的缓冲区,这样就只需访问对象字典一次;而对分块传输来说,因为数据量较大,不能在RAM中缓冲所有块的数据,所以块传送需要多次访问对象字典。
canopen