文档章节

CanOpen学习笔记4-- 建立SDO通信

b
 bo_zhang
发布于 2017/07/25 21:12
字数 1945
阅读 118
收藏 0
点赞 0
评论 0

作为DSO Client想要对SDO Server进行写操作(调用_writeNetworkDict):

1、根据nodeID找出OD中对应的SDO Client Parameter的序号CliNbr(即index-0x1280)。

2、再在SDO transfers[]中判断作为SDO_CLIENT的CliNbr是否已经存在(GetSDOClientFromNodeId),即是否存在对同一个Server的通信,没有则继续。

3、在SDO transfers[]中选择一个没有被使用的传输线(getSDOfreeLine得到line序号)并保存whoami(SDO_CLIENT or SDO_SERVER),再初始化此传输线(initSDOline),将状态(SDO_DOWNLOAD_IN_PROGRESS或SDO_BLOCK_DOWNLOAD_IN_PROGRESS)和CliNbr以及索引等保存其中。传输量较大的分配内存到传输线(dynamicData)中,再复制全部数据到此传输线中。

4、构建SDO帧信息(8字节部分),并将Callback函数指针赋值给此传输线的回调函数指针,用于传输结束时调用。

5、发送SDO帧(根据SDO_CLIENT和CliNbr确定COB_ID部分),启动SDO传输。

 

注:函数writeNetworkDictCallBackAI是用于没有找到对应nodeID的SDO Client Parameter的传输,利用SDO_CLIENT中ServerID为0的SDO Client Parameter来赋值替代。

 

对于SDO写操作的结果可以通过getWriteResultNetworkDict来查看,在执行时先判断是否存在对应的Client以及其SDOline是否在使用,若是直接判断传输线的状态(transfers[line].state)是否为SDO_FINISHED,若不是,返回当前的状态;若是,复位传输线(resetSDOline)并返回SDO_FINISHED。

当需要结束SDO传输时(SDO传输完成或者超时),调用closeSDOtransfer,根据nodeID找到对应的在使用的传输线,并复位传输线。

 

利用SDO传输文件

Server端准备工作:传输一个文件至少需要传输三个部分,即文件名、文件大小以及文件内容,由于CanOpen协议本身是没有传输文件的规定的,所以需要在CanOpen协议基础上实现文件的传输。

这里在OD对象字典上定义三个变量,分别保存传输文件的三个部分(如上所述)。文件名利用visible_string类型存储,为避免动态分配内存,这里定义32字节的数组,也就是说文件名的最大长度为31字节(最后一个为结束符),所以文件名固定传输32个字节。文件大小用uint32类型存储。文件内容用domain类型存储,其大小和存储区域在传输完文件大小后动态分配。

这里至少FileSize和FileBuffer需要回调函数,在其值发生改变时调用。远程Client传输文件前需要先传输文件的大小,在FileSize的回调函数中,分配需要尺寸的内存,并初始化FileBuffer变量的相关参数(如类型、大小、指针)。注:其实FileBuffer定义的数组并没有利用,使用动态分配的存储空间。

这里FileName的回调函数并没有利用。

当FileBuffer 的回调函数调用时说明文件传输已经完成,可以对文件进行存储。注意由于这个函数是在_setODentry中调用的,也就是在canDispatch()中调用,而canDispatch()调用时已经关中断(定时器中断)了,同时在这个回调函数中对文件系统经行打开读写操作可能会导致故障(我这里发现写的时候系统自动复位),所以FileBuffer的回调函数应该尽量快速完成,可以设置一个标志位,这里置位,在某个线程(Task)中,轮询此标志并进行处理。处理完成后需要释放(free)分配的内存空间,并初始化FileBuffer索引相关的变量。

Client端准备工作:对于Server端的存储文件的三个变量索引必须知道(最好固定下来),在获得文件大小,文件名,文件内容后,调用WriteSDOFile(自己实现)启动文件发送。

这里首先发送的是文件大小,同时确定文件大小传输完成后的回调函数,在其回调函数启动发送文件名,在发送文件名的回调函数中启动发送文件内容,在发送文件内容的回调函数中释放分配的内存。

这里在开始就已经将文件名和文件大小以及文件内容的指针用全局变量保存下来。

 

