本文主要介绍CiA DS301 V4.02
(CAN in Automation Draft Standard)和EN50325-4
(欧洲电工标准化委员会)中所规定的CANopen的技术内容。除了DS301
,还有许多其他与CANopen相关的标准由CiA发布,这些标准包括若干框架、设备描述和应用描述,这些将在后面的文章中介绍。
文章目录
1 标识符和对象
标识符(identifier
)和对象(object
)是两个很容易混淆的术语,然而CANopen中有许多种标识符和对象,因此识别它们之间的差异至关重要。
三种标识符
- 节点ID:用于识别特定的CANopen节点,节点ID的允许范围是1到127。
- 对象字典的索引和子索引(16位和8位的标识符):用于识别节点内的特定变量(可以是过程数据或配置数据)
- COB ID(连接对象ID):主要用于识别网络上的特定消息,此ID直接对应于CAN消息ID。它有如下特性:
- 唯一的
- 用于一个特定的通信通道(从一个节点到一个或多个其他节点)。
- 可能包含控制位,例如启用/禁用位。
对象
- 对象字典(OD):以某种查找表的形式存储变量和常量,包括过程数据和配置数据
- 过程数据对象(PDO):是包含过程数据的消息或帧
- 服务数据对象(SDO):是包含服务/配置数据的消息或帧
- 连接对象(COB):COB ID在需要分配消息或帧以实现服务时使用
- 例如:每个SDO需要分配两个COB ID,一个用于客户端向服务器发送请求,另一个用于服务器向客户端发送响应。
2 对象字典
在之前的文章中,我们简要讨论了对象字典(Object Dictionary
,OD
)。这一节我们深入介绍对象字典的组织结构、如何阅读CANopen规范中的对象字典条目、各种条目类型、对象字典包含的内容以及如何简化对象字典的访问。
2.1 定义
定义:
- 对象字典就像表格,包含所有网络可访问的数据。每个CANopen节点都必须实现自己的对象字典
- 对象字典描述了节点的CANopen配置和功能,可以被其他CANopen节点读取和写入
用途:
- 对象字典不仅存储节点的应用特定信息,还可以被网络上的其他节点使用
- 通过向节点的对象字典条目写入数据(有时通过读取数据),可以指示节点执行某种操作
- 例如采样当前温度,并将采样数据存储在对象字典中以供其他节点读取
信息获取:
- 通过读取节点的对象字典条目,其他节点可以了解该节点的功能和操作方式。
- 对象字典中包含的描述信息量可以根据网络设计的需求而有所不同,但有些信息是强制性的,必须存在。这些强制性信息取决于节点实现的CANopen功能。
例子
假设一个CANopen网络实现了一个精确控制电机的系统,电机的性能随温度变化而变化。
电机控制节点
- 控制电机节点的对象字典:可包含每个电机的当前位置,允许网络上的其他节点读取这些位置
- 其他节点可以向该节点的对象字典写入新位置,从而使该节点移动电机到所需位置
温度传感节点
另一个节点包含温度传感器,并知道温度如何影响电机性能
- 在网络启动时,网络主节点通过写入该节点的对象字典来存储初始校准数据
- 这些校准数据可以通过读取对象字典提供给网络上的其他节点
- 随着温度变化,该节点修改存储在其中的校准数据,因此其他节点通过读取对象字典可以获得最新的校准数据
2.2 组织和内容
对象字典被组织成一个包含多个条目的集合,有点像一张表。每个条目都有一个称为索引(Index
)的16位(即最大65536个条目)编号,用于访问该条目,另外,每个条目最多可以有256个子条目(Subentry
),用8位的子索引(Subindex
)进行引用。
- 只存储一个值的条目:只有在子索引00h处有一个子条目
- 存储多个值的条目:每个值有一个子条目,并在子索引00h处存储最高子条目的编号。
对象字典中的并非所有条目都被实现或使用,这在表中会产生空白。例如,索引为0000h - 09FFh的条目通常没有实现(用于未来扩展),但索引为1000h的条目总是实现的。
对象字典示例
(1)只存储一个值
假设条目在对象字典中的索引为2000h,索引2000h存储一个8位值:
- 子索引00h = 8位值
(2)存储2个值
假设条目在对象字典中的索引为2001h,索引2001h存储两个8位值:
- 索引2001h,子索引00h = 2
- 索引2001h,子索引01h = 第一个8位值
- 索引2001h,子索引02h = 第二个8位值
-
省略子索引:引用只有一个子索引的条目时,可以省略子索引,默认为子索引00h。
-
数据类型和内容:对象字典包含标准化和自定义的数据类型,存储CANopen通信配置、制造商特定信息和设备配置文件数据。
对象字典的65536个索引可被划分为多个部分,以组织和结构化存储数据:
索引范围 | 描述 |
---|---|
0000h | 保留 |
0001h - 0FFFh | 数据类型(Data Types) |
1000h - 1FFFh | 通信条目(Communication Entries) |
2000h - 5FFFh | 制造商规定(Manufacturer Specific) |
6000h - 9FFFh | 设备配置文件参数(Device Profile Parameters) |
A000h - FFFFh | 保留 |
下面就来详细介绍一下这些Index所对应的内容。
2.3 数据类型(Data Types)
对象字典中的数据类型部分(0001h-0FFFh)的条目不存储任何变量;它们仅用于定义数据类型。
- 如果在节点中物理实现了这些条目,读取这些条目会返回该数据类型的字节大小
- 如果该节点中未使用该数据类型,则返回错误
- 此机制允许配置工具读取数据类型部分,以确定节点中实际使用了哪些数据类型
对象字典可以存储标准/预定义的数据类型和制造商定义的数据类型。此外,CANopen 规范定义了两类基本数据类型:标准数据类型和复杂数据类型。为了组织用于定义数据类型的索引范围,对象字典的数据类型部分进一步细分:
索引范围 | 描述 |
---|---|
0001h – 001Fh | 标准数据类型 (Standard Data Types) |
0020h – 0023h | 预定义复杂数据类型 (Pre-defined Complex Data Types) |
0024h – 003Fh | 保留 (Reserved) |
0040h – 005Fh | 制造商复杂数据类型 (Manufacturer Complex Data Types) |
0060h – 007Fh | 设备配置文件标准数据类型 (Device Profile Standard Data Types) |
0080h – 009Fh | 设备配置文件复杂数据类型 (Device Profile Complex Data Types) |
00A0h – 025Fh | 多设备模块数据类型 (Multiple Device Modules Data Types) |
0260h – 0FFFh | 保留 (Reserved) |
多个设备模块数据类型在使用多个设备配置文件时,存储标准和复杂数据类型。在实现 CANopen 节点时,可以在对象字典的制造商复杂数据类型部分定义自定义复杂数据类型。
2.3.1 标准数据类型
下表列出了标准数据类型、它们的描述以及它们在对象字典中的定义位置。
标准数据类型 (Standard Data Type) | 描述 (Description) | 存储在 OD 索引 (Stored in OD Index) |
---|---|---|
BOOLEAN | 0 或 1 表示假或真 | 0001h |
INTEGER8 | 8位有符号整数 | 0002h |
INTEGER16 | 16位有符号整数 | 0003h |
INTEGER24 | 24位有符号整数 | 0010h |
INTEGER32 | 32位有符号整数 | 0004h |
INTEGER40 | 40位有符号整数 | 0012h |
INTEGER48 | 48位有符号整数 | 0013h |
INTEGER56 | 56位有符号整数 | 0014h |
INTEGER64 | 64位有符号整数 | 0015h |
UNSIGNED8 | 8位无符号整数 | 0005h |
UNSIGNED16 | 16位无符号整数 | 0006h |
UNSIGNED24 | 24位无符号整数 | 0016h |
UNSIGNED32 | 32位无符号整数 | 0007h |
UNSIGNED40 | 40位无符号整数 | 0018h |
UNSIGNED48 | 48位无符号整数 | 0019h |
UNSIGNED56 | 56位无符号整数 | 001Ah |
UNSIGNED64 | 64位无符号整数 | 001Bh |
REAL32 | 32位单精度浮点数 | 0008h |
REAL64 | 64位双精度浮点数 | 0011h |
VISIBLE_STRING | 包含可打印ASCII字符的文本字符串 | 0009h |
OCTET_STRING | 8位无符号整数数组 | 000Ah |
UNICODE_STRING | 16位无符号整数数组 | 000Bh |
TIME_OF_DAY | 自1984.1.1以来的天数和自午夜以来的毫秒数的48位值 | 000Ch |
TIME_DIFFERENCE | 表示天数和自午夜以来的毫秒数的48位值 | 000Dh |
DOMAIN | 数据块 | 000Fh |
- DOMAIN 类型是特定应用的数据块,可以是任意长度,这提供了一种开放且灵活的数据类型
- 由多个字节组成的数据类型使用小端格式进行传输
对象字典中的每个子索引都使用本节列出的标准数据类型之一。我们通常使用简写符号来泛指某些数据类型:
数据类型 (Data Type) | 描述 (Description) |
---|---|
INTEGERx | 使用 x 位存储的有符号整数 |
REALx | 使用 x 位存储的浮点值 |
UNSIGNEDx | 使用 x 位存储的无符号整数 |
VISIBLE_STRINGx | 包含 x 个字符的字符串 |
OCTET_STRINGx | 包含 x 个字节的字符串 |
例子
假设我们希望在对象字典中存储一个当前温度值。我们可以在对象字典条目2000h处使用REAL32类型。回想一下,每个对象字典条目必须至少有一个使用子索引00h的子条目。因此,在索引2000h,子索引00h处,数据类型将为REAL32。
一个CANopen节点也可以允许读取定义标准数据类型的对象字典条目。当读取这些条目时,它们返回数据类型的位大小。例如,类型UNSIGNED16在对象字典条目0006h处定义。当读取条目0006h时,它可以返回值16。
2.3.2 复杂数据类型
复杂数据类型是包含一个或多个标准数据类型组合在一起的类型,允许构建数据集,类似于C语言中的结构体。
复杂数据类型示例
假设我们希望存储错误消息的详细信息。我们需要知道错误编号和错误消息的文本。为此,我们可以定义一个名为ERROR_MESSAGE
的复杂数据类型:
UNSIGNED16
:错误编号VISIBLE_STRING
:错误文本
一旦定义了该类型,我们就可以在对象字典中使用它。例如,我们可以定义对象字典条目2000h - 200Fh的类型为ERROR_MESSAGE
,以创建一个存储16条错误消息的位置。对象字典条目2000h的子索引如下:
- 子索引00h - 存储值2,表示最高子索引为2
- 子索引01h - 类型为
UNSIGNED16
- 子索引02h - 类型为
VISIBLE_STRING
在CANopen规范中预定义了四种复杂数据类型:
数据类型 (Data Type) | 描述 (Description) | 在OD的索引 |
---|---|---|
PDO_COMMUNICATION_PARAMETER | 用于存储PDO通信参数的记录 | 0020h |
PDO_MAPPING | 用于存储PDO映射参数的记录 | 0021h |
SDO_PARAMETER | 用于存储SDO通信参数的记录 | 0022h |
IDENTITY | 用于存储身份信息的记录,如供应商ID和产品ID | 0023h |
仔细查看CANopen规范中PDO_COMMUNICATION_PARAMETER复杂数据类型的定义如下:
索引 | 子索引 | 名称 | 类型 |
---|---|---|---|
0020h | 00h | 最高子索引数量 (Number of highest Subindex) | UNSIGNED8 |
0020h | 01h | COB ID | UNSIGNED32 |
0020h | 02h | 传输类型 (Transmission Type) | UNSIGNED8 |
0020h | 03h | 抑制时间 (Inhibit Time) | UNSIGNED16 |
0020h | 04h | 保留 (Reserved) | UNSIGNED8 |
0020h | 05h | 事件定时器 (Event Timer) | UNSIGNED16 |
该类型由一组8位、16位和32位值组成。
- 有多个子索引时,子索引00h的类型总是UNSIGNED8,存储该对象字典条目中最高子索引的数量
读取复杂数据类型示例
假设前面提到的错误消息类型在制造商特定的复杂数据类型区域的索引0040h处定义。读取三个子索引中的每一个将返回以下值: 索引0040h:
- 子索引00h - 返回2,表示最高子索引数量
- 子索引01h - 返回06h,表示类型为UNSIGNED16
- 子索引02h - 返回09h,表示类型为VISIBLE_STRING
2.4 通信条目(Communication Entries)
对象字典中的通信条目描述了节点使用的 CANopen 通信的大部分方面,包括标识、通信参数、PDO 和 SDO 配置等。许多条目是可写的,或者可以设置为可写,从而允许网络上的其他节点配置该节点。通信条目占据对象字典中的索引范围1000h – 1FFFh
。
下表概述了所有的通信条目:
索引 (Index) | 名称 (Name) |
---|---|
1000h | 设备类型 (Device Type) |
1001h | 错误寄存器 (Error Register) |
1002h | 制造商状态寄存器 (Manufacturer Status Register) |
1003h | 预定义错误字段 (Pre-defined Error Field) |
1005h | 同步 COB ID (COB ID SYNC) |
1006h | 通信周期周期 (Communication Cycle Period) |
1007h | 同步窗口长度 (Synchronous Window Length) |
1008h | 制造商设备名称 (Manufacturer Device Name) |
1009h | 制造商硬件版本 (Manufacturer Hardware Version) |
100Ah | 制造商软件版本 (Manufacturer Software Version) |
100Ch | 保护时间 (Guard Time) |
100Dh | 生命周期因子 (Life Time Factor) |
1010h | 存储参数 (Store Parameters) |
1011h | 恢复默认参数 (Restore Default Parameters) |
1012h | 时间 COB ID (COB ID Time) |
1013h | 高分辨率时间戳 (High Resolution Time Stamp) |
1014h | 紧急 COB ID (COB ID EMCY) |
1015h | 抑制时间 EMCY (Inhibit Time EMCY) |
1016h | 消费者心跳时间 (Consumer Heartbeat Time) |
1017h | 生产者心跳时间 (Producer Heartbeat Time) |
1018h | 身份对象 (Identity Object) |
1200h – 127Fh | 服务器 SDO 参数 (Server SDO Parameters) |
1280h – 12Fh | 客户端 SDO 参数 (Client SDO Parameters) |
1400h – 15FFh | 接收 PDO 通信参数 (RxPDO Communication Parameters) |
1600h – 17FFh | 接收 PDO 映射参数 (RxPDO Mapping Parameters) |
1800h – 19FFh | 发送 PDO 通信参数 (TxPDO Communication Parameters) |
1A00h – 1BFFh | 发送 PDO 映射参数 (TxPDO Mapping Parameters) |
其中强制性条目(必须在节点中实现)如下:
(1)设备类型 (1000h)
设备类型是一个32位的值,用于有限地描述节点的一些功能。例如,它可以描述节点是否是数字输入/输出模块,如果是的话,还可以描述是否实现了输入和/或输出功能。
(2)错误寄存器 (1001h)
错误寄存器是一个8位的值,可以指示节点中是否发生了各种常见错误,例如电流错误、温度错误、通信错误等。唯一必须实现的位是通用错误位。还有一个制造商特定位,用于指示应用特定的错误。此字节也会在紧急对象(Emergency Objects)中传输。
(3)保护时间 (100Ch)
节点必须支持心跳或节点监护这两种机制。两种机制将在本章稍后讨论。总结来说,这些机制允许节点确定特定节点是否存活、正常工作并能够与网络通信,以及节点的当前状态。保护时间是一个16位的值,指定主节点发送或节点必须接收到的节点监护请求的频率。如果不使用心跳机制,则必须实现此条目。
(4)生命周期因子 (100Dh)
生命周期因子是一个8位的值,与保护时间一起工作。它指定在没有从主节点传输或从从节点接收到响应的情况下,必须经过多少个保护时间的倍数后才会生成错误状态。如果不使用心跳机制,则必须实现此条目。
(5)生产者心跳时间 (1017h)
如果节点不使用节点监护,则必须实现心跳机制。此条目指定节点应如何频繁地传输心跳消息。可以将其设置为零以禁用心跳传输。如果不使用节点监护,则必须实现此条目。
(6)身份对象 (1018h)
身份对象提供关于节点的识别信息。它必须至少包含由CAN自动化组织分配的供应商ID,该ID对于特定供应商是唯一的。它还可以包含用于识别节点所在产品的产品代码、修订号和序列号。
2.6 制造商特定条目(Manufacturer Specific Entries)
对象字典的这一部分,使用索引范围从 2000h 到 5FFFh,由 CANopen 规范完全开放,供应用特定使用。每当应用程序需要存储数据或配置操作且这些内容不属于CANopen标准(包括框架、设备配置文件和其他标准)时,就可以定义在对象字典的这一部分。
制造商特定条目示例
假设我们的节点具有一个实时时钟。我们希望将当前时间更新到对象字典条目中。就可以在制造商定义以下对象字典条目来实现这一点: 索引 2000h:
- 子索引 00h - 3 (UNSIGNED8)
- 子索引 01h - 小时 (UNSIGNED16)
- 子索引 02h - 分钟 (UNSIGNED8)
- 子索引 03h - 秒 (UNSIGNED8)
2.7 设备配置文件参数(Device Profile Parameters)
CANopen 规范 [CiADS301] 提供了多种通信服务。一旦实现了特定节点,节点的设计者(或其将要使用的网络的设计者)必须指定使用哪些通信服务以及如何使用。设备配置文件指定了节点所知道的过程数据变量以及默认配置和通信设置。有专有配置文件,以及 CiA 标准化的设备配置文件和应用配置文件。
CiA 设备配置文件标准化了特定类型的节点,例如通用输入/输出模块。为各种设备类型发布了规范,为了实现这些规范,它们使用位于设备配置文件参数部分的对象字典条目。
设备配置文件示例
在设备配置文件 CiA DS 401 通用 I/O [CiADS401] 中,对象字典条目 6000h 允许一次读取最多 2032 个数字输入,每次 8 位。 索引 6000h:
索引 (Index) | 子索引 (Subindex) | 名称 (Name) | 类型 (Type) |
---|---|---|---|
6000h | 00h | 1 – 254 | UNSIGNED8 |
6000h | 01h | 读取输入 1 – 8 (Read inputs 1 – 8) | UNSIGNED8 |
6000h | 02h | 读取输入 9 – 16 (Read inputs 9 – 16) | UNSIGNED8 |
6000h | – | – | – |
6000h | – | – | – |