您的位置:首页 > 其它

BeagleBone Black CAN总线读写数据操作

2013-12-16 11:00 302 查看
进入BBB之后可以通过ifconfig -a来查看是否打开CAN总线了:

root@BBB-CAN:~# ifconfig -a
can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          UP RUNNING NOARP  MTU:16  Metric:1
          RX packets:25 errors:0 dropped:0 overruns:0 frame:0
          TX packets:62 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:65535 
          RX bytes:104 (104.0 B)  TX bytes:312 (312.0 B)
          Interrupt:71 
............


如果没有看到can0之类的接口的话,估计是你的BBB CAN总线还没被打开,你可以去看这篇文章来打开你的CAN总线。/article/2466788.html。使用CAN总线之前需要配置CAN属性(波特率等)并且启动CAN,也可以在该博客中看到。

BeagleBone Black的CAN总线使用socketcan,因此在你打开完CAN总线的socket之后的操作基本和你使用socket一样的。

socketcan的相关内容可以去看wiki。http://en.wikipedia.org/wiki/Socketcan

废话不多,直接来一个例子吧,是想CAN总线上发送0到7数据包(和cansend can0 0 1 2 3 4 5 6 7一样功能)。

/**
 * BeagleBone Black CAN Bus
 * trb
 * 2013-12-16
 * ©ynsoft.cn
 *
 * @see http://en.wikipedia.org/wiki/Socketcan  */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/can.h>
#include <linux/can/raw.h>

int main(int argc, char *argv[]) {
	int sock_can = 0, i;
	struct sockaddr_can addr;
	static struct can_frame can_frame;
	struct ifreq ifr;

	// 创造嵌套子
	if ((sock_can = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
		perror("Create socket failed");
		exit(-1);
	}

	// 设置CAN接口名称为can0
	strcpy(ifr.ifr_name, "can0");
	ioctl(sock_can, SIOCGIFINDEX, &ifr);
	addr.can_family = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;

	// 绑定CAN总线
	if (bind(sock_can, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("Bind failded");
		close(sock_can);
		exit(-2);
	}
	can_frame.can_id = 0x123;	// 设置CANID
	can_frame.can_dlc = 8;	// 数据长度为8

	// 下面简单的设置数据为0到7
	for(i=0; i<8; ++i){
		can_frame.data[i] = i;
	}

	// 发送 0 1 2 3 4 5 6 7, CAN-ID 0x123
	if(write(sock_can, &can_frame, sizeof(struct can_frame))<0){
		perror("Send failded");
		close(sock_can);
		exit(-3);
	}
	close(sock_can);
	return 0;
}


接收也是差不多一样的,传入一个can_frame结构就行:

len = read(sock_can_listen, &can_frame, sizeof(struct can_frame));


如果返回的len小于0的话就是接收出错了。
接收成功之后can_frame的.can_id代表该数据包来自哪个CANID,.can_dlc是CAN数据长度(0-8),而.data里面就放着就收到的数据了。

最后,如果你需要通过代码而非命令行来设置CAN的相关属性的话推荐一个库,叫做libsocketcan,这个地方可以找到http://www.pengutronix.de/software/libsocketcan/download/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: