NXP

I.MX6 Android 平台CAN总线调试(包含测试C语言代码)

2019-07-12 13:59发布

        I.MX6 Android 平台CAN总线调试(包含测试C语言代码)

  前言:这几天需要调试NXP Android平台CAN总线,以前到工作中都没有接触过can总线,折腾了几天,终于通信成功。至于can总线的原理我就不细说了,网上很多,原理很复杂,也比较难懂,我们主要还是学习如何使用就可以了。这里就记录以下在android平台下如何使用can进行通信。 一、外围电路CAN总线收发驱动电路。 二、在imx6q的的BSP中已经有了CAN总线的驱动,驱动的源代码在drivers etcanflexcan.c,一般情况下已经打开了CAN功能,如果没打开的话进入kernel代码执行make menuconfig对内核进行配置,如下图,具体的设置就不细说。 三、adb shell进入调试模式,使用iproute2工具到ip命令,查看和设置can参数,这个工具android已经集成有,直接使用。
        ifconfig  -a  //确认是否有can0 和can1存在
        ifconfig can0 down         //关闭can0,以便配置
        ip link set can0 up type can bitrate 500000         //设置can0波特率
        ip link set can0 up  // 启动can0
        ip link set can0 down // 关闭can0
        ip -details -statistics link show can0  //查看统一参数
        ip -details link show can0  //查看统一参数 四、PC端用工具跟ARM开发板进行can通信。  4.1、arm开发板can总线收发can数据测试c语言代码。 /* * can_test_send_and_dump.c * * Created on: 2018-8-25 * Author: tanghanyue */ #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int s, nbytes; unsigned char number=0; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame; struct can_frame frame_send; struct can_filter rfilter[1]; pid_t pid = -1; int i; /* handle (optional) flags first */ if(argc != 2) { fprintf(stderr, "Usage: %s <-r> for receiving or <-s> for sending ", argv[0]); exit(1); } /* create socket */ if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { perror("Create socket failed"); exit(-1); } /* set up can interface */ strcpy(ifr.ifr_name, argv[1]); printf("can port is %s ",ifr.ifr_name); /* assign can device */ ioctl(s, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; /* bind can device */ if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Bind can device failed "); close(s); exit(-2); } pid = fork(); if(pid == -1) { perror(" failed to fork!! "); return -1; } else if(pid==0)/* configure receiving can data*/ { /* set filter for only receiving packet with can id 0x88 */ rfilter[0].can_id = 0x88; rfilter[0].can_mask = CAN_SFF_MASK; if(setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)) < 0) { perror("set receiving filter error "); close(s); exit(-3); } /* keep reading */ while(1){ nbytes = read(s, &frame, sizeof(frame)); if(nbytes > 0) { printf("read datas:%s ID=%#x data length=%d ", ifr.ifr_name, frame.can_id, frame.can_dlc); for ( i=0; i < frame.can_dlc; i++) printf("%#x ", frame.data[i]); printf(" "); } printf("read can data over "); } }/* configure sending can data*/ else { while(1) { /* configure can_id and can data length */ frame_send.can_id = 0x88; frame_send.can_dlc = 8; printf("%s ID=%#x data length=%d ", ifr.ifr_name, frame_send.can_id, frame_send.can_dlc); /* prepare data for sending: 0x11,0x22...0x88 */ for (i=0; i<8; i++) { frame_send.data[i] = ((i+1)<<4) | (i+1); frame_send.data[7] =number; printf("%#x ", frame_send.data[i]); } printf("success to Sent out "); /* Sending data */ if(write(s, &frame_send, sizeof(frame_send)) < 0) { perror("Send failed"); close(s); exit(-4); } sleep(1); number++; } } close(s); return 0; } 4.2、PC通过USB口连接到CAN分析仪,将arm开发板到can端口连接到can分析仪。 4.3、PC端运行USB_CAN TOOL,安装对应的USB驱动。 4.4、在ubuntu下用ARM交叉编译工具把c语言代码编译成可执行文件,然后adb push到android设备/system/bin/路径下,执行can_test_send_and_dump can0. 4.5、USB_CAN TOOL打开can连接,可以看到收发can数据。 4.6、注意的一点是,测试程序只接收ID为0x88的CAN设备发送过来到can数据,在USB_CAN TOOL要设置ID为0x88,不然ARM板端接收不到数据。 4.7、PC机和arm板的can通信成功。