编译canutils\iproute\libsocketcan应用程序测试can

1. 
执行 ip link set can0 up type can bitrate 125000 等命令时,提示: 
ip: either “dev” is duplicate, or “type” is garbage 
Try1: 
配置内核:(下面的选项应该选上) 
Networking support —> 
CAN bus subsystem support —> 
— CAN bus subsystem support 
Raw CAN Protocol (raw access with CAN-ID filtering) 
Broadcast Manager CAN Protocol (with content filtering) 
CAN Device Drivers —> 
Virtual Local CAN Interface (vcan) //原来没有选 
Platform CAN drivers with Netlink support 
[Y] CAN bit-timing calculation 
再次运行 ip link set can0 up type can bitrate 125000,依旧提示ip: either “dev” is duplicate, or “type” is garbage 
(BUSYBOX制作的IP命令工具不支持对socketcan的设置,必须要自己去下载iproute2的源代码自己编译)

移植Iproute 
(http://www.linuxgrill.com/anonymous/iproute2/NEW-OSDL/ 下载地址) 
./configure 错误,出现如下提示: 
TC schedulers 
ATM no 
IPT Package xtables was not found in the pkg-config search path. 
Perhaps you should add the directory containing `xtables.pc’ 
to the PKG_CONFIG_PATH environment variable 
No package ‘xtables’ found 
using iptables 
IPSET no
iptables modules directory: /lib/xtables 
libc has setns: yes 
SELinux support: no

Sudo apt-get install xtables-addons-common 
Sudo apt-get install xtables-addons-source 无效

https://www.kernel.org/pub/linux/utils/net/iproute2/ 下载iproute2 4.2.0 4.6.0 4.4.0的版本. 编译失败 
发现有configure 还有Makefile ,.configure 不起作用, 修改Makefile 后直接编译 
Make 失败,阅读makefile文档,安装如下库 
sudo apt-get install libdb4.8-dev

出现如下错误: 
../lib/libnetlink.a: could not read symbols: Archive has no index; run ranlib to add one 
collect2: ld returned 1 exit status 
make[1]: * [ip] Error 1

用厂家提供的内核和文件系统,实验Can的ip 命令和功能都好用 
root@ok335x:/bin# which ip 
/bin/ip 
root@ok335x:/bin# ls -l ip 
lrwxrwxrwx 1 root root 19 Jun 17 2014 ip -> ../sbin/ip.iproute2

解决办法: 借用Ti厂家提供的文件系统,移植ip 和 iprotue2 到 开发板的文件系统中 
book@ubuntu:~/work/software$ ls 
bin Code Composer Studio 6.1.3.desktop libsocketcan-0.0.8 setup.sh 
board-support docs linux-devkit targetNFS 
busybox-1.7.0 example-applications Makefile xdctools_3_31_03_43_core 
busybox-1.7.0.tar.bz2 filesystem mtd-utils-05.07.23 
canutils-4.0.6 iproute2 mtd-utils-05.07.23.tar.bz2 
ccsv6 iproute2-2.4.7-now-ss010824.tar.gz Rules.make

其中 绿色标记的字体为安装 ti linux sdk 包生成的文件. 
Cd filesystem

book@ubuntu:~/work/software/filesystem/sbin$ ls ip -l 
lrwxrwxrwx 1 book book 17 Apr 5 16:56 ip -> /sbin/ip.iproute2

将命令cp 到开发板 
Cp ip ip.iproute2 /sbin -R

Libsockecan 
./configure –host=arm-linux-gnueabihf prefix=$PWD/temp_install 
Make 
Make install
常用命令: 
ip link set can0 type can bitrate 125000 
ip link set can0 down 
ip link set can0 up 
ifconfig can0 up ifconfig can0 down cat /proc/net/can/version cat /proc/net/can/stats 
Candump 
candump can0 
cansend 
cansend can0 500#1E.10.10 向地址0x1E, 0x10, 0x10的can设备发送数据 500 
cansend can0 500#R 发送远程请求帧,数据为500 
3.EmbededConfig、EmbededDebug 工具的使用 
Arm板,设定can bitrate: 
ip link set can0 type can bitrate 10000 
Ip link set can0 up

3.1使用EmbededConfig设置虚拟串口的波特率、设置can的波特率(注意EmbededConfig与Embededdebug的串口波特率要设为一致) 
Embededdebug 软件设置:(注意串口的波特率一定要与EmbededConfig号一直) 
Can 程序调试: 
调试过程: 将usb-can 与Am3354的can 连接后,Am3354运行2个进程,一个进程只发送数据(发送的Id 为0x11,0x22),另一个进程发送完数据后收数据(过滤设置为0x11)。 
结果: 收发进程能收到另一进程的发送数据(Id 为0x11),但用Usb-can 发送数据,却无法接收数据(原因是usb-can 设备坏了,不能发送数据)。 
CAN 发送:源码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>

int main()
{
int can_fd, nbytes;
int ret=0;
struct sockaddr_can can_addr_sendtask;
struct ifreq can_devices_sendtask;
struct can_frame frame[2] = {{0}};

can_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);//创建can套接字
if(can_fd==-1)
{
  printf("socket can is fail \n");
  exit(0);
}

strcpy(can_devices_sendtask.ifr_name, "can0" );

ioctl(can_fd, SIOCGIFINDEX, &can_devices_sendtask); //指定 can0 设备

can_addr_sendtask.can_family = AF_CAN;  // 设置can
can_addr_sendtask.can_ifindex = can_devices_sendtask.ifr_ifindex;

ret=bind(can_fd, (struct sockaddr *)&can_addr_sendtask, sizeof(can_addr_sendtask));//将套接字与 can0 绑定
if(ret==-1)
{
  printf("bind fail \n");
  exit(0);
}

//禁用过滤规则,本进程不接收报文,只负责发送

// 因为这个任务只发送,禁用can接收报文
ret=setsockopt(can_fd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL,0);// 禁用过滤规则
if(ret==-1)
{
    printf("setsockopt fail \n");
    exit(0);

}
int loopback =1 ;// 关闭回环模式
//发送的两个报文设置
frame[0].can_id = 0x11;// can 标示为0x11 的设备
frame[0].can_dlc = 1;   // 发送数据长度
frame[0].data[0] = 11;


frame[1].can_id = 0x22;
frame[1].can_dlc = 1;// 发送数据长度
frame[1].data[0] = 22;
//循环发送两个报文
while(1)
{
nbytes = write(can_fd, &frame[0], sizeof(frame[0])); //发送 frame[0]

if(nbytes != sizeof(frame[0]))
{
printf("Send Error frame[0]\n!");
}

sleep(1);

nbytes = write(can_fd, &frame[1], sizeof(frame[1])); //发送 frame[1]
if(nbytes != sizeof(frame[0]))
{
printf("Send Error frame[1],write count is %d\n!",nbytes);
}

sleep(1);
}
close(can_fd);
return 0;
}
Can 收发进程源码:
/*
//禁用过滤规则

setsockopt(can_fd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); //禁用过滤规则

//通过错误掩码可以实现对错误帧的过滤
can_err_mask_t err_mask = ( CAN_ERR_TX_TIMEOUT | CAN_ERR_BUSOFF );
setsockopt(can_fd, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, err_mask, sizeof(err_mask));

在默认情况下,本地回环功能是开启的,可以使用下面的方法关闭回环/开启功能:
int loopback = 0; // 0 表示关闭, 1 表示开启(默认)
setsockopt(can_fd, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));

*/

int main()
{
int can_fd, nbytes;
int ret=0;
struct sockaddr_can can_addr_sendtask;
struct ifreq can_devices_sendtask;


can_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);//创建套接字
if(can_fd==-1)
{
  printf("socket can is fail \n");
  exit(0);
}


strcpy(can_devices_sendtask.ifr_name, "can0" );

ioctl(can_fd, SIOCGIFINDEX, &can_devices_sendtask); //指定 can0 设备

can_addr_sendtask.can_family = AF_CAN;
can_addr_sendtask.can_ifindex = can_devices_sendtask.ifr_ifindex;

ret=bind(can_fd, (struct sockaddr *)&can_addr_sendtask, sizeof(can_addr_sendtask));//将套接字与 can0 绑定
if(ret==-1)
{
  printf("bind fail \n");
  exit(0);
}


int loopback =1 ;  
ret=setsockopt(can_fd, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));
if(ret==-1)
{
    printf("loopback fail \n");
    exit(0);

}
//  设定过滤规则
struct can_frame rec_frame[1];
struct can_filter rfilter[1];

rfilter[0].can_id   = 0x11; // 接收id为0x11的帧
rfilter[0].can_mask = CAN_SFF_MASK;

ret=setsockopt(can_fd, SOL_CAN_RAW,CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

if(ret==-1)
{
    printf("setsockopt fail \n");
    exit(0);

}

struct can_frame frame[2] = {{0}};

//发送两个报文
frame[0].can_id = 0x11;// can 标示为0x11 的设备
frame[0].can_dlc = 1;   // 发送数据长度
frame[0].data[0] = 0x11;
frame[1].can_id = 0x22;
frame[1].can_dlc = 1;// 发送数据长度
frame[1].data[0] = 0x22;

while(1)
{
nbytes = write(can_fd, &frame[0], sizeof(frame[0])); //发送 frame[0]

if(nbytes != sizeof(frame[0]))
{
printf("Send Error frame[0]\n!");
}

nbytes = write(can_fd, &frame[1], sizeof(frame[1])); //发送 frame[1]
if(nbytes != sizeof(frame[0]))
{
printf("Send Error frame[1],write count is %d\n!",nbytes);
}
printf("send 2 frame \n");
sleep(1);

nbytes=read(can_fd,&rec_frame, sizeof(rec_frame[0]));
if(nbytes != sizeof(rec_frame[0]))
{
printf("rece Error frame,rece count is %d\n!",nbytes);
}

printf("rec %d bytes,id is %d \n",rec_frame[0].can_dlc,rec_frame[0].can_id);

}
close(can_fd);
return 0;
}
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值