基于libusb的无驱设计Word格式.docx
《基于libusb的无驱设计Word格式.docx》由会员分享,可在线阅读,更多相关《基于libusb的无驱设计Word格式.docx(22页珍藏版)》请在冰点文库上搜索。
usb_find_busses
intusb_find_busses(void);
寻找系统上的usb总线,任何usb设备都通过usb总线和计算机总线通信。
进而和其他设备通信。
此函数返回总线数。
usb_find_devices
intusb_find_devices(void);
寻找总线上的usb设备,这个函数必要在调用usb_find_busses()后使用。
以上的三个函数都是一开始就要用到的,此函数返回设备数量。
usb_get_busses
structusb_bus*usb_get_busses(void);
这个函数返回总线的列表,在高一些的版本中已经用不到了,这在下面的实例中会有讲解
2.2操作设备接口
usb_open
usb_dev_handle*usb_open(struct*usb_devicedev);
打开要使用的设备,在对硬件进行操作前必须要调用usb_open来打开设备,这里大家看到有两个结构体usb_dev_handle和usb_device是我们在开发中经常碰到的,有必要把它们的结构看一看。
在libusb中的usb.h和usbi.h中有定义。
这里我们不妨理解为返回的usb_dev_handle指针是指向设备的句柄,而行参里输入就是需要打开的设备。
usb_close
函数定义:
intusb_close(usb_dev_handle*dev);
与usb_open相对应,关闭设备,是必须调用的,返回0成功,<
0失败。
usb_set_configuration
intusb_set_configuration(usb_dev_handle*dev,intconfiguration);
设置当前设备使用的configuration,参数configuration是你要使用的configurtationdescriptoes中的bConfigurationValue,返回0成功,<
0失败(一个设备可能包含多个configuration,比如同时支持高速和低速的设备就有对应的两个configuration,详细可查看usb标准)
usb_set_altinterface
intusb_set_altinterface(usb_dev_handle*dev,intalternate);
和名字的意思一样,此函数设置当前设备配置的interfacedescriptor,参数alternate是指interfacedescriptor中的bAlternateSetting。
返回0成功,<
0失败
usb_resetep
intusb_resetep(usb_dev_handle*dev,unsignedintep);
复位指定的endpoint,参数ep是指bEndpointAddress,。
这个函数不经常用,被下面介绍的usb_clear_halt函数所替代。
usb_clear_halt
intusb_clear_halt(usb_dev_handle*dev,unsignedintep);
复位指定的endpoint,参数ep是指bEndpointAddress。
这个函数用来替代usb_resetep
usb_reset
intusb_reset(usb_dev_handle*dev);
这个函数现在基本不怎么用,不过这里我也讲一下,和名字所起的意思一样,这个函数reset设备,因为重启设备后还是要重新打开设备,所以用usb_close就已经可以满足要求了。
usb_claim_interface
intusb_claim_interface(usb_dev_handle*dev,intinterface);
注册与操作系统通信的接口,这个函数必须被调用,因为只有注册接口,才能做相应的操作。
Interface指bInterfaceNumber.(下面介绍的usb_release_interface与之相对应,也是必须调用的函数)
usb_release_interface
intusb_release_interface(usb_dev_handle*dev,intinterface);
注销被usb_claim_interface函数调用后的接口,释放资源,和usb_claim_interface对应使用。
2.3控制传输接口
usb_control_msg
intusb_control_msg(usb_dev_handle*dev,intrequesttype,intrequest,intvalue,intindex,char*bytes,intsize,inttimeout);
从默认的管道发送和接受控制数据
usb_get_string
intusb_get_string(usb_dev_handle*dev,intindex,intlangid,char*buf,size_tbuflen);
usb_get_string_simple
intusb_get_string_simple(usb_dev_handle*dev,intindex,char*buf,size_tbuflen);
usb_get_descriptor
intusb_get_descriptor(usb_dev_handle*dev,unsignedchartype,unsignedcharindex,void*buf,intsize);
usb_get_descriptor_by_endpoint
intusb_get_descriptor_by_endpoint(usb_dev_handle*dev,intep,unsignedchartype,unsignedcharindex,void*buf,intsize);
2.4批传输接口
usb_bulk_write
intusb_bulk_write(usb_dev_handle*dev,intep,char*bytes,intsize,inttimeout);
usb_interrupt_read
intusb_interrupt_read(usb_dev_handle*dev,intep,char*bytes,intsize,inttimeout);
2.5中断传输接口
usb_bulk_write
usb_interrupt_read
基本上libusb所经常用到的函数就有这些了,和usb协议确实很接近吧。
下面我们实例在介绍一个应用。
基于libusb的无驱设计
(二)
使用libusb之前你的linux系统必须装有usb文件系统,这里还介绍了使用hiddev设备文件来访问设备,目的在于不仅可以比较出usb的易用性,还提供了一个转化成libusb驱动的案例。
3.1find设备
任何驱动第一步首先是寻找到要操作的设备,我们先来看看HID驱动是怎样寻找到设备的。
我们假设寻找设备的函数Device_Find(注:
代码只是为了方便解说,不保证代码的健全)
[cpp:
nogutter]viewplaincopyprint?
1.
.
/*
我们简单看一下使用hid驱动寻找设备的实现,然后在看一下libusb是如何寻找设备的
*/
2.
int
Device_Find()
3.
{
4.
char
dir_str[100];
这个变量我们用来保存设备文件的目录路径
5.
hiddev[100];
这个变量用来保存设备文件的全路径
6.
DIR
dir;
7.
8.
申请的字符串数组清空,这个编程习惯要养成
9.
memset
(dir_str,
0
sizeof(dir_str));
10..
(hiddev,
sizeof(hiddev));
11..
12..
hiddev
的设备描述符不在/dev/usb/hid下面,就在/dev/usb
下面
13..
这里我们使用opendir函数来检验目录的有效性
14.14.
打开目录返回的值保存在变量dir里,dir前面有声明
15..
16..
dir=opendir("
/dev/usb/hid"
);
17..
if(dir){
18..
程序运行到这里,说明存在
/dev/usb/hid
路径的目录
19..
sprintf(dir_str,"
/dev/usb/hid/"
20..
closedir(dir);
21..
}else{
22..
如果不存在hid目录,那么设备文件就在/dev/usb下
23..
/dev/usb/"
24..
}
25..
26..
DEVICE_MINOR
是指设备数,HID一般是16个
27..
for(i
=
0;
i
<
DEVICE_MINOR;
i++)
28..
获得全路径的设备文件名,一般hid设备文件名是hiddev0
到
hiddev16
29..
sprintf(hiddev,
"
%shiddev%d"
dir_str,i);
30..
31..
打开设备文件,获得文件句柄
32..
fd
open(hiddev,
O_RDWR);
33..
if(fd
>
0)
34..
35..
操作设备获得设备信息
36..
ioctl(fd,
HIDIOCGDEVINFO,
&
info);
37..
38..
VENDOR_ID
和
PRODUCT_ID
是标识usb设备厂家和产品ID,
39..
驱动都需要这两个参数来寻找设备,到此我们寻找到了设备
40..
if(info.vendor==
info.product==
PRODUCT_ID)
41..
这里添加设备的初始化代码
42..
43..
44..
device_num++;
找到的设备数
45..
46..
close(fd);
47..
48..
49..
return
device_num;
返回寻找的设备数量
50..
我们再来看libusb是如何来寻找和初始化设备
struct
usb_bus
*busses;
device_num
记录设备数量
usb_init();
初始化
usb_find_busses();
寻找系统上的usb总线
usb_find_devices();
寻找usb总线上的usb设备
获得系统总线链表的句柄
14..
busses
usb_get_busses();
*bus;
遍历总线
for
(bus
busses;
bus;
bus
bus->
next)
usb_device
*dev;
遍历总线上的设备
(dev
devices;
dev;
dev
dev->
寻找到相关设备,
if(dev->
descriptor.idVendor==VENDOR_ID&
descriptor.idProduct
==
PRODUCT_ID){
返回设备数量
注:
在新版本的libusb中,usb_get_busses就可以不用了,这个函数是返回系统上的usb总线链表句柄
这里我们直接用usb_busses变量,这个变量在usb.h中被定义为外部变量
所以可以直接写成这样:
1..
2..
usb_busses;
3..
4..
5..
6..
7..
3.2打开设备
假设我们定义的打开设备的函数名是device_open,
1
使用hid驱动打开设备
Device_Open()
handle;
传统HID驱动调用,通过open打开设备文件就可
handle
open(“hiddev0”,
O_RDONLY);
使用libusb打开驱动
LIBUSB
驱动打开设备,这里写的是伪代码,不保证代码有用
usb_device*
udev;
usb_dev_handle*
device_handle;
当找到设备后,通过usb_open打开设备,这里的函数就相当open
函数
device_handle
usb_open(udev);
3.3读写设备和操作设备
假设我们的设备使用控制传输方式,至于批处理传输和中断传输限于篇幅这里不介绍
我们这里定义三个函数,Device_Write,Device_Read,Device_Report
Device_Report功能发送接收函数
Device_Write功能写数据
Device_Read
功能读数据
Device_Write和Device_Read调用Device_Report发送写的信息和读的信息,开发者根据发送的命令协议来设计,我们这里只简单实现发送数据的函数。
假设我们要给设备发送72字节的数据,头8个字节是报告头,是我们定义的和设备相关的规则,后64位是数据。
HID驱动的实现(这里只是用代码来有助理解,代码是伪代码)
Device_Report(int
fd,
unsigned
*buffer72)
ret;
保存ioctl函数的返回值
index;
send_data[72];
发送的数据