在网上下载CanFestival源码最新版本CanFestival-3-884a60cbb83e
建立以下文件夹:
inc文件夹:放LM3S8962硬件相关以及驱动部分的头文件,adc.h、hw_adc.h等等;
Lib文件夹:放集成库文件driverlib.lib,这个需要比较新的,因为遇到老的库文件缺少CANbitset()函数;
Startup文件夹:放启动代码,Keil软件自身提供的,只需要加入定时器中断(CANopen需要一个16位定时器)和CAN接收中断处理函数;
Target文件夹:目标板初始化代码,其实就是设置系统时钟吧!其实设置的50M;
CANopen_source文件夹:包括CANopen源文件,下载的源码中有13个,不过本次移植dcf.c、lss.c、symbols.c文件没有用到,其中不包含对象字典文件ObjDict.c,该文件我们选取的是examples\AVR\Slave中的ObjDict.c,是从节点的对象字典;
CANopen_include文件夹:包括CANopen头文件,即下载的文件夹的\include目录下的公共文件19个,然后我们把ObjDict.h加进来了,那一共20个,但是有2个应该不会用到(lss.h、dcf.h),因为未用对应的C文件;
user文件夹:存放main.c、includes.h(包括inc中的头文件以及其他文件如CANopen相关的)、以及\include\AT91目录下的4个头文件,分别为applicfg.h、canfestival、config.h、timerscfg.h

需要注意的地方:
CANopen中的timer.h和can.h与库头文件中的文件重名了,需要修改CANopen中的文件名,而且CANopen源文件中引用该头文件的地方也需要修改过来,我们将其改名为CANopen_timer.h、CANopen_can.h。Keil软件提供了全局查找的功能,可以方便查找。

Keil里全局查找Message时,在.h文件中没有找到,其实在CANopen_can.h中有Message的定义,估计是h文件没有包含进入工程吧!我们只是option for target中的C/C++的包含目录中添加了头文件所在的路径,以后可以将h文件加入工程!!!

建立新的工程,将上述文件加入工程,然后编写简单的main.c函数,开始编译改错

编译错误:
1)SDO中发现SDO_BLOCK_SIZE常量未定义,在SDO.c中增加定义#defineSDO_BLOCK_SIZE 10
2)CO_Data结构体中用到了未定义的ObjDict_obj100C,故在对象字典中增加定义
3)Link错误:比如未实现voidsetTimer(TIMEVALvalue)、TIMEVALgetElapsedTime(void)等等。实现上述函数是移植的关键
......

修改直至编译通过,然后写简单的测试代码,测试心跳报文、TPDO、RPDO、SDO功能,当然是从最简单的心跳报文开始,测试时发现了犯了一个错误,搞错UNS8canSend(CAN_PORT notused, Message *m)函数类型,之前采用的UNS8canSend(Message *m) ,解决这个问题后所有的功能就正常了。这个是通过跟踪调试发现的,具体跟踪如下:
setState(&ObjDict_Data, Initialisation); 之后会自动跳到Pre_operational状态,该状态支持{0, 1, 1, 1, 1, 0, 1};分别对应csLSS、csSDO、csSYNC、csLifeGuard、csEmergency、csPDO、csBoot_Up,由此可知仅不支持csLSS和csPDO功能。
switchCommunicationState()中会执行StartOrStop(csLifeGuard,lifeGuardInit(d),lifeGuardStop(d))
这就会执行lifeGuardInit(d), 就会执行heartbeatInit(d);定时时间到就会执行ProducerHeartbeatAlarm(),该函数就会调用底层CAN发送函数canSend(d->canHandle,&msg );发送心跳报文,帧ID为0x701

SDO测试结果截图,读取对象字典对象索引0x1017的第0个数据(标号是从0开始的)
USB-CAN卡发送帧ID 0x601  数据40 17 10 00 00 00 00 00//
从节点返回:  帧ID 0x581  数据4b 17 10 00 10 27 00 00

USB-CAN卡发送帧ID 0x601  数据23 00 18 01 01 02 00 00//改写索引0x1800子索引0x01即TPDO1对应的帧ID为0x00000201从节点返回:  帧ID 0x581  数据40 00 18 01 00 00 00 00//读取索引0x1800子索引0x01即TPDO1对应的帧ID
USB-CAN卡发送SYNC,从节点收到之后C触发发送TPDO,我们设置的TPDO是同步方式,而且受到一个SYNC就发送TPDO

从以上结果可以知道移植的CANopen从节点功能正常。

调试时还发现一个问题:
TIMER_HANDLE SetAlarm()函数中有一条语句有问题,需要加上强制类型转换:
if (row_number == (TIMER_HANDLE)last_timer_raw + 1) last_timer_raw++;
也即下面的问题:
U16 i = 0;
U16 j = -1;
i != (j + 1),其实j + 1为65536 
故需要加强制类型转换
i == (U16)(j + 1) 成立

