CANopen

CANopen是一种架构在控制器区域网路（Controller Area Network, CAN）上的高层通讯协定，包括通讯子协定及设备子协定常在嵌入式系统中使用，也是工业控制常用到的一种现场总线。
CANopen实作了OSI模型中的网路层以上（包括网路层）的协定。CANopen标准包括定址方案、数个小的通讯子协定及由设备子协定所定义的应用层。CANopen支援网路管理、设备监控及节点间的通讯，其中包括一个简易的传输层，可处理资料的分段传送及其组合。一般而言资料链结层及实体层会用CAN来实作。除了CANopen外，也有其他的通讯协定（如POWERLINK及EtherCAT）实作CANopen的设备子协定。
基本的CANopen设备及通讯子协定定义在CAN in Automation (CiA) draft standard 301.。针对个别设备的子协定以CiA 301为基础再进行扩充。如针对I/O模组的CiA401及针对运动控制的CiA402。

**设备模型**
以下是所有CANopen设备都要具备的功能：- 通讯单元处理和网路上其他模组通讯所需要的通讯协定。- 设备的启动及重置由状态机（state machine）控制。状态机需包括以下的几个状态：Initialization, Pre-operational, Operational及Stopped。当接收到网路管理（NMT）通讯物件，状态机会转换到对应的状态。- 物件字典（Object Dictionary）是一个有16位元索引（Index）的变数阵列。每个变数可以（但非必须）有8位元的子索引（Subindex）。变数可用来调整设备的组态，也可以对应设备量测的资料或设备的输出。- 当状态机设定为operational　之后，设备的应用（application）部份就会实现设备预期的机能。此部份可以由物件字典中的变数调整其设定，而资料由通讯层传收或接收。

**物件字典**
CANopen设备都需要具备物件字典，用来设定设备组态及进行非即时的通讯。物件字典的entry定义如下：- 索引（Index）：物件16位元的位址。- 物件名称（Object name）：一个代表物件的symbolic type，可以是阵列、纪录或只是一个变数。- 名称（Name）：描述此entry的字串。- 形态（Type）：变数的资料形态。- 属性（Attribute）：提供此entry是否可读／可写的资料，有下列四种：可读/写、唯读、唯写、唯读常数。- 必须（Mandatory）/可选（Optional）栏位定义属于特定设备规范下的设备，是否必须实现某些物件。
在CANopen标准中定义了物件字典中的基本资料型态，包括逻辑值、整数及浮点数。也定义了复合物件：如阵列、记录及字串。复合物件用一个8位元的数值作为其子索引（subindex）。记录或阵列中子索引0的位置记录此资料结构的元素个数，资料型态为UNSIGNED8。
例如在CiA301标准中，设备通讯的参数放在索引范围0x1000 - 0x1FFF（通讯行规区）。此区域的前几项如下：
若配合适当的工具，可以用编辑电子资料表（electronic data sheet, EDS)档案的方式规划一个设备，并且将变数的数值上传到设备中。EDS档案的格式通常会是INI档。

**通讯**

**通讯物件**
CANopen的物理层CANbus每次传送的资料量不大，其中包括11位元的ID、远端传输请求（RTR）位元及大小不超过8位元组的资料。CANopen将CANbus 11位元的ID分为4位元的功能码及7位元的CANopen节点ID。7位元的ID共有128种不同的组合，其中ID 0不使用，因此一个CANopen网路上最多允许127台设备。CANbus在CAN 2.0 B规格中允许29位元的ID，因此若配合CAN 2.0 B使用，CANopen网路上可以超过127台设备，不过在实际运用中，大多数的CANopen网路上设备数量均低于此数值。
CANopen将CANbus的11位元ID称为通讯物件ID（COB-ID）。当传输资料出现碰撞时，CANbus的仲裁机制会使COB-ID最小的讯息继续传送，不用等待或重传。COB-ID的前4个位元是CANopen的功能码，因此数值小的功能码表示对应的功能重要，允许的延迟时间较短。
以下是一个标准的CANopen页框（frame）：
在CANopen标准中，部份COB-ID被保留作网路管理及SDO通讯用。而在设备初始化后，有些功能码和COB-ID会对映到标准的功能，不过后续仍可以规划为其他用途。

