linux-can编程(一)

建立can的socket

int can_create_socket(char *name)
{
	int fd;
    	struct sockaddr_can addr;
    	struct ifreq ifr;

	socklen_t len = sizeof(addr);
	/* 
	 * RAW protocol sockets with can filters(SOCK_RAW) 
	 * Broadcast Manager protocol sockets(SOCK_DGRAM)
	 */
    	fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
//	fd = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);

	if(fd < 0)	return -1;

    	strcpy(ifr.ifr_name, name );
    	ioctl(fd, SIOCGIFINDEX, &ifr);
		
	/* 非阻塞 */
//	int flags = fcntl(fd, F_GETFL, 0);
//	fcntl(fd, F_SETFL, flags |O_NONBLOCK);

    	addr.can_family = AF_CAN;
    	addr.can_ifindex = ifr.ifr_ifindex;
	
    	bind(fd, (struct sockaddr *)&addr, len);

	return fd;
}

设置can的波特率

void can1_baudrate_set(int bitrate)
{
	system("ip link set can1 down");
	if(bitrate == CAN_50K_BAUDRATE){
		system("ip link set can1 type can bitrate 50000");
	}else if(bitrate == CAN_20K_BAUDRATE){
		system("ip link set can1 type can bitrate 20000");
	}	
	system("ip link set can1 up");

}

接受函数如下:

int can1_receive(void)
{
	int canFdMax, fd_act;	
	int can1_sock;
	int rxlen;
	fd_set 	recvFdSet;	
	struct timeval timeout;
	struct can_frame rxBuf;
	int  can_frame_size = sizeof(struct can_frame);
	
	can1_sock=can_create_socket("can1");
can1_baudrate_set(CAN_50K_BAUDRATE);//can1_baudrate_set(CAN_20K_BAUDRATE);
  while(1)
  {
		canFdMax = -1;
		FD_ZERO(&recvFdSet);
		if (can1_sock > 0) {
			FD_SET(can1_sock, &recvFdSet); 
			if(canFdMax < can1_sock) {canFdMax =can1_sock;}
		}		
		if(canFdMax > 0){
			timeout.tv_sec = 0;
			timeout.tv_usec = 8*1000;
			fd_act = 0;
			fd_act = select(canFdMax+1, &recvFdSet, NULL, NULL, &timeout);		
			if (fd_act > 0) {
				if (can1_sock > 0) {
					if (FD_ISSET(can1_sock, &recvFdSet)) {	/* can1 接收 */						
						rxLen = read(can1_sock, &rxBuf, can_frame_size);
						if(rxLen > 0){	
								/*解析rxbuf*/				
						}		
					}					
				}						
			}
		
		}
	
}
		

}

解析rxbuf过程,首先看can_frame结构体(我用的事扩展帧)

 	struct can_frame {

	canid_t can_id;//CAN 标识符
	__u8 can_dlc;//数据场的长度
	__u8 data[8];//数据

	};

截取rubuf的成员,可以建立一个自己的结构体,用来解析

typedef struct {
	unsigned char eff_rtr_err;
	unsigned char  fun1;
	unsigned char  fun2;
	unsigned char  fun3;
	unsigned char  fun4;
}can_id_t;
can_id_t can_id_out;

假设 fun1为22-29(21-28)、fun2为15-21(14-20)、fun3为8-14(7-13)、fun1为1-7(0-6)
can_id_out.eff_rtr_err=(uchar)((rxbuf.can_id & 0xe0000000)>>29);
can_id_out.fun1	= (uchar)((rxbuf.can_id & 0x1fe00000)>>21);
can_id_out.fun2	= (uchar)((rxbuf.can_id & 0x001fc000)>>14);
can_id_out.fun3	= (uchar)((rxbuf.can_id & 0x00003f80)>>7);
can_id_out.fun4	= (uchar)(rxbuf.can_id & 0x0000007f);


rxbuf.can_dlc用来判断长度;
rxbuf.data为接受数据

发送数据类似

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值