(笔记)CANOpen移植(CanFestival移植)

在网上下载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) 成立

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于将CANopen协议栈CanFestival移植到GD32微控制器平台,您可以按照以下步骤进行操作: 1. 首先,确保您已经安装了GD32的开发环境,包括编译器和调试器。 2. 在GD32上创建一个新的工程,并将CanFestival的源代码添加到工程中。您可以从CanFestival的官方网站或GitHub仓库获取源代码。 3. 根据GD32的硬件规格和外设配置,修改CanFestival的配置文件。主要需要关注的是CAN总线的参数设置,例如波特率、过滤器配置等。 4. 实现GD32与CanFestival之间的硬件抽象层(HAL)函数。这些函数包括CAN总线的初始化、发送和接收数据等。您需要根据GD32的外设库文档或相应的例程来编写这些函数。 5. 在主函数中初始化CanFestival,并配置CANopen节点的参数,如节点ID、通信参数等。 6. 实现CanFestival的回调函数,用于处理CANopen协议栈的事件和对象字典的读写操作。根据您的应用需求,您可能需要自定义一些回调函数。 7. 在主循环中调用CanFestival的主任务函数,以处理CANopen通信和事件。您可以使用定时器中断或轮询方式来调用该函数。 8. 编译并下载程序到GD32微控制器上,然后通过CAN总线与其他CANopen设备进行通信。 请注意,以上步骤提供了一个基本的框架,您可能需要根据您的具体应用需求做一些定制化的修改和调整。同时,建议参考CanFestival的官方文档和示例代码,以获取更详细的指导和帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值