[Linux 驱动] CAN测试程序编写

CAN在通讯中应用比较广泛,尤其是汽车领域;高端MCU跑Linux系统后,会把CAN归为网络设备,像操作网卡芯片一样去配置和激活,在操作上面会稍微复杂一些。

一、CAN测试
1、查看设备 ifconfig -a

[root@Jack Jack]$ifconfig -a
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:19

can1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:28

eth0 Link encap:Ethernet HWaddr e0:13:12:16:ba:01
inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::e213:12ff:fe16:ba01/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:968 errors:0 dropped:0 overruns:0 frame:0
TX packets:910 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:150759 (147.2 KiB) TX bytes:65359 (63.8 KiB)
Interrupt:25 Base address:0x8000

eth1 Link encap:Ethernet HWaddr e0:13:12:16:ba:02
inet addr:192.168.2.100 Bcast:192.168.2.255 Mask:255.255.255.0
inet6 addr: fe80::e213:12ff:fe16:ba02/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:401 errors:0 dropped:0 overruns:0 frame:0
TX packets:154 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:29424 (28.7 KiB) TX bytes:11100 (10.8 KiB)
Interrupt:33 Base address:0xc000

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:461 errors:0 dropped:0 overruns:0 frame:0
TX packets:461 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:41988 (41.0 KiB) TX bytes:41988 (41.0 KiB)

sit0 Link encap:UNSPEC HWaddr 00-00-00-00-66-65-31-36-00-00-00-00-00-00-00-00
NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

2、设置波特率 250K
ip link set can0 type can bitrate 250000

[root@Jack Jack] i p l i n k s e t c a n 0 t y p e c a n b i t r a t e 250000 [ r o o t @ J a c k J a c k ] ip link set can0 type can bitrate 250000 [root@Jack Jack] iplinksetcan0typecanbitrate250000[root@JackJack]

3、查询can设备参数
ip -details link show can0

[root@Jack Jack]$ip -details link show can0
2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
bitrate 250000 sample-point 0.833
tq 333 prop-seg 4 phase-seg1 5 phase-seg2 2 sjw 1
at91_can: tseg1 4…16 tseg2 2…8 sjw 1…4 brp 2…128 brp-inc 1
clock 66000000

4、使能CAN0设备
ifconfig can0 up

5、查询工作状态
[root@Jack Jack] i p − d e t a i l s − s t a t i s t i c s l i n k s h o w c a n 02 : c a n 0 : < N O A R P , U P , L O W E R U P , E C H O > m t u 16 q d i s c p f i f o f a s t s t a t e U N K N O W N m o d e D E F A U L T g r o u p d e f a u l t q l e n 10 l i n k / c a n p r o m i s c u i t y 0 c a n s t a t e E R R O R − A C T I V E ( b e r r − c o u n t e r t x 0 r x 0 ) r e s t a r t − m s 0 b i t r a t e 250000 s a m p l e − p o i n t 0.833 t q 333 p r o p − s e g 4 p h a s e − s e g 15 p h a s e − s e g 22 s j w 1 a t 9 1 c a n : t s e g 14..16 t s e g 22..8 s j w 1..4 b r p 2..128 b r p − i n c 1 c l o c k 66000000 r e − s t a r t e d b u s − e r r o r s a r b i t − l o s t e r r o r − w a r n e r r o r − p a s s b u s − o f f 000000 R X : b y t e s p a c k e t s e r r o r s d r o p p e d o v e r r u n m c a s t 000000 T X : b y t e s p a c k e t s e r r o r s d r o p p e d c a r r i e r c o l l s n s 000000 [ r o o t @ J a c k J a c k ] ip -details -statistics link show can0 2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10 link/can promiscuity 0 can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0 bitrate 250000 sample-point 0.833 tq 333 prop-seg 4 phase-seg1 5 phase-seg2 2 sjw 1 at91_can: tseg1 4..16 tseg2 2..8 sjw 1..4 brp 2..128 brp-inc 1 clock 66000000 re-started bus-errors arbit-lost error-warn error-pass bus-off 0 0 0 0 0 0 RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0 [root@Jack Jack] ipdetailsstatisticslinkshowcan02:can0:<NOARP,UP,LOWERUP,ECHO>mtu16qdiscpfifofaststateUNKNOWNmodeDEFAULTgroupdefaultqlen10link/canpromiscuity0canstateERRORACTIVE(berrcountertx0rx0)restartms0bitrate250000samplepoint0.833tq333propseg4phaseseg15phaseseg22sjw1at91can:tseg14..16tseg22..8sjw1..4brp2..128brpinc1clock66000000restartedbuserrorsarbitlosterrorwarnerrorpassbusoff000000RX:bytespacketserrorsdroppedoverrunmcast000000TX:bytespacketserrorsdroppedcarriercollsns000000[root@JackJack]

