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)
上一篇 2022年6月29日 下午10:46
下一篇 2022年6月29日 下午11:00


相关推荐

  • Android中根据coverage.ec文件生成报告

    Android中根据coverage.ec文件生成报告关于android中的代码覆盖率,可以参考我前几篇文章:Android手工测试代码覆盖率增强版Android手工测试的代码覆盖率AndroidUI自动化测试的代码覆盖率官方生成代码覆盖率报告的流程gradle为android提供的插件生成代码覆盖率的报告流程为首先在应用目录的生成coverage.ec文件(比如我们的应用package为com.wuba.wuxian.android_0

    2022年7月20日
    17
  • 普林斯顿结构和哈佛结构_模具哈佛结构图

    普林斯顿结构和哈佛结构_模具哈佛结构图普林斯顿结构 –通用计算机 ARM7                        –冯诺依曼结构 哈佛结构         –单片机  ARM9ARM10ARM11 普林斯顿结构:指令、数据混合存储,结构简单,成本低。 哈佛结构   :指令、数据分开存储,高速数据处理,可同时读指令、读数据,大大提高了数据吞吐量,缺点是结构复杂。   指令、

    2022年10月5日
    4
  • Nmap命令详解及常用命令总结[通俗易懂]

    Nmap命令详解及常用命令总结[通俗易懂]Nmap学习文章目录Nmap学习0Nmap介绍1Nmap命令详解1.1Nmap命令help详解(内附中文翻译)1.2Nmap命令思维导图2Nmap常见使用场景以及相关命令2.1Nmap常用扫描命令2.1.1扫描固定端口,以sqlServer为例2.1.2获取远程主机的系统类型及开放端口2.1.3列出开放了指定端口的主机列表2.1.4在网络寻找所有在线主机2.1.5…

    2022年5月28日
    115
  • Java 是值传递还是引用传递

    Java 是值传递还是引用传递最近整理面试题 整理到值传递 引用传递 到网上搜了一圈 争议很大 带着一脸蒙圈 线上线下查了好多资料 最终有所收获 所以分享给大家 希望能对你有所帮助 首先说下我的感受 这个题目出的很好 但是在 Java 中这个题目是有问题的 在下面我会解释 并且 有很多结论是 Java 中只有值传递 我认为这样说不够严谨 当然如果针对 Java 语言本身来讲 Java 中只有值传递 没有

    2026年3月19日
    3
  • PowerMockito使用详解

    PowerMockito使用详解一 为什么要使用 Mock 工具 nbsp nbsp nbsp nbsp 在做单元测试的时候 我们会发现我们要测试的方法会引用很多外部依赖的对象 比如 发送邮件 网络通讯 远程服务 文件系统等等 而我们没法控制这些外部依赖的对象 为了解决这个问题 我们就需要用到 Mock 工具来模拟这些外部依赖的对象 来完成单元测试 nbsp nbsp nbsp nbsp 二 为什么要使用 PowerMock nbsp nbsp nbsp 现如今比较流行的 Mock 工具如 jMo

    2026年3月20日
    2
  • window修改host文件权限_win10hosts文件在哪

    window修改host文件权限_win10hosts文件在哪文章目录第一步进入host目录下第二步编辑hosts文件中users用户的属性第三步授权users用户完全控制权限第四步编辑hosts文件第一步进入host目录下第二步编辑hosts文件中users用户的属性第三步授权users用户完全控制权限第四步编辑hosts文件格式IP地址(空格)网址202.108.22.5www.baidu.com…

    2022年10月10日
    5

发表回复

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

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