**通讯模型**
CANopen设备间的通讯可分为以下三种通讯模型。
*在主从（master/slave模型）中，一个CANopen设备为master，负责传送或接收其他设备（称为slave）的资料。NMT协定就使用了master/slave模型。
*客户端/服务器（client/server）模型定义在SDO协定中，SDO client将物件字典的索引及子索引传送给SDO server，因此会产生一个或数个需求资料（物件字典中，索引及子索引对应的内容）的SDO封包。
*生产者／消费者（producer/consumer）模型用在Heartbeat and Node Guarding协定。由一个生产者送出资料给消费者，同一个生产者的资料可能给一个以上的消费者。又可分为二种：
**push-model：生产者会自动送出资料给消费者。
**pull-model：消费者需送出请求讯息，生产者才会送出资料。

**协议**

**NMT协议**
NMT（网路管理, Network management）协议是用来发布（设备内部）状态机的状态变更命令（如启动设备或停止设备）、以及监测远端设备启动及故障情形。
NMT master使用的模组控制协定可变更设备的状态。其COB-ID为0，其功能码及节点ID均为0，因此网路上的所有节点均会处理这个讯息。在此讯息的资料部份会有此讯息实际针对节点的ID，此ID也可为0，表示所有节点都要变更为指定的状态。
心跳协定（Heartbeat protocol）是用心跳机制来监控网路中的节点及确认其正常工作。心跳讯息的生产者（一般是slave设备）周期性的送出功能码1110、ID为本身节点ID的讯息，讯息的资料部份有一个表示节点状态的位元。而心跳讯息的消费者负责接收上述资料，若在指定时间（于设备的物件字典中定义）内，消费者均未收到讯息，可采取相关行动（例如显示错误或重置该设备）。
其格式为：    
COBID + DATA (status of node)  
CANopen设备需要在bootup时自动从Initializing状态切换至Pre-operational状态，设备会在切换完成后送出一个心跳讯息，这就是心跳协定。
有一种pull model的NMT协定，称作节点监控（Node guarding）协定，也可以作从机的监控。

**服务资料物件（SDO）协定**
服务资料物件（SDO）可用来存取远端节点的物件字典，读取或设定其中的资料。提供物件字典的节点称为SDO server，存取物件字典的节点称为SDO client。SDO通讯一定由SDO client开始，并提供初始化相关的参数。
在CANopen的术语中，上传是指由SDO server中读取资料，而下载是指设定SDO server的资料。
由于物件字典中的资料长度可能超过8个位元组，无法只用一个CAN页框传输，SDO也支援长讯息的分割（segmentation）和合并（desegmentation）。这样的物件有二种：SDO下载/上传（SDO download/upload）及SDO区块下载/上传（SDO Block download/upload）。CANopen协定较新版本支援SDO区块传输，可以允许传输大量的资料，且传输的overhead可以较低。
负责处理SDO资料传输的COB ID可在物件字典中设定。在物件字典的索引0x1200至0x127F可设定SDO server的COB ID，最多可设定到127个。而SDO client可以在物件字典的索引0x1280至0x12FF中设定。不过预定义连结（pre-defined connection set）定义在开机后（Pre-operational状态）可用来设定设备组态的SDO。接收用的COB ID为0x600 +节点ID，而传送用的COB为0x580 +节点ID。
以下用SDO下载来说明SDO的协定，SDO client在要启始下载时，会送出CAN讯息，其ID为接收端SDO channel的COB ID，而CAN页框的资料栏位内容如下：- ccs是SDO传输时client指令的识别码，可分为以下几种：
** 0：SDO区域下载
** 1：启始下载
** 2：启始上传
** 3：SDO区域上传
** 4：中断SDO传输- n为此讯息中实际资料的长度，只有在e和s设定时有效- e若设为1，表示是快速传输（expedited transfer），目前讯息即包括了所有要传输的资料。若设为0，表示要传输的资料无法用一个讯息传送，会分割为数个讯息。   - s若设为1，且e也设为1，表示资料长度记录在n。若e设为0，表示实际完整资料的长度会放在此讯息中的资料栏位中。- 索引是要存取资料的物件字典索引。- 子索引是要存取变数的子索引。- 资料在快速传输（e=1）时是要上传的资料，若s=1且e=0，则是实际资料的长度。

