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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 什么是TCP粘包?怎么解决这个问题[通俗易懂]

    什么是TCP粘包?怎么解决这个问题[通俗易懂]在socket网络编程中,都是端到端通信,由客户端端口+服务端端口+客户端IP+服务端IP+传输协议组成的五元组可以明确的标识一条连接。在TCP的socket编程中,发送端和接收端都有成对的socket。发送端为了将多个发往接收端的包,更加高效的的发给接收端,于是采用了优化算法(Nagle算法),将多次间隔较小、数据量较小的数据,合并成一个数据量大的数据块,然后进行封包。那么这样一来,接收端就必须…

    2022年8月11日
    3
  • smo算法C语言,SMO算法详解[通俗易懂]

    smo算法C语言,SMO算法详解[通俗易懂]一、我们先回顾下SVM问题。A、线性可分问题1、SVM基本原理:SVM使用一种非线性映射,把原训练数据映射到较高的维。在新的维上,搜索最佳分离超平面,两个类的数据总可以被超平面分开。2、问题的提出:3、如何选取最优的划分直线f(x)呢?4、求解:凸二次规划建立拉格朗日函数:求偏导数:B、线性不可分问题1、核函数如下图:横轴上端点a和b之间红色部分里的所有点定为正类,两边的黑色部分里的点定为负类…

    2022年6月15日
    25
  • 时间复杂度和空间复杂度 如何计算出来_代码时间复杂度和空间复杂度

    时间复杂度和空间复杂度 如何计算出来_代码时间复杂度和空间复杂度时间复杂度和空间复杂度如何计算?推导算法:大O推导法时间复杂度定义常数阶线性阶对数阶平方阶小结空间复杂度定义推导算法:大O推导法1、用常数1取代运行时间中的所有加法常数2、在修改后的运行次数函数中,只保留最高阶项3、如果最高阶项存在且不是1,那么我们就去除于这个项相乘的常数。时间复杂度定义在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变…

    2025年7月7日
    0
  • docker 查看redis 版本「建议收藏」

    dockerexec-itcontainer-name-or-idredis-server-v

    2022年4月17日
    106
  • tinyXml生成XML文件

    tinyXml生成XML文件1.tinyXMl生成XML文件#include<stdio.h>#include<string>usingnamespacestd;#include”../tinyxml/tinyxml.h”inttest1(){ TiXmlDocumentxml_doc; //添加XML声明 xml_doc.LinkEndChild(n…

    2022年6月5日
    66
  • linux命令之pstack[通俗易懂]

    linux命令之pstack[通俗易懂]很多时候我们想知道在Linux下后台程序到底运行到哪里了,卡住了吗,出错了吗,最简单的我们会使用#psauxf|grep来查看后台程序的状态,可是如果想知道的更多,那就可以用到pstack这个命令了。首先举一个简单的例子(test.c)来引出这个命令 #include#include#includevoid*thread_proc(void*data)

    2022年9月14日
    0

发表回复

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

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