文章目录
CAN 是Controller Area Network 的缩写,是ISO国际标准化的串行通信协议。1986 年德国电气商博世公司开发出面向汽车的CAN 通信协议。此后,CAN 通过ISO11898 及ISO11519 进行了标准化。
与一般的通信总线相比,CAN总线的数据通信具有突出的可靠性、实时性和灵活性。CAN被公认为几种最有前途的现场总线之一。其典型的应用协议有:SAE J1939/ISO11783、CANOpen、CANaerospace、DeviceNet、NMEA 2000等。
在CAN2.0B的版本协议中有两种不同的帧格式,不同之处为标识符域的长度不同,含有11位标识符的帧称之为标准帧,而含有29位标识符的帧称为扩展帧。CANopen使用标准帧格式。
在报文传输时,不同的帧具有不同的传输结构,主要包括数据帧、远程帧、错误帧、过载帧等。

数据帧由七种不同的位域(Bit Field)组成:帧起始(Start of )、仲裁域(Arbitration Field)、控制域(Control Field)、数据域(DataField)、CRC域(CRC Field)、应答域(ACK Field)和帧结尾(End of )。数据域的长度可以为0~8个字节。在实际应用时,用户关注的是标识符和数据域。其他可参考相关文档介绍。
从OSI的7层网络模型的角度来看,CAN现场总线紧紧定义了第1层(物理层)、第2层(数据链路层)。这些完全由硬件实现,设计人员无需开发相关软件或固件,即可完成对CAN的控制。CAN没有规定应用层,但在CAN总线的工业自动化应用中,设备互通互联的需求越来越多,所以需要一个开放的、标准化的高层协议。
CANopen协议是在20世纪90年代末,由总部位于德国纽伦堡的CiA组织(CAN-in-Automation,http://www.can-cia.org )在CAL(CAN Application Layer)的基础上发展而来。
CANopen包含一系列的协议,其中基础协议是CANopen应用层协议(CANopen Application Layer and Communication Profile)(DS 301),规定了CANopen协议层及通信结构描述。在基础协议之上,各个行业具备设备子协议。所谓子协议,就是针对不同行业的应用对象,对CANopen内部的数据含义进行重新定义或添加新的控制逻辑,如运动控制子协议CANopen Profile for Drives and Motion Control (DS 402)。
CANopen协议通常分为用户应用层、对象字典以及通信三个部分。其中最核心的是对象字典,描述了应用对象和CANopen报文之间的关系。CANopen通信定义了协议通信规则以及与CAN控制器驱动之间对应关系。
控制CANopen网络中的设备,是通过对写该设备的参数以及对该设备的状态信息实现的,而CANopen设备的读写通常都基于设备的对象字典。
对象字典是一个有序的对象组,描述了对应设备的所有参数。每个对象都采用一个16位的索引值寻址,这个索引值通常称为索引(index),范围在0x0000~0xFFFF之间。除了索引外,对象还可能包含一个8位的子索引(sub-index),用于描述对象的一组相关参数。

CANopen对象字典(OD: Object Dictionary)是CANopen协议最为核心的概念。所谓的对象字典就是一个有序的对象组,描述了对应CANopen节点的所有参数,包括通讯数据的存放位置也列入其索引,这个表变成可以传递形式就叫做EDS文件(电子数据文档Electronic Data Sheet)。对象字典,就像体检表,具备这个人每个功能的参数,便于用人单位(主站)进行合理分配工作。
每个对象采用一个16位的索引值来寻址,这个索引值通常被称为索引,其范围在0x0000到0xFFFF之间。为了避免数据大量时无索引可分配,所以在某些索引下也定义了一个8 位的索引值,这个索引值通常被称为子索引,其范围是0x00到0xFF之间。
每个索引内具体的参数,最大用32位的变量来表示,即Unsigned32,四个字节。
每个CANopen设备都有一个对象字典,使用电子数据文档(EDS文件)来记录这些参数,而不需要把这些参数记录在纸上。对于CANopen网络中的主节点来说,不需要对CANopen从节点的每个对象字典项都访问。
CANopen对象字典中的项由一系列子协议来描述。子协议为对象字典中的每个对象都描述了它的功能、名字、索引、子索引、数据类型,以及这个对象是否必需、读写属性等等,这样可保证不同厂商的同类型设备兼容。
CANopen协议的核心描述子协议是DS301,其包括了CANopen协议应用层及通信结构描述,其它的协议子协议都是对DS301 协议描述文本的补充与扩展。在不同的应用行业都会起草一份CANopen设备子协议,子协议编号一般是DS4xx 。
下表为对象字典索引区域定义,其中标绿色底纹的通讯对象子协议区和制造商特定子协议区是用户需要关注的区域。

通讯对象子协议区(Communication profile area)定义了所有和通信有关的对象参数,如下表,标绿色底纹的索引范围1000h to 1029h为通用通讯对象,所有CANopen节点都必须具备这些索引,否则将无法加入CANopen网络。其他索引根据实际情况进行分配与定义。

由于 通用讯对象十分重要, 通用讯对象十分重要, NMTNMT 主站( CANopenCANopenCANopenCANopen CANopen 主站) 在启动时, 通常都全部或者部分读取所有从站中通用讯对象中的索引,所以所有的通用讯对象都必须在CANopen从站中实现。
对象字典索引2000h to 5FFFh为制造商特定子协议,通常是存放所应用子协议的应用数据。而上文所描述的通讯对象子协议区(Communication profile area)是存放这些应用数据的通信参数。比如广州致远电子的XGate-COP10从站模块规定了:
为保证网络可靠、可控,CANopen具备NMT服务,通常由主站实施。
CANopen网络中设备的状态可以用一个简单的状态机描述:
预操作状态(Pre-operational):此时节点不能进行PDO通信,可以进行SDO通信和NMT网络管理;
操作状态(operational):可以进行PDO通信,SDO通信,NMT网络管理;
停止状态(Stopped):PDO和SDO通信被停止,但允许NMT网络管理。

NMT报文的一个重要作用是控制网络中设备状态,通常称为NMT节点状态切换命令。NMT节点切换命令具备最高的CAN优先级,CANID均为000h,数据为2个字节:
第一个字节代表命令类型:
01h为启动命令(让节点进入操作状态);
02h为停止命令(让节点进入停止状态);
80h为进入预操作命令(让节点进入预操作状态);
81h为复位节点应用层(让节点的应用恢复初始状态);
82h为复位节点通讯((让节点通讯重新初始化)。
第二个字节代表被控制节点的Node-ID,如果取0,则对整个网络的所有节点同时进行控制。
任何一个CANopen从站上线后,必须发出节点上线报文(boot-up)。节点上线报文的CANID为700h+Node-ID,数据为1个字节0。节点上线报文的生产者是CANopen从站。

CANopen网络对节点监测有两种方式:节点心跳与节点守护。
节点心跳用于表征当前节点在线与操作状态,心跳报文的格式中,CANID与节点上线报文相同为700h+Node-ID,数据为1个字节,代表当前状态,04h为停止状态,05h为操作状态,7Fh为预操作状态。报文生产者为CANopen从站。

在CANopen应用中,还有一种可以通过轮询模式监视从站状态的节点守护模式,与心跳报文模式二者不能并存。首先由NMT-Master节点发送标准远程帧(无数据):CANID为700h+Node-ID,NMT-Slave节点应答发送数据帧,数据为1个字节:包含一个触发位(bit7),触发位必须在每次节点保护应答中交替置“0”或“1”。bits0~6表示节点状态,含义与节点心跳相同。
同步报文实现整个网络的同步传输,具有较高的优先级以及最短的传输时间。通常同步报文的CAN-ID为80h,由一般主站发送,数据长度为0。

同步报文也可以由从站发送。
时间戳报文,由CANopen网络中节点发送,用于整个网络中设备的对时。时间戳报文采用广播的方式,无需节点应答,CAN-ID为100h,数据长度为6,数据为当前时间与1984年1月1日0时的时间差。

当设备发生内部错误时,会触发紧急事件,发送设备内部错误代码,提示NMT主站。紧急报文属于诊断性报文,一般不影响CANopen通讯,其CAN-ID存储在1014h索引中,一般定义为080h+node-ID,数据长度为8,包括EEC:紧急事件错误代码,ER:错误寄存器,MEF:厂商自定义的错误代码。

PDO(Process data object),过程数据对象,用于传输节点的过程数据。PDO单向传输,无需接收节点应答。网络中的任意节点都可以发送PDO,其他一个或多个节点都可以接收该PDO报文。PDO使用“生产消费”或“peer-to-peer”模型。

PDO的数据长度被限制为1~8字节。只要1帧就可以把一条消息或一个变量传递结束。
在PDO预定义中,人为规定了TPDO(发送)和RPDO(接收),通常每个节点设备均包含4个TPDO和4个RPDO。在预定义中,规定了CAN-ID包含了node-ID,方便PDO的解析。

CAN-ID与node-ID没有必然联系,在实际使用中,可以根据需要作修改。RPDO的CAN-ID保存在1400h-15FFh中,TPDO的CAN-ID保存在1800h~19FFh中。
PDO有两种传输类型:同步传输和异步传输。
同步传输基于同步报文,让所有节点能在统一时刻进行上传数据或者下传数据,执行应用命令,可以有效避免异步传输导致的应用逻辑混乱和总线负载不平衡问题。
异步传输通常由设备子协议规定的对象特定事件触发,如定时传输、数据变化传输等。
PDO通信参数,定义了该设备的PDO报文的COB-ID、传输类型等,分别保存在索引1400h ~ 15FFh和1800h ~19FFh中。

同步传输基于同步报文,让所有节点能在统一时刻进行上传数据或者下传数据,执行应用命令,可以有效避免异步传输导致的应用逻辑混乱和总线负载不平衡问题。
异步传输通常由设备子协议规定的对象特定事件触发,如定时传输、数据变化传输等。
PDO 的映射参数保存在通讯参数之后1600h ~ 17FFh (RPDO)和1A00h ~1BFFh (TPDO)中,包含了读写对象的索引和子索引,数据长度(单位,位),以及访问的对象数量。
以下模拟从站02 的TPDO2,将参数、应用数据、CAN 报文数据联合起来展示。

则节点2 在受到内部特定事件触发后发送TPDO2:
CAN-ID:0x182,数据域(3 字节):0x375603
SDO(Service data object),服务数据对象,一般用于主站对从站的参数配置。与PDO 的单向传输不同,SDO 是应答式的通信。SDO 包含指定被接收节点的地址(node-ID),并且需要指定的接收节点回应确认。SDO 使用“服务器客户端”模型。

在CANopen 网络中,通常从站作为SDO 服务器,主站作为唯一的SDO 客户端。SDO客户端通过索引和子索引,能够访问SDO 服务器上的任意对象字典。SDO 可以传输任意长度的数据。
SDO 的通讯原则非常单一,发送方(客户端)发送CAN-ID 为600h+node-ID 的报文,数据长度为8 字节。接收方(服务器)成功接收后,回应CAN-ID 为580h+node-ID 的报文,数据长度为8 字节。这里node-ID 均为从站的地址。

根据需要传送的数据长度,SDO 可分为快速SDO 和普通SDO。
快速SDO 是最常见的一种SDO,所谓快速,就是客户端服务器间1 次问答完成。快速SDO 的前提条件是读取或写入的值不能大于32 位(4 字节)。SDO 报文中包含了访问对象的索引、子索引和数据长度。

通过快速SDO,可以直接对CANopen 节点的对象字典中的值进行读取和修改,所以在做参数配置之外,也经常作为关键性数据传输之用。比如CANopen 控制机器人的电机转动角度时,就使用SDO 来传输,保证可靠到达。
当需要传输的值超过32 位时,就不能使用快速SDO 了,必须使用普通SDO 进行分帧传输。普通SDO 在实际应用中较少使用。
普通 SDO的CAN帧ID与快速SDO相同,发送方(客户 端)发送的报文 CAN-ID 为 600 h +Node -ID,接收方(服务器 )成功接收 后,回应 CAN -ID 为 580h+Node -ID 的报文。普通 SDO协议难点在于分包逻辑与CS命令符的变化。
普通SDO下载协议:

普通SDO上传协议:
针对copley电机驱动器速度环控制的示例
设置驱动器的node ID为1(602中的2代表ID),数据均为16进制。
广州致远电子股份有限公司,CANopen 轻松入门
copley controls,CANopenProgrammersManual
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
是否可以在应用程序中包含的gem代码中知道应用程序的Rails文件系统根目录?这是gem来源的示例:moduleMyGemdefself.included(base)putsRails.root#returnnilendendActionController::Base.send:include,MyGem谢谢,抱歉我的英语不好 最佳答案 我发现解决类似问题的解决方案是使用railtie初始化程序包含我的模块。所以,在你的/lib/mygem/railtie.rbmoduleMyGemclassRailtie使用此代码,您的模块将在
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty