linux下 libusb使用--打开usb设备进行通信

下载编译安装libusb:https://blog.csdn.net/u011598479/article/details/82705378

1.确定你要通信的USB设备的一些参数。

    user_device.idProduct = USB_PRODUCT_ID; //PID

    user_device.idVendor = USB_VENDOR_ID ; //VID

    user_device.bInterfaceClass = LIBUSB_CLASS_PRINTER ; //打印机设备

    user_device.bInterfaceSubClass = LIBUSB_CLASS_PER_INTERFACE ; //预留接口

    user_device.bmAttributes = LIBUSB_TRANSFER_TYPE_BULK ; //usb bulk 通信方式

    user_device.dev = NULL; //初始化参数

 

user_device为我设置的结构体,用来保存一些要用到的参数。

 

2.init_libusb(); //调用这个库函数初始化库

 

 

3.获取设备描述符,然后根据第一步的设备参数遍历配置描述符,接口描述符,端点描述符,找到USB设备端点地址

4.打开设备libusb_open_device_with_vid_pid()

 

5.声明接口libusb_claim_interface()

 

6.发送数据libusb_bulk_transfer()

 

7.关闭设备,释放接口,释放申请的空间,退出库

libusb_close(g_usb_handle);

libusb_release_interface(g_usb_handle,user_device.bInterfaceNumber);

libusb_free_device_list(user_device.devs, 1);

 libusb_exit(NULL);

 

Makefile

# C compiler options
CC	= gcc
#CFLAGS	= -g -O2             
TARGET	=	main
LIBSPATH = ../lib
PLATFORM = linux32
#LIBS	= /usr/local/lib -lusb-1.0
LIBS	= /usr/local/lib/libusb-1.0.a -lm -lpthread
INC	= /usr/local/include/libusb-1.0

#多字节字符 指定汉字编码方式GB18030
EXCHAR	= -fexec-charset=GB18030    

# Source files
SRCS = main.c

# Object files
OBJS	= $(SRCS:.c=.o)

# Make everything
all:	$(TARGET) 

# Make the application
#-lstdc++:编译c++的时候用到
$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) $(EXCHAR) -o $(TARGET) $(OBJS)  $(LIBS) 

# Dependencies
#$@:表示目标文件,即:demo.o
#$<:表示依赖文件,即:demo.c
#-I$(INC) :指向包含了的.h文件的路径 即wbe,h的路径
$(OBJS): %.o: %.c 
	$(CC) -c $(CFLAGS) $(EXCHAR) -o $@ $< -I$(INC)  
#
# Clean all object files...
#

clean:
	$(RM) $(OBJS) $(TARGET) 

 

main.c

/*
 * libusb example program to list devices on the bus
 * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <stdio.h>

#include "libusb.h"

#define USB_VENDOR_ID 0x0483
#define USB_PRODUCT_ID 0x8007

#define BULK_ENDPOINT_OUT 1
#define BULK_ENDPOINT_IN  2

struct userDevice{
	/*Device descriptor*/

	/** USB-IF vendor ID */
	uint16_t idVendor;

	/** USB-IF product ID */
	uint16_t idProduct;

	/*Interface descriptor*/

	/** USB-IF class code for this interface. See \ref libusb_class_code. */
	uint8_t  bInterfaceClass;

	/** USB-IF subclass code for this interface, qualified by the
	 * bInterfaceClass value */
	uint8_t  bInterfaceSubClass;

	/*Endpoint descriptor*/

	/** Attributes which apply to the endpoint when it is configured using
	 * the bConfigurationValue. Bits 0:1 determine the transfer type and
	 * correspond to \ref libusb_transfer_type. Bits 2:3 are only used for
	 * isochronous endpoints and correspond to \ref libusb_iso_sync_type.
	 * Bits 4:5 are also only used for isochronous endpoints and correspond to
	 * \ref libusb_iso_usage_type. Bits 6:7 are reserved.
	 */
	
	uint8_t  bmAttributes;

	
	/*save parameter*/

	libusb_device *dev;
	libusb_device **devs;


	u_int8_t bInEndpointAddress;

	u_int8_t bOutEndpointAddress;

	/* Number of this interface */
	uint8_t  bInterfaceNumber;
};


int init_libusb(void)
{
	/*1. init libusb lib*/
	int rv = 0;
	
	rv = libusb_init(NULL);
	if(rv < 0) {
		printf("*** initial USB lib failed! \n");    
		return -1;
	}
	return rv;
}


int get_device_descriptor(struct libusb_device_descriptor *dev_desc,struct userDevice *user_device)
{
	/*2.get device descriptor*/
	int rv = -2;
	ssize_t cnt;
	int i = 0;

	libusb_device **devs;
	libusb_device *dev;

	cnt = libusb_get_device_list(NULL, &devs); //check the device number
	if (cnt < 0)
		return (int) cnt;

	while ((dev = devs[i++]) != NULL) {
		rv = libusb_get_device_descriptor(dev,dev_desc);
		if(rv < 0) {
			printf("*** libusb_get_device_descriptor failed! i:%d \n",i);
			return -1;
		}
		if(dev_desc->idProduct==user_device->idProduct &&dev_desc->idVendor==user_device->idVendor)
		{
			user_device->dev = dev;
			user_device->devs = devs;
			rv = 0;
			break;
		}
	}
	return rv;
}


int match_with_endpoint(const struct libusb_interface_descriptor * interface, struct userDevice *user_device)
{
	int i;
	int ret=0;
	for(i=0;i<interface->bNumEndpoints;i++)
	{
		if((interface->endpoint[i].bmAttributes&0x03)==user_device->bmAttributes)   //transfer type :bulk ,control, interrupt
		{
				if(interface->endpoint[i].bEndpointAddress&0x80)					//out endpoint & in endpoint
				{
					ret|=1;
					user_device->bInEndpointAddress = interface->endpoint[i].bEndpointAddress;
				}
				else
				{
					ret|=2;
					user_device->bOutEndpointAddress = interface->endpoint[i].bEndpointAddress;
				}
		}
										
	}
	if(ret==3)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

int get_device_endpoint(struct libusb_device_descriptor *dev_desc,struct userDevice *user_device)
{
	/*3.get device endpoint that you need */
	int rv = -2;
	int i,j,k;
	struct libusb_config_descriptor *conf_desc;
	u_int8_t isFind = 0;
	for (i=0; i< dev_desc->bNumConfigurations; i++)
	{
		if(user_device->dev != NULL)
			rv = libusb_get_config_descriptor(user_device->dev,i,&conf_desc);
		if(rv < 0) {
			printf("*** libusb_get_config_descriptor failed! \n");    
			return -1;
		}
		for (j=0; j< conf_desc->bNumInterfaces; j++)
		{
			for (k=0; k < conf_desc->interface[j].num_altsetting; k++)
			{
				if(
					conf_desc->interface[j].altsetting[k].bInterfaceClass==user_device->bInterfaceClass
					)
				{
					if(match_with_endpoint(&(conf_desc->interface[j].altsetting[k] ), user_device ))
					{
						user_device->bInterfaceNumber = conf_desc->interface[j].altsetting[k].bInterfaceNumber;
						libusb_free_config_descriptor(conf_desc);
						rv = 0;
						return rv;
					}
				}
			}
		}
	}
	return -2;  //don't find user device
}


int main(void)
{
	int rv;

	int length;

	unsigned char a[100] = {0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a};

	libusb_device_handle* g_usb_handle;

	struct userDevice user_device;
	struct libusb_device_descriptor dev_desc;

	user_device.idProduct = USB_PRODUCT_ID;
	user_device.idVendor =  USB_VENDOR_ID ;
	user_device.bInterfaceClass = LIBUSB_CLASS_PRINTER ;
	user_device.bInterfaceSubClass = LIBUSB_CLASS_PRINTER ;
	user_device.bmAttributes = LIBUSB_TRANSFER_TYPE_BULK ;
	user_device.dev = NULL;

	init_libusb();

	rv = get_device_descriptor(&dev_desc,&user_device);
	if(rv < 0) {
			printf("*** get_device_descriptor failed! \n");    
			return -1;
		}

	rv = get_device_endpoint(&dev_desc,&user_device);
	if(rv < 0) {
			printf("*** get_device_endpoint failed! rv:%d \n",rv);    
			return -1;
		}

	
	/*4.open device and start communication by usb*/
	//open the usb device
	g_usb_handle = libusb_open_device_with_vid_pid(NULL, user_device.idVendor, user_device.idProduct);
	if(g_usb_handle == NULL) {
		printf("*** Permission denied or Can not find the USB board (Maybe the USB driver has not been installed correctly), quit!\n");
		return -1;
	}

	rv = libusb_claim_interface(g_usb_handle,user_device.bInterfaceNumber);
	if(rv < 0) {
		rv = libusb_detach_kernel_driver(g_usb_handle,user_device.bInterfaceNumber);
		if(rv < 0) {
			printf("*** libusb_detach_kernel_driver failed! rv%d\n",rv);    
			return -1;
		}
		rv = libusb_claim_interface(g_usb_handle,user_device.bInterfaceNumber);
		if(rv < 0)
		{
			printf("*** libusb_claim_interface failed! rv%d\n",rv);    
			return -1;
		}

	}


	rv = libusb_bulk_transfer(g_usb_handle,BULK_ENDPOINT_OUT,a,100,&length,1000);	
	if(rv < 0) {
		printf("*** bulk_transfer failed! \n");    
		return -1;
	}

	libusb_close(g_usb_handle);

	libusb_release_interface(g_usb_handle,user_device.bInterfaceNumber);

	libusb_free_device_list(user_device.devs, 1);

	libusb_exit(NULL);
}

 

  • 15
    点赞
  • 128
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
libusb-1.0.22是一个开源的用户空间USB库,可以用于Linux、macOS、Windows等操作系统。它提供了一个简单的编程接口,使开发者能够方便地与USB设备进行通信libusb-1.0.22支持USB 1.1和USB 2.0标准,并且还提供了对USB 3.0和USB 3.1的初步支持。它可以用于控制USB设备的各种功能,如数据的读取和写入、设备的配置和控制、USB接口的复位等。开发者可以使用libusb-1.0.22库来开发各种用途的USB设备驱动程序、USB设备管理工具以及其他需要与USB设备进行交互的应用程序。 libusb-1.0.22的主要特点包括: 1. 跨平台支持:libusb-1.0.22可以在不同的操作系统上使用,开发者可以使用相同的代码来编写USB应用程序,而无需考虑底层操作系统的差异。 2. 简单易用:libusb-1.0.22提供了一组简单的API函数,使得开发者能够轻松地进行USB设备的操作和通信。开发者只需了解USB设备通信协议和规范,就可以使用libusb-1.0.22来实现与USB设备的交互。 3. 功能丰富:libusb-1.0.22支持各种USB设备的操作,包括控制传输、批量传输、中断传输以及同步传输。此外,libusb-1.0.22还支持USB设备的热插拔和事件通知,方便开发者进行设备的动态管理。 总之,libusb-1.0.22是一个强大而灵活的USB库,可以帮助开发者更简便地实现USB设备的控制和通信功能。无论是开发USB设备驱动程序还是与USB设备进行交互的应用程序,libusb-1.0.22都是一个很好的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值