发送文件后记:在SDO发送数据时会先将要发送的数据保存在SDO传输线中(小尺寸保存在transfers[line].data中,若尺寸过大则先动态分配内存(transfers[line].dynamicData),将所有要传输的数据复制到其中),原数据的内存可以释放掉。而在接收方,SDO在initiate download阶段只是在传输线中保存以后传送文件的大小,并没有分配内存,在之后接收数据时先保存在transfers[line].data[SDO_MAX_LENGTH_TRANSFER]中,当接收到的数据量大于SDO_MAX_LENGTH_TRANSFER(32)时再一次动态分配SDO_DYNAMIC_BUFFER_ALLOCATION_SIZE(128*1024)量的内存,并将之前收到的数据复制到其中,之后的接收数据直接保存到新分配的内存中。当接收的数据量再次大于SDO_DYNAMIC_BUFFER_ALLOCATION_SIZE时,会重新分配再加SDO_DYNAMIC_BUFFER_ALLOCATION_SIZE的内存量,也就是说每次超过分配的数据量时会再加SDO_DYNAMIC_BUFFER_ALLOCATION_SIZE大小的内存量。当数据接收完成之后,再将数据复制到对象字典中。

 

后记二:当SDO CLIENT发送或者接收超时,会在SDOTimeoutAlarm()中发送SDO ABORT给与该SDO通信的节点。同时置通信状态transfers[line].state为SDO_ABORTED_INTERNAL,并且置transfers[line].abortCode为SDOABT_TIMED_OUT,之后再调用此SDO传输线的CallBack函数transfers[line].Callback(d, nodeId),在这个函数中用户可以进行相应的处理。若传输成功,则置通信状态为transfers[line].state = SDO_FINISHED,并调用CallBack函数。若SDO CLIENT接收到SDO ABORT帧,会置通信状态为transfers[line].state = SDO_ABORTED_RCV,并且transfers[line].abortCode置为接收的错误代码,并调用transfers[line].Callback函数。

注意:在处理SDO帧(proceedSDO)时,由于自身原因导致的错误(如toggle位错误,通信阶段错误,line存取错误等),若自身为SDO_SERVER,则只resetSDOline并发送SDO ABORT帧;若自身为SDO_CLIENT,则先停掉该line的定时器,并置状态和错误代码,再发送SDO ABORT帧。都没有调用CallBack函数。

综上可知,当SDO Client发起读或者写远程OD时,可以初始化传输线(line)时设置CallBack函数,并发起传输;SDO Server接收到此初始SDO传输时选择一个空闲的SDO line并初始化,之后开始传输。传输过程中若SDO Server出现错误,则调用failedSDO复位传输线(line)并发送SDO ABORT帧,Client接收到此帧则停止定时器、置状态和错误代码并调用CallBack函数。若传输过程中SDO Client出现错误,则调用failedSDO停止定时器、置状态并发送SDO ABORT帧,没有复位传输线,也没有调用CallBack函数(需要应用检查传输状态并结束传输线,认为可以加上callback调用),Server接收到此帧则复位传输线。若Client规定时间内没有接收到Server响应,则置状态发送SDO ABORT帧,并调用CallBack函数,若此函数没有复位(或关闭)传输线,则还会复位此传输线。

 

后记三:对于OD对象字典的参数变量的回调函数,在完成处理后要返回OD_SUCCESSFUL,若返回其他非零值,会当做错误代码发送至与其通信的远端节点。注:没有写返回值的,编译器可能会随即返回某个值导致发送错误(Keil出现过)。

© 著作权归作者所有

共有 人打赏支持
b
粉丝 0
博文 7
码字总数 6636
作品 0
苏州
CANopen协议介绍

1.CANopen协议简介 从OSI 网络模型的角度来看,CAN总线只定义了OSI网络模型的第一层(物理层) 和第二层(数据链路层),而在实际设计中,这两层完全由硬件实现,设计人员无需再为此开发相关...

炉yu ⋅ 2017/06/14 ⋅ 0

SPI (Serial Peripheral Interface)串行外设接口 协议详解+实例

SPI (Serial Peripheral Interface)串行外设接口 协议详解+实例 一、协议简介 SPI协议简介(转) (2008-04-26 16:24) 分类:单片机及硬件相关技术 来自:http://blog.chinaunix.net/space...

FreeBlues ⋅ 2012/07/16 ⋅ 1

JDBC中如何获取java.sql.Array的值

因为最近在做GIS项目,中间涉及存取Oracle Spatial的SDOGeometry信息,由于当初的设计原因,现在增加一个功能,要从库中取出地理信息的数据——这个功能可真是折腾人啊。。 我也是刚接触GIS...

tnjin ⋅ 2016/02/28 ⋅ 0

SPI协议概括

一 SPI协议概括 SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟...

曾永刚 ⋅ 2012/08/08 ⋅ 0

SylixOS-IgH系统平台搭建

1.参考手册 下面7个文件存放在本地服务器“\10.9.1.113.研发部9.ExchangeFolder郑磊”路径下 《RealEvo-IDE使用手册》 《SylixOS应用开发手册》 《SylixOSshell用户手册》 《SylixOS-IgH使用...

zhengleich ⋅ 05/15 ⋅ 0

ESP8266笔记汇总

一、前言 2015年开始,随着ESP8266的横空出现,WiFi SoC大幅降价,市场模组价格一下被拉到了10元档。WiFi由于可直接入网的,在智能家居等行业中成为了应用最广泛的物联网技术。本尊贵为物联网...

iotisan ⋅ 2017/02/03 ⋅ 0

个人知识管理软件使用感受

关于个人知识管理 个人知识管理(百度百科):个人知识管理是一种新的知识管理的理念和方法,能将个人拥有的各种资料、随手可得的信息变成更具价值的知识,最终利于自己的工作、生活。通过对...

Lucups ⋅ 2013/03/31 ⋅ 27

Oracle Spatial研究

Oracle Spatial是Oracle公司推出的空间数据库组件,通过Oracle数据库系统存储和管理空间数据。 Oracle从9i开始对空间数据提供了较为完备的支持。 由于Oracle Spatial本身是ORACLE数据库的一个...

长平狐 ⋅ 2013/12/25 ⋅ 0

SPI串行接口优缺点及通信原理

SPI是串行外设接口(Serial Peripheral Interface)的缩写。是一种同步串行接口技术,是高速的,全双工,同步的通信总线。 1、SPI接口的优点 支持全双工操作; 操作简单; 数据传输速率较高。 ...

昇润科技 ⋅ 05/16 ⋅ 0

Nebula3学习笔记(7): 网络系统

Nebula3的网络子系统提供了基于TCP协议的简单C/S通信模式. 它并没有打算做成大厅,会话管理还有玩家数据同步的面向游戏的高级通信. 这些以后会在更高层的Nebula3子系统中出现. 使用IP地址 一个...

长平狐 ⋅ 2012/11/12 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

两道面试题,带你解析Java类加载机制

在许多Java面试中,我们经常会看到关于Java类加载机制的考察,例如下面这道题: class Grandpa{ static { System.out.println("爷爷在静态代码块"); }} cl...

1527 ⋅ 22分钟前 ⋅ 0

SpringCloud(Data Flow)

dataflow-server

赵-猛 ⋅ 33分钟前 ⋅ 0

深入理解Java虚拟机

这本书我读到第8章,之后就是在读不下去了。 读到后面是一种痛苦的体验,太多的东西是不全面的,大量的专有名词是没有解释的,读到最后很多东西仅仅是一个侧面,所以我觉得,这本书不适合初学...

颖伙虫 ⋅ 38分钟前 ⋅ 0

B树和B+树的总结

B树 为什么要B树 磁盘中有两个机械运动的部分,分别是盘片旋转和磁臂移动。盘片旋转就是我们市面上所提到的多少转每分钟,而磁盘移动则是在盘片旋转到指定位置以后,移动磁臂后开始进行数据的...

浮躁的码农 ⋅ 41分钟前 ⋅ 0

NanoPi NEO core/ Ubuntu16.04单网卡配置3个IP地址(2个静态,1个动态)

配置 root@NanoPi-NEO-Core:/etc/network# cat interfacesauto loiface lo inet loopbackallow-hotplug eth0iface eth0 inet static address 172.31.188.249 netmask 255.......

SamXIAO ⋅ 今天 ⋅ 0

三步为你的App集成LivePhoto功能

摘要:LivePhoto是iOS9新推出的一种拍照方式,类似于拍摄Gif图或录制视频片段生成图片。如果没有画面感,可以联想《哈利波特》霍格沃茨城堡的壁画,哈哈,很炫酷有木有,但坑爹的是只有iphone6S以...

壹峰 ⋅ 今天 ⋅ 0

centos7 git安装

由于centos中的源仓库中git不是最新版本,需要进行源码安装。 1、查看yum仓库git信息 [root@iZm5e3d4r5i5ml889vh6esZ zh]# yum info gitLoaded plugins: fastestmirrorLoading mirror s...

xixingzhe ⋅ 今天 ⋅ 0

input file 重复上传同一张图片失效的解决办法

解决办法 方法一:来回切换input[type='file']的type属性值,可以是‘text’,'button','button'....,然后再切换回来‘file’ 方法二:每次取消图片预览后,重置input[type='file']的value的...

时刻在奔跑 ⋅ 今天 ⋅ 0

Mahout推荐算法API详解

前言 用Mahout来构建推荐系统,是一件既简单又困难的事情。简单是因为Mahout完整地封装了“协同过滤”算法,并实现了并行化,提供非常简单的API接口;困难是因为我们不了解算法细节,很难去根...

xiaomin0322 ⋅ 今天 ⋅ 0

WampServer默认web服务器根目录位置

安装WampServer之后的web服务器根目录默认位置在WampServer安装目录下的www:

临江仙卜算子 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部