CAN 接口测试[通俗易懂]

CAN 接口测试[通俗易懂]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…

大家好,又见面了,我是你们的朋友全栈君。

CAN 接口测试

一、命令测试

系统下测试会用到candump与cansend

备注:如果没有can命令可以通过编译can-utils获得,can-utils源码:http://sources.buildroot.net/can-utils/
交叉编译:make ARCH=XXXX CC=XXXX-linux-gcc -j4 CFLAGS=-static

测试脚本cantest.sh如下

#!/bin/sh
ifconfig can0 down
ifconfig can1 down
echo cantest recv can0 id
echo cantest send can0 id times data0 data1
echo id -1 means receive all
set -x
/sbin/ip link set can0 type can bitrate 100000
/sbin/ip link set can1 type can bitrate 100000
ifconfig can0 up
ifconfig can1 up
candump can0  &
cansend  can1 123#11223344556677

1.sudo modprobe vcan
加载虚拟can模块
2.sudo ip link add dev vcan0 type vcan
添加vcan0网卡
3.ifconfig -a
可以查到当前can网络 can0 can1,包括收发包数量、是否有错误等等
4.ip link set can0 up type can bitrate 800000
//ip link set can0 type can –help
设置can0的波特率为800kbps,CAN网络波特率最大值为1Mbps
5.ip link set can0 up type can bitrate 800000 loopback on
设置回环模式,自发自收,用于测试是硬件是否正常,loopback不一定支持
6. ip link set can0 down
关闭can0 网络
7.cansend can0 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88
发送默认ID为0x1的can标准帧,数据为0x11 22 33 44 55 66 77 88 每次最大8个byte
8.cansend can0 -i 0x800 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 -e
-e 表示扩展帧,CAN_ID最大29bit,标准帧CAN_ID最大11bit
-i表示CAN_ID
9. cansend can0 -i 0x02 0x11 0x12 –loop=20
–loop 表示发送20个包
10.candump can0
接收CAN0数据

二、应用程序测试

1、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>

void CANTestMenu(void)
{
    printf("************************************************** \n");
    printf("*  Select CAN bitrate menu \n");
    printf("*  1  5Kbps \n");
    printf("*  2  10Kbps \n");
    printf("*  3  20Kbps \n");
    printf("*  4  50Kbps \n");
    printf("*  5  100Kbps \n");
    printf("*  6  125Kbps \n");
    printf("*  7  250Kbps \n");
    printf("*  8  500Kbps \n");
    printf("*  9  800Kbps \n"); 
    printf("*  10 1000Kbps \n");    
    printf("*  11 exit \n");
    printf("************************************************** \n");

    printf("*  please input CAN bitrate Int Number,press enter end \n");
    printf("************************************************** \n");
}



int CanInit(unsigned int id, unsigned int baud)
{
    int s;
    int ret;
    char dev[8] = {0};
    char cmd[128] = {0};
    struct sockaddr_can addr = {0};
    struct ifreq ifr = {0};

    sprintf(dev, "can%d", id);
    printf("can dev : %s \n", dev);
    
    //关闭can设备
    sprintf(cmd, "ifconfig %s down", dev);
    printf(cmd);printf("\n");
    if(system(cmd) < 0)
    {
        printf("can device shut down failed  \n");
        return -1;
    }

    //设置can设备波特率
    bzero(cmd, sizeof(cmd));
    sprintf(cmd, "/sbin/ip link set %s type can bitrate %d ", dev, baud);
    printf(cmd);printf("\n");
    if(system(cmd) < 0)
    {
        printf("set can device baud rate failed  \n");
        return -1;
    }
    
    //打开can设备
    bzero(cmd, sizeof(cmd));
    sprintf(cmd, "ifconfig %s up", dev);
    printf(cmd);printf("\n");   
    if(system(cmd) < 0)
    {
        printf("can device open failed  \n");
        return -1;
    }

    //创建套接字
    s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if(s < 0){
        perror("can socket");
        return -1;
    }
    
    strcpy(ifr.ifr_name, "can0" );
    //指定can0 设备
    ret = ioctl(s, SIOCGIFINDEX, &ifr);
    if(ret < 0){
        perror("can ioctl");
        return -1;
    }
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    
    //将套接字与can0 绑定
    ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
    if(ret < 0){
        perror("can bind");
        return -1;
    }

    return s;   
}

int main()
{
    int s, nbytes, n;
    long bitrate;
    struct sockaddr_can addr;
    struct ifreq ifr;
    struct can_frame frame;

    //CANTestMenu();

    bitrate=100000;
    s = CanInit(0, bitrate);

    if(s < 0){
        printf("CanInit failed \n");
        sleep(1);
        close(s);
        return -1;
    }
    printf("CanInit success\n");

    frame.can_id = 0x123ab|CAN_EFF_FLAG;
    frame.can_dlc = 8;

    frame.data[0] = 0x11;
    frame.data[1] = 0x22;
    frame.data[2] = 0x33;
    frame.data[3] = 0xaa;
    frame.data[4] = 0xbb;
    frame.data[5] = 0xcc;
    frame.data[6] = 0xdd;
    frame.data[7] = 0xee;
    //禁用过滤规则,本进程不接收报文,只负责发送
    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);    
    
    while(1)
    {
        nbytes = write(s, &frame, sizeof(frame)); //发送frame
        if(nbytes != sizeof(frame))
        {
            printf("Send Error frame\n!");
//            break; //发送错误,退出
        }
        else
        {
            printf("Send msg success!\n");
        }
        usleep(10000);
    }
    close(s);
    return 0;
}