二、驱动验证OK后,编写应用程序代码;

1、初始化函数,可设置ID滤波等参数;

int init_can(char* can) {
int sock;
struct sockaddr_can addr;
//struct ifreq ifr;

sock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if(sock < 0) {
    printf("error\n");
    return -1;
}

addr.can_family = AF_CAN;
strcpy(ifr.ifr_name, can );

int ret;

ret = ioctl(sock, SIOCGIFINDEX, &ifr);  //get index
if(ret && ifr.ifr_ifindex == 0) {
    printf("Can't get interface index for can0, code= %d, can0 ifr_ifindex value: %d, name: %s\n", ret, ifr.ifr_ifindex, ifr.ifr_name);
    close(sock);
    return -1;
}

printf("%s can_ifindex = %x\n",ifr.ifr_name,ifr.ifr_ifindex);
addr.can_ifindex = ifr.ifr_ifindex;
//ioctl(sock,SIOCGIFNAME,&ifr);
//printf("ret = %d can0 can_ifname = %s\n",ret,ifr.ifr_name);   

int recv_own_msgs = 0;//set loop back:  1 enable 0 disable

setsockopt(sock, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,&recv_own_msgs, sizeof(recv_own_msgs));
if (bind(sock,(struct sockaddr*)&addr,sizeof(addr))<0) {
    printf("bind error\n");
    close(sock);
    return -1;
}

return sock;

}
2、CAN接收函数

void Can_Read_thread(void psock)
{
int sock = *(int *)psock;
struct can_frame frame;

while(1) {
    memset(&frame,0,sizeof(struct can_frame));
    read(sock,&frame,sizeof(struct can_frame));

    if(frame.can_dlc > 0) {
        printf("%s recv: ID=0x%X DLC=%d data[0]=0x%X\n",ifr.ifr_name,frame.can_id,frame.can_dlc, frame.data[0]);

    }
}   

}

3、CAN发送函数

int Write_Can_Data(int sock,char* str,int len)
{
struct can_frame frame;
int i;
int nbytes = 0;

frame.can_id = 0x0; //can device id

while(len) {
    //nbytes = sendto(sock,&frame,sizeof(struct can_frame),0,(struct sockaddr*)&addr,sizeof(addr));
    //memset(&buf,0,sizeof(buf));
    //sprintf(buf,"%s%d","hello",i);
    //strcpy((char *)frame.data,buf);
    if(len > sizeof(frame.data)) {
        memset(&frame.data,0,sizeof(frame.data));
        memcpy(&frame.data,str,sizeof(frame.data));
        //printf("%d,(%s)\r\n",sizeof(frame.data),frame.data);
        frame.can_dlc = sizeof(frame.data);
        str += sizeof(frame.data);
        len -= sizeof(frame.data);
    }
    else {
        memset(&frame.data,0,sizeof(frame.data));
        memcpy(&frame.data,str,len);
        //printf("%d,(%s)\r\n",len,frame.data);
        frame.can_dlc = len;
        str = NULL;
        len = 0;
    }
    write(sock, &frame, sizeof(struct can_frame));
    usleep(100);
}

}
4、主函数编写

int main(int argc ,char** argv)
{
int sock;
int nbytes;
pthread_t canthreadid;
int ret;
char str[4096];
//addr.can_family = AF_CAN;
//addr.can_ifindex = ifr.ifr_ifindex;
//setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
setsockopt(sock,);
//printf(“ifr.ifr_ifindex = %d \r\n”,ifr.ifr_ifindex);
if(argc < 2) {
printf(“Usage: %s (can0/can1)\n”, argv[0]);
return 0;
}

sock = init_can(argv[1]);
if(sock < 0)
{
    return 0;
}

ret=pthread_create(&canthreadid,NULL,Can_Read_thread,&sock);

while(1) {
    printf("Please Input string to send to %s\n:",argv[1]);
    scanf("%s", str);
    if(strlen(str)>0)
        Write_Can_Data(sock,str,strlen(str));
}

// struct can_frame frame;
// char buf[20];
// frame.can_id = 0x0; //can device id
// int i;
// for(i=0;i<20;i++)
// {
//nbytes = sendto(sock,&frame,sizeof(struct can_frame),0,(struct sockaddr*)&addr,sizeof(addr));
// memset(&buf,0,sizeof(buf));
// sprintf(buf,"%s%d",“hello”,i);
// strcpy((char *)frame.data,buf);
// frame.can_dlc = strlen(frame.data);
// nbytes = write(sock, &frame, sizeof(struct can_frame));
// printf("%d. %ld bytes has been sent\n", i, nbytes);
// sleep(1);
// }
close(sock);
printf(“ok\n”);

return 0;

}

6、外部接上CAN盒调用驱动

./canTest can0

关注微信公众号,回复“ Linux CAN测试”,免费获取源代码;
在这里插入图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值