**-{zh-hans:进程数据对象; zh-tw:程序资料物件}-（PDO）协定**
-{zh-hans:进程数据对象; zh-tw:程序资料物件}-（PDO）协定可用来在许多节点之间交换即时的资料。可透过一个PDO，传送最多8位元组（64位元）资料给一设备，或由一设备接收最多8位元组（64位元）的资料。一个PDO可以由物件字典中几个不同索引的资料组成，规划方式则是透过物件字典中对应PDO mapping及PDO参数的索引。
PDO分为两种：传送用的TPDO及接收用的RPDO。一个节点的TPDO是将资料由此节点传输到其他节点，而RPDO则是接收由其他节点传输的资料。一个节点分别有4个TPDO及4个RPDO。
PDO可以用同步或非同步的方式传送：同步的PDO是由SYNC讯息触发，而非同步的PDO是由节点内部的条件或其他外部条件触发。例如若一个节点规划为允许接受其他节点产生的TPDO请求，则可以由其他节点送出一个没有资料但有设定RTR位元的TPDO（TPDO请求），使该节点送出需求的资料。　   
借由RPDO也可以使两个或两个以上的设备同时启动。只要将其RPDO对应到相同的TPDO即可。

**同步（SYNC）协定**
同步协定使用生产者/消费者模型。同步生产者（Sync-Producer）会定时产生同步讯号供同步消费者（Sync-Consumer）使用。当同步消费者收到讯号，即可进行已规划好的同步工作。
同步讯号会定时产生，若有 PDO 是由同步讯号引发，透过 PDO 传送时间及同步讯号传送周期之间的调整，可以使感测器定期的取様，而致动器也可以根据最新的输入讯号产生对应的输出。
在物件字典中，同步物件的索引为0x1005，可透过编辑此物件启动同步协定。

**时间标记物件（TIME）协定**
一般而言，时间标记物件的内容是从1984年1月1日午夜之后到现在之间经过的时间，单位为毫秒。为一个48位元（6位元组）的数值。
不过有些应用会要求时间要非常精确，这种情形会需要精准的同步，尤其是在大型网路，通讯速度受限时更是如此。此时需要将各设备的时钟同步，精准度要到毫秒的等级。这个要求可透过高解析度的同步信号达成，在同步信号中也包括了另一种时间标记，可供各设备调整时钟用。
同步信号中的时间标记型态为unsigned32，单位为1毫秒，因此时间标记会在每72分钟归零重新计数。

**紧急物件（EMCY）协定**

**初始化**
以下是在master初始化2个压力感测器（ID分别为1和2）中，通讯的资料。

**CANopen专有名词**
PDO程序资料物件 - 对应实际物理量的输入及输出。资料的单位可能是RPM, V, Hz, mAmp...。
*SDO服务资料物件 - 一般来说是组态设定的资料，如节点位置、节点ID、通讯速度、位移、增益等……。
*COB-ID - CAN物件编号
*CAN ID - CAN Identifier.是在每个CAN讯息前面的讯息识别码，共11位元。
*EDS - 电子资料档（Electronic data sheet）是INI格式的档案。
*DCF - 设备组态档案（Device configuration file），是加强版的EDS，可以设定节点ID及通讯速度。

**参照**
 控制器区域网路（CAN）- DeviceNet（另一种使用CAN的工业通讯定）

**参考资料**

**外部连结**
 CAN in Automation的CANopen简介date=20160816094147 - CANopen简介（www.esacademy.com）date=20080219103651 - CANopen的教学网页（softing.com）date=20080308124350 - CANopen开发资料（canopendesign.com）- CAN-wiki中CANopen的页面date=20080421112709 - CANopen: An Introduction- 关于About CANopen（canopensolutions.com）fix-attempted=yes - CANopen-Lift社群的WIKIdate=20190924182232 - Introduction to CANopen基础介绍（www.canopen-solutions.com）date=20080520124505 -  CanFestival - 一个开放源码多平台CANopen的计划date=20080516175036