imx6q添加两路CAN并实现通信功能

目的:在imx6q上添加第二路CAN的驱动支持,并实现第二路CAN的通信功能。

CPU:imx6q

Linux:imx linux3.10.53

 

一、添加二路CAN的驱动支持

这个过程很简单,就是添加第二路CAN的设备树,驱动系统已经帮我们做好。

在内核源码中搜索can,可以在imx6q-sabresd.dts中发现如下信息:

imx6q添加两路CAN并实现通信功能_第1张图片

这是原本已经添加的一路CAN的设备树(一部分代码),仿照此段添加另一路CAN的设备树即可。如下:

imx6q添加两路CAN并实现通信功能_第2张图片

其中第4行的trx-stby-gpio是使能can芯片,低电平使能,如果原理图中已将此引脚拉低,可不写。

修改完成后重新编译,然后将设备树和内核烧入开发板启动,如果一切正确,ifconfig -a后可看到can0和can1。

 

二、两路CAN通信的Linux应用程序编写

两路can通信使用两条can总线,因此建立两个socket即可:

void can_init( void )
{
    int socked, socked_can1;
	struct sockaddr_can can_addr;
	struct ifreq ifr;
	int b_on=1;
	
	if((socked = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) 
	{
        printf("if((socked = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) \n");
		return;
	}
    memset(&ifr, 0, sizeof(ifr));
	strcpy(ifr.ifr_name, DEV_CAN);

	if (RET_SUCCESS != ioctl(socked, SIOCGIFINDEX, &ifr))
	{
		close(socked);
		return;
	}
	printf("ioctl has been  set \n");
	
	t_RetData = ioctl (socked, FIONBIO, &b_on);    //b_on=1,设置为非阻塞模式

    memset(&can_addr, 0, sizeof(can_addr));
	can_addr.can_family  = AF_CAN;
	can_addr.can_ifindex = 2; 
  
	if(bind(socked, (struct sockaddr *)&can_addr, sizeof(can_addr)) < 0) 
	{
		close(socked);
		return;
	}
    printf("CAN initialed");
    s_Can0Socket = socked;
	 
	

	printf("InitCAN1 \n");
	if((socked_can1 = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) 
	{
        printf("if((socked = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) \n");
		return;
	}
    memset(&ifr, 0, sizeof(ifr));
	strcpy(ifr.ifr_name, DEV_CAN1);

	if (RET_SUCCESS != ioctl(socked_can1, SIOCGIFINDEX, &ifr))
	{
	    printf("if (RET_SUCCESS != ioctl(socked, SIOCGIFINDEX, &ifr))\n");
		close(socked_can1);
		return;
	}
	printf("ioctl has been  set \n");

	b_on = 0;
	t_RetData = ioctl(socked_can1, FIONBIO, &b_on);
    printf("t_RetData:%d",t_RetData);

    memset(&can_addr, 0, sizeof(can_addr));
	can_addr.can_family  = AF_CAN;
	can_addr.can_ifindex = 3;			// 这里ifindex不能和第一个的相同,不然会有问题。可以在系统中查看此值
  
	if(bind(socked_can1, (struct sockaddr *)&can_addr, sizeof(can_addr)) < 0) 
	{
		close(socked_can1);
		return;
	}
    printf("CAN initialed ");
    s_Can1Socket = socked_can1;
	
    return;    
   
}

 

你可能感兴趣的:(imx6q,Linux驱动)