2、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 CanInit(unsigned int id, unsigned int baud)
{
    int s;
    int ret;
    char dev[8] = {0};
    char cmd[128] = {0};
    struct sockaddr_can addr = {0};
    struct ifreq ifr = {0};

    sprintf(dev, "can%d", id);
    printf("can dev : %s \n", dev);
    
    //关闭can设备
    sprintf(cmd, "ifconfig %s down", dev);
    printf(cmd);printf("\n");
    if(system(cmd) < 0)
    {
        printf("can device shut down failed  \n");
        return -1;
    }
    
    //设置can设备波特率
    bzero(cmd, sizeof(cmd));
    sprintf(cmd, "ip link set %s type can bitrate %d ", dev, baud);
    printf(cmd);printf("\n");
    if(system(cmd) < 0)
    {
        printf("set can device baud rate failed  \n");
        return -1;
    }
    
    //打开can设备
    bzero(cmd, sizeof(cmd));
    sprintf(cmd, "ifconfig %s up", dev);
    printf(cmd);printf("\n");   
    if(system(cmd) < 0)
    {
        printf("can device open failed  \n");
        return -1;
    }
    
    //创建套接字
    s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if(s < 0){
        perror("can socket");
        return -1;
    }
    
    strcpy(ifr.ifr_name, "can0" );
    //指定can0 设备
    ret = ioctl(s, SIOCGIFINDEX, &ifr);
    if(ret < 0){
        perror("can ioctl");
        return -1;
    }
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    
    //将套接字与can0 绑定
    ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
    if(ret < 0){
        perror("can bind");
        return -1;
    }

    return s;
}

int main()
{
    int s, nbytes;
    struct can_frame frame;
    struct can_filter rfilter[1];
    
    s = CanInit(0, 100000);
    //定义接收规则,只接收表示符等于0x11 的报文
    rfilter[0].can_id = 0x11;
    rfilter[0].can_mask = CAN_SFF_MASK;
    //设置过滤规则
    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
    
    while(1)
    {
        nbytes = read(s, &frame, sizeof(frame)); //接收报文
        //显示报文
        if(nbytes > 0)
        {
            printf("ID=0x%x, DLC=%d, data[0]=0x%x \n", frame.can_id, frame.can_dlc, frame.data[0]);
        }
    }
    close(s);
    return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/147680.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • filetype all java试卷_java认证考试试题及答案

    filetype all java试卷_java认证考试试题及答案java认证考试试题及答案故答案为C。12.Whatistheresultafterthefollowingcodeexecutes?1shorts=0x00FD;2byteb=(byte)s;3System.out.println(b);Select1correctanswer:A.Compiletimeerrorinline1B.Comp…

    2022年7月8日
  • php三个数从大到小排列_php常用的流程控制语句

    php三个数从大到小排列_php常用的流程控制语句<?php$a = rand(100,999);$b = rand(100,999);$c = rand(100,999);echo “a=”.”$a”.”<br>”;echo “b=”.”$b”.”<br>”;echo “c=”.”$c”.”<br>”;if(($a > $b ) && ($a > …

    2022年8月18日
  • String字符串截取方式

    String字符串截取方式原文连接:https://www.cnblogs.com/alisapan/p/6490590.html1.split()+正则表达式来进行截取。将正则传入split()。返回的是一个字符串数组类型。不过通过这种方式截取会有很大的性能损耗,因为分析正则非常耗时。Stringstr=”abc,12,3yy98,0″;String[]strs=str.split(“,”);for(…

    2022年5月12日
  • sql数据库unique的用法_mysql中的date数据类型

    sql数据库unique的用法_mysql中的date数据类型摘自帮助:uniqueidentifier全局唯一标识符(GUID)。注释uniqueidentifier数据类型的列或局部变量可用两种方法初始化为一个值:使用NEWID函数。将字符串常量转换为如下形式(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,其中每个x是0-9或a-f范围内的一个十六进制的数字)。例如,6F9619FF-8B86-D011-B…

    2022年9月8日
  • iPhone4S iOS6.1.2完美越狱「建议收藏」

    iPhone4S iOS6.1.2完美越狱「建议收藏」iPhone4SiOS6.1.2完美越狱iOS6完美越狱工具Evasi0n继续更新至1.5版本,新版本同样支持iOS6.1.2完美越狱,并提升了设备的开机速度。如果您的设备未越狱,建议使用Evasi0n1.5进行完美越狱。如果您之前越狱后遇到了开机慢的问题,可至cydia下载0.4-1修复补丁。iOS6.x完美越狱工具下载:点击下载>>>evasi0n1.5(wind

    2022年6月1日
  • 是学Java好呢?还是学C++更有前途?

    是学Java好呢?还是学C++更有前途?最近有不少初学编程的朋友问:他们比较倾向于Java和C++作为他们首选学习语言,但是学Java好呢?还是学C++更有前途?到底哪一门语言更有“钱途”呢?这个问题问的好,很多初学者都会有类似的疑问,今天我就来给大家简单的解答一下。1、C++和Java在编程排行榜中的排名作为IT行业的软件研发人员,在我看来,这两种语言都可以学,都很有前途。其实Java和C++一直名列世界编程语言排行榜的前几位,始终是热门的开发语言,下图是最近的世界编程语言排行榜:不管是从世界…

    2022年7月17日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号