(笔记)CANOpen移植(CanFestival移植)的更多相关文章

  1. 郑重推荐开源CANopen协议栈CANFestival(LGPL许可)!!!!!!!!

    郑重推荐开源CANopen协议栈CANFestival(LGPL许可)!!!!!!!!(这条文章已经被阅读了 次) 时间:2010/03/04 06:47am 来源:winshton [这个贴子最后由 ...

  2. LINUX为什么要进行内核移植 内核移植的作用

    LINUX为什么要进行内核移植 内核移植的作用,不移植能用么?   LZ的问题应该是为什么要重新编译内核吧.既然你已经可以跑了,证明你现在用的内核已经移植到你用的硬件上,自然你也不需要做什么移植.通常 ...

  3. 【转】(笔记)CANopen协议【CANFestival】移植方法

    一.背景 CAN组网就必须得要应用层协议,原因就在于 * 便于网络管理与控制 * 确认数据的收发 * 发送大于8个字节的数据块(CAN每帧数据传输大小为8字节) * 为不同节点分配不同的报文标识符 * ...

  4. (笔记)CanOpen协议【CanFestival】移植方法 支持VC、QT、STM32

    转自http://bbs.21ic.com/icview-878522-1-1.html   前段时间学习了CanOpen协议,到网上下载的CanFestival3-10源码,移植到VC.QT.STM ...

  5. AM335x(TQ335x)学习笔记——GPIO关键驱动移植

    或按照S5PV210学习秩序.我们首先解决的关键问题.TQ335x有六个用户按钮,每个上.下.剩下.对.Enter和ESC. 我想开始学习S5PV210当同一,写输入子系统驱动器的关键问题要解决,但浏 ...

  6. AM335x(TQ335x)学习笔记——GPIO按键驱动移植

    还是按照S5PV210的学习顺序来,我们首先解决按键问题.TQ335x有六个用户按键,分别是上.下.左.右.Enter和ESC.开始我想到的是跟学习S5PV210时一样,编写输入子系统驱动解决按键问题 ...

  7. cocos2d-x 3.0游戏实例学习笔记 《跑酷》移植到android手机

    说明:这里是借鉴:晓风残月前辈的博客.他是将泰然网的跑酷教程.用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...

  8. AM335x(TQ335x)学习笔记——Nand&&网卡驱动移植

    移植完成声卡驱动之后本想再接再励,移植网卡驱动,但没想到的是TI维护的内核太健壮,移植网卡驱动跟之前移植按键驱动一样简单,Nand驱动也是如此,于是,本人将Nand和网卡放在同一篇文章中介绍.介绍之前 ...

  9. AM335x(TQ335x)学习笔记——WM8960声卡驱动移植

    经过一段时间的调试,终于调好了TQ335x的声卡驱动.TQ335x采用的Codec是WM8960,本文来总结下WM8960驱动在AM335x平台上的移植方法.Linux声卡驱动架构有OSS和ALSA两 ...

随机推荐

  1. 了解HTTP协议栈(实践篇)

    关于http协议的理论知识,我在这里就不详细说明了,具体下面给出的链接有.接下来都是用具体的操作显示的,各位可以结合起来看. 一.使用nc打开端口,并使用浏览器进行访问 (对应文章中的HTTP协议详解 ...

  2. iOS9中怎样注冊远程通知

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 假设认为写的不好请多提意见,假设认为不错请多多支持点赞.谢谢! hopy ;) 在以往的版本号中,我们能够通过: [[UIApplicatio ...

  3. 当update的查询条件是数组的时候,upsert会失效

    不管是findOneAndUpdate还是update方法,只要他们的查询条件是数组,upsert就会失效,比如: //这段代码只会更新已存在的数据,不存在的不会插入 tagModel.update( ...

  4. git rm与git rm --cached

    当我们需要删除暂存区或分支上的文件, 同时工作区也不需要这个文件了, 可以使用 git rm file_path git commit -m 'delete somefile' git push 当我 ...

  5. crontab入门

    参数 crontab是一个处理定时任务的命令,在终端输入man crontab可以得到使用方法提示,主要参数如下: crontab -u # 指定运行的账户,默认为当前账户 crontab -l # ...

  6. C#对DataTable里数据筛选排序的方法

    在日常开发过程中,有一个DataTable集合,里面有很多字段,现在要求针对某一列进行排序,如果该列为数字的话,进行ASC即可实现,但是该字段类型为string,此时排序就有点不正确了 protect ...

  7. Nvidia显卡安装驱动

    首先要知道需要安装哪个类型的显卡驱动,可以使用如下指令查看 sudo add-apt-repository ppa:graphics-drivers在#current那一栏中找到显卡驱动型号,使用的是 ...

  8. scala工程导入报错:scalatest_2.10-1.9.1.jar is cross-compiled with an incompatible version of Scala (2.10).

    错误原因: The Scala IDE tries to check if binary incompatible Scala libraries have been inadvertently mi ...

  9. 纯css3开发的响应式设计动画菜单(支持ie8)

    这是一个响应式设计的菜单.单击列表图标,当你显示屏大小可以完全水平放下所有菜单项时,菜单水平显示(如图1).当你的显示屏不能水平放置所有菜单项时,菜单垂直显示(如图2). 而且显示的时候是以动画的型式 ...

  10. 调整Intellij IDEA内存

    最近IDEA真是卡的要死,下面