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


相关推荐

  • puremvc的unity案例_游戏防闪退框架

    puremvc的unity案例_游戏防闪退框架作者:吴秦出处:http://www.cnblogs.com/skynet/本文基于署名2.5中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名吴秦(包含链接).参考资料[1]    PureMVC官方网站:www.puremvc.org[2]    Wikipedia:http://zh.wikipedia.org/zh-cn/MVC[

    2025年8月13日
    4
  • Kong Api 初体验

    Kong Api 初体验转载请标明出处:https://blog.csdn.net/forezp/article/details/79383631本文出自方志朋的博客Kong是一个可扩展的开源API层(也称为API网关或API中间件)。Kong运行在任何RESTfulAPI的前面,并通过插件扩展,它们提供超出核心平台的额外功能和服务。Kong最初是在Mashape建立的,用于为其AP…

    2022年6月26日
    23
  • linux命令_linux挂载cifs报错

    linux命令_linux挂载cifs报错[pcd@localhostax_peta]$petalinux-config–get-hw-description../SG400_top_hw_platform_1INFO:Gettinghardwaredescription…cp:omittingdirectory‘/home/pcd/peta_prj/SG400_top_hw_platform_1/cache…

    2022年9月11日
    4
  • 罗马字符转换数字_数字变成字符串怎么改过来

    罗马字符转换数字_数字变成字符串怎么改过来今年在力扣上做了一道这个题,还算简单,主要是理解规则。解法也有很多种,我这里用的是常规解法,先将输入进来的字符串转换为字符数组,然后进行一系列操作。题目:罗马数字包含以下七种字符:I,V,X,L,C,D和M。字符数值I1V5X10L50C100D500M1000例如,…

    2022年9月30日
    4
  • Zigbee 协议栈

    Zigbee 协议栈Zigbee协议栈平台协议栈对我们的作用怎么使用协议栈协议栈的安装、编译与下载Components(部件)Documents(文件)Projects(项目例子)Tools(工具)平台协议TIZStack-CC2530-2.5.1a协议栈对我们的作用协议栈是协议的实现,可以理解为代码,函数库,供上层应用调用,协议较底下的层与应用是相互独立的。商业化的协议栈就是给你写好了底层的代码,符合协议标准,提供给你一个功能模块给你调用。你需要关心的就是你的应用逻辑,数据从哪里到哪里,怎么存储,处

    2022年5月28日
    35
  • 基于Linux搭建Apache网站服务配置详解

    基于Linux搭建Apache网站服务配置详解

    2021年7月6日
    66

发表回复

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

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