基于野火I.MX6ULL移植canfestival

    • 测试can是否正常运行:

1.1.打开开发板CAN总线

通过野火自带得fire-config工具打开can总线设备(这里要注意,野火得485引脚和can引脚冲突,在打开can设备之前,先关闭485设备)

sudo fire-config

然后重启开发板

sudo reboot  #重启开发板
ifconfig -a #查看can设备是否在线

1.2.下载can调试工具测试

sudo apt-get -y install can-utils  #下载can调试工具

如出现报错 E: Unable to locate package can-utils,更新一下下载源就可以

sudo apt-get update
sudo ip link set can0 type can bitrate 1000000  #设置can0,can0对应得你ifconfig -a的设备名,1000000为波特率
sudo ip link set can0 up #启动can0
sudo ip link set can1 type can bitrate 1000000
sudo ip link set can1 up #同时打开can1
candump can0 #打开一个终端,使用can0接收数据
cansend can1 123#abcdabcd #代开另外一个终端,使用can1发送数据

can0接收如下:

    • 下载并编译canfestival

2.1 源码下载

为了方便开发,下面代码的编译和移植放在ubuntu上进行,最后进行交叉编译即可(ubuntu18.04)

sudo apt install git #先安装git工具
sudo git clone https://github.com/ljessendk/CanFestival.git #下载源码
cd CanFestival  #进入源码目录
./configure --help #先查看一下configure的参数说明

2.2编译源码

sudo ./configure --prefix=$PWD/myinstall --can=socket --debug=WAR,MSG
#这里编译源码 
#--prefix 为动态库的生成位置,后面应用程序运行时,要添加此路径
#--debug 这里我把所有的debug信息都打开了,方便后续调试
sudo make all
sudo make install

我这里有报错信息,暂时不管他,这里进到编译目录下

sudo modprobe vcan #加载虚拟can口模块
sudo ip link add dev vcan0 type vcan #配置虚拟can口
sudo ip link set up vcan0 #打开虚拟can口
ifconfig -a #查看虚拟can口是否运行
cd myintall/bin 
./CANOpenShell load#../lib/libcanfestival_can_socket.so,vcan0,500k,1,1 #启动脚本测试
candump -tz vcan0 #在另外一个终端查看vcan0发送的消息

上图所示vcan0发送了节点启动的报文,则证明canfestival编译成功

    • canfestival使用之SDO

3.1 例程解析

我使用的例程是CANFESTIVAL/example/TestMasterSlave,该例程已经帮你配置了主站和从站

上图是该例程的使用教程,-l为动态库的目录(在之前configure指定的目录下面的lib目录里面)

再配置主从的can口和波特率即可实现主从之间的通信。

    if(strcmp(SlaveBoard.baudrate, "none")){
        
        TestSlave_Data.heartbeatError = TestSlave_heartbeatError;
        TestSlave_Data.initialisation = TestSlave_initialisation;
        TestSlave_Data.preOperational = TestSlave_preOperational;
        TestSlave_Data.operational = TestSlave_operational;
        TestSlave_Data.stopped = TestSlave_stopped;
        TestSlave_Data.post_sync = TestSlave_post_sync;
        TestSlave_Data.post_TPDO = TestSlave_post_TPDO;
        TestSlave_Data.storeODSubIndex = TestSlave_storeODSubIndex;
        TestSlave_Data.post_emcy = TestSlave_post_emcy;

        if(!canOpen(&SlaveBoard,&TestSlave_Data)){
            eprintf("Cannot open Slave Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate);
            goto fail_slave;
        }
    }

上面是main函数里面的一段代码,主要是将回调函数注册到TestSlave_Data结构体中,然后使用canOpen函数进行对从站的初始化。

StartTimerLoop(&InitNodes);这个函数是对节点的初始化配置,设置nodeid,并启动定时器。

3.2 读写SDO

3.2.1 写SDO

可以参考源码Master.c里面主站对从站的写SDO,这两个地址就是对从站的TPDO进行参数配置的,

也就是对索引0x1800,子索引的0x02写入Transmission_Type这个值,然后注册了一个回调函数CheckSDOAndContinue:

static void CheckSDOAndContinue(CO_Data* d, UNS8 nodeId)
{
    UNS32 abortCode;
    /*这里是判断sdo写完成没有,主站对从站写sdo之后,从站回返回一个写成功命令,这里建议用一个while循环去get返回结果,不然的话返回的稍微慢一点就会报错*/    
    if(getWriteResultNetworkDict (d, nodeId, &abortCode) != SDO_FINISHED)
        eprintf("Master : Failed in initializing slave %2.2x, step %d, AbortCode :%4.4x \n", nodeId, init_step, abortCode);

    /* Finalise last SDO transfer with this node */
    closeSDOtransfer(&TestMaster_Data, nodeId, SDO_CLIENT);

    ConfigureSlaveNode(d, nodeId);
}
3.2.2读SDO

根据读sdo可以看到最终调用sdo.h下面_writeNetworkDict,那么写sdo就是下面这个函数:

u8 ReadDict(u8 nodeId, u16 index, u8 subindex)
{

  UNS32 abortCode = 0;
  UNS8 buf[4];
  UNS32 size=4;
    readNetworkDict(&masterObjdict_Data,nodeId,index,subindex,0,0);//读SDO
    //while(readNetworkDict(&masterObjdict_Data,nodeId,index,subindex,0,0)==0xff);
    if(getReadResultNetworkDict(&masterObjdict_Data,nodeId,buf,&size, &abortCode)!=SDO_FINISHED){//获取读到结果,读到的数据会传到参数“buf”里面,这里也一样,建议用while循环去获取结果,不然第一次获取不到就跳出了
    
        closeSDOtransfer(&masterObjdict_Data,nodeId,SDO_CLIENT);
    }
    delay_ms(25);
    closeSDOtransfer(&masterObjdict_Data,nodeId,SDO_CLIENT);
    return 0;
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值