libusb-win32

 一、 libusb 介�B


   libusb �O�了一系列的外部API ���用程序所呼叫,通�^�@些API��用程序可以操作硬件,��libusb的原始�a可以看出,�@些API 呼叫了核心的底�咏槊妫�和kernel driver中所用到的函�邓����F的功能差不多,只是libusb更加接近USB ��。使得libusb的使用也比�_�l核心��映淌较�θ菀椎亩唷�

Libusb 的��g安�b�查看Readme,�@�e不做�解

二、 libusb 的外部介面

2.1 初始化�O�浣槊�

�@些介面也可以�Q�楹诵暮��担�它��主要用�沓跏蓟��K�ふ蚁嚓P�O�洹�

usb_init

函�刀��x: void usb_init(void);

�暮��得��Q可以看出�@��函�凳怯�沓跏蓟�相�P�Y料的,�@��函�荡蠹抑灰��住必�呼叫就行了,而且是一�_始就要呼叫的.

usb_find_busses

函�刀��x: int usb_find_busses(void);

�ふ蚁到y上的usb�R流排,任何usb�O�涠纪ㄟ^usb�R流排和�算�C�R流排通�。�M而和其他�O�渫ㄓ�。此函�捣祷�R流排�怠�

usb_find_devices

函�刀��x: int usb_find_devices(void);

�ふ�R流排上的usb�O�洌��@��函�当匾�在呼叫usb_find_busses()後使用。以上的三��函�刀际且婚_始就要用到的,此函�捣祷卦O��盗俊�

usb_get_busses

函�刀��x: struct usb_bus *usb_get_busses(void);

�@��函�捣祷�R流排的列表,在高一些的版本中已�用不到了,�@在下面的��例中��有�v解

2.2 操作�O�浣槊�

    usb_open

函�刀��x: usb_dev_handle *usb_open(struct *usb_device dev);

打 �_要使用的�O�洌�在�τ布��M行操作前必�要呼叫usb_open �泶蜷_�O�洌��@�e大家看到有����Y���w usb_dev_handle 和 usb_device 是我��在�_�l中�常碰到的,有必要把它��的�Y��看一看。在libusb 中的usb.h和usbi.h中有定�x。

�@�e我��不妨理解�榉祷氐� usb_dev_handle 指�是指向�O�涞挠�息�理函式,而行�⒀e�入就是需要打�_的�O�洹�

   usb_close

   函�刀��x: int usb_close(usb_dev_handle *dev);

   �cusb_open相���,�P�]�O�洌�是必�呼叫的, 返回0成功,<0 失� �

   usb_set_configuration

   函�刀��x: int usb_set_configuration(usb_dev_handle *dev, int configuration);

   �O置��前�O�涫褂玫�configuration,���configuration 是你要使用的configurtation descriptoes中的bConfigurationValue, 返回0成功,<0失��( 一���O�淇赡馨�含多��configuration,比如同�r支持高速和低速的�O�渚陀���的���configuration,��可查看usb���)

   usb_set_altinterface

   函�刀��x: int usb_set_altinterface(usb_dev_handle *dev, int alternate);

   和名字的意思一�樱�此函�翟O置��前�O�渑渲玫�interface descriptor,���alternate是指interface descriptor中的bAlternateSetting。返回0成功,<0失��

   usb_resetep

   函�刀��x: int usb_resetep(usb_dev_handle *dev, unsigned int ep);

   �臀恢付ǖ�endpoint,���ep 是指bEndpointAddress,。�@��函�挡唤�常用,被下面介�B的usb_clear_halt函�邓�替代。

   usb_clear_halt

   函�刀��x: int usb_clear_halt (usb_dev_handle *dev, unsigned int ep);

   �臀恢付ǖ�endpoint,���ep 是指bEndpointAddress。�@��函�涤�硖娲�usb_resetep

   usb_reset

   函�刀��x: int usb_reset(usb_dev_handle *dev);

   �@��函�惮F在基本不怎�N用,不�^�@�e我也�v一下,和名字所起的意思一�樱��@��函��reset�O�洌�因�橹�⒃O�溽徇�是要重新打�_�O�洌�所以用usb_close就已�可以�M足要求了。

   usb_claim_interface

   函�刀��x: int usb_claim_interface(usb_dev_handle *dev, int interface);

   �]�耘c操作系�y通�的介面,�@��函�当仨�被呼叫,因�橹挥性]�越槊妫�才能做相��的操作。

Interface 指 bInterfaceNumber. (下面介�B的usb_release_interface �c之相���,也是必�呼叫的函��)

   usb_release_interface

   函�刀��x: int usb_release_interface(usb_dev_handle *dev, int interface);

   �]�N被usb_claim_interface函�岛艚嗅岬慕槊妫��放�Y源,和usb_claim_interface���使用。

2.3 控制�鬏�介面

   usb_control_msg

   函�刀��x:int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);

   ��
�A�O的管道�l送和接受控制�Y料

   usb_get_string

   函�刀��x: int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen);

   usb_get_string_simple

函�刀��x: int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen);

   usb_get_descriptor

   函�刀��x: int usb_get_descriptor(usb_dev_handle *dev, unsigned char type, unsigned char index, void *buf, int size);

   usb_get_descriptor_by_endpoint

   函�刀��x: int usb_get_descriptor_by_endpoint(usb_dev_handle *dev, int ep, unsigned char type, unsigned char index, void *buf, int size);

2.4 批次�鬏�介面

   usb_bulk_write

   函�刀��x: int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

    usb_interrupt_read

函�刀��x: int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

2.5 中��鬏�介面

usb_bulk_write

函�刀��x: int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

usb_interrupt_read

函�刀��x: int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

基本上libusb所�常用到的函�稻陀羞@些了,和usb�f�h�_��很接近吧。下面我����例在介�B一����用。

//===================================

Libusb函式�斓氖褂�
使用libusb之前你的linux系�y必��b有usb�n案系�y,�@�e�介�B了使用hiddev�O��n案�碓L���O�洌�目的在於不�H可以比�^出usb的易用性,�提供了一���D化成libusb��映淌降陌咐�。

3.1 find�O��
任何��映淌降谝徊绞紫仁�ふ业揭�操作的�O�洌�我��先�砜纯�HID��映淌绞窃��ふ业皆O�涞摹N��假�O�ふ以O�涞暮���Device_Find(�]:程式�a只是�榱朔奖憬庹f,不保�C程式�a的健全)

/* 我����慰匆幌率褂�hid��映淌�ふ以O�涞���F,然後在看一下libusb是如何�ふ以O�涞� */
int Device_Find()
{
    char dir_str[100];   /* �@����滴��用��Υ嬖O��n案的目�路�� */
    char hiddev[100];    /* �@����涤��Υ嬖O��n案的 完整路�� */
DIR dir;              
/* 申�的字串�列清空,�@���程��T要�B成 */
memset (dir_str, 0 , sizeof(dir_str));
memset (hiddev, 0 , sizeof(hiddev));
    /* hiddev 的�O�涿枋龇�不在/dev/usb/hid下面,就在/dev/usb 下面
�@�e我��使用opendir函���z�目�的有效性
打�_目�返回的值�Υ嬖谧���dir�e,dir前面有�明
*/
dir=opendir("/dev/usb/hid");
    if(dir){
        /* 程序�绦械竭@�e,�f明存在 /dev/usb/hid 路�降哪夸� */
        sprintf(dir_str,"/dev/usb/hid/");
        closedir(dir);
    }else{
        /* 如果不存在hid目�,那�N�O��n案就在/dev/usb下 */
        sprintf(dir_str,"/dev/usb/");
    }
    /* DEVICE_MINOR 是指�O��担�HID一般是16�� */
for(i = 0; i < DEVICE_MINOR; i++) {
    /* �@得完整路�降脑O��n案名,一般hid�O��n案名是hiddev0 到 hiddev16 */
        sprintf(hiddev, "%shiddev%d", dir_str,i);
       /* 打�_�O��n案,�@得�n案�息�理函式 */
       fd = open(hiddev, O_RDWR);
       if(fd > 0) {
           /* 操作�O�浍@得�O�溆�息 */
          ioctl(fd, HIDIOCGDEVINFO, &info);
   
              /* VENDOR_ID 和 PRODUCT_ID 是�俗Rusb�O��S家和�a品ID,��映淌蕉夹枰��@�������ふ以O�洌�到此我���ふ业搅嗽O�� */
           if(info.vendor== VENDOR_ID && info.product== PRODUCT_ID) {
                /* �@�e添加�O�涞某跏蓟�程式�a */
                  
               device_num++;   /* 找到的�O��� */
           }
           close(fd);
       }
    }
    return device_num;         /* 返回�ふ业脑O��盗� */
}


我��再�砜�libusb是如何��ふ液统跏蓟��O��

int Device_Find()
{
struct usb_bus             *busses;
    int                           device_num = 0;
    device_num = 0;       /* ���O��盗� */
   
    usb_init();            /* 初始化 */
    usb_find_busses();   /* �ふ蚁到y上的usb�R流排 */
    usb_find_devices(); /* �ふ�usb�R流排上的usb�O�� */
   
    /* �@得系�y�R流排�表的�息�理函式 */
busses = usb_get_busses();
    struct usb_bus       *bus;
    /* 遍�v�R流排 */
    for (bus = busses; bus; bus = bus->next) {
        struct usb_device *dev;
        /* 遍�v�R流排上的�O�� */
        for (dev = bus->devices; dev; dev = dev->next) {
           /* �ふ业较嚓P�O�洌� */
if(dev->descriptor.idVendor==VENDOR_ID&& dev->descriptor.idProduct == PRODUCT_ID) {
                /* �@�e添加�O�涞某跏蓟�程式�a */
                  
               device_num++;   /* 找到的�O��� */
}              
        }       
    }
    return device_num;        /* 返回�O��盗� */
}


�]:在新版本的libusb中,usb_get_busses就可以不用了,�@��函�凳欠祷叵到y上的usb�R流排�表�息�理函式。
�@�e我��直接用usb_busses��担��@����翟�usb.h中被定�x�橥獠孔��担�所以可以直接��成�@�樱�

struct usb_bus    *bus;
        for (bus = usb_busses; bus; bus = bus->next) {
               struct usb_device *dev;
        for (dev = bus->devices; dev; dev = dev->next) {
           /* �@�e添加�O�涞某跏蓟�程式�a */
        }
}


3.2 打�_�O��
假�O我��定�x的打�_�O�涞暮��得�是device_open,

/* 使用hid��映淌酱蜷_�O�� */
int Device_Open()
{
    int handle;
    /* �鹘yHID��映淌胶艚校�通�^open打�_�O��n案就可 */
handle = open(「hiddev0」, O_RDONLY);
}
/* 使用libusb打�_��映淌� */
int Device_Open()
{
/* LIBUSB ��映淌酱蜷_�O�洌��@�e��的是��M�a,不保�C程式�a有用 */
struct usb_device*    udev;
usb_dev_handle*        device_handle;
/* ��找到�O�溽幔�通�^usb_open打�_�O�洌��@�e的函�稻拖喈�open 函�� */
device_handle = usb_open(udev);
}


3.3 �x���O�浜筒僮髟O��
假�O我��的�O�涫褂每刂�鬏�方式,至於批�理�鬏�和中��鬏�限於篇幅�@�e不介�B。

我���@�e定�x三��函�担�Device_Write, Device_Read,Device_Report

Device_Report 功能�l送接收函��
Device_Write 功能��入�Y料
Device_Read   功能�x取�Y料

Device_Write和Device_Read呼叫Device_Report�l送��的�息和�x的�息,�_�l者根���l送的命令�f�h�碓O�,我���@�e只�����F�l送�Y料的函�怠�

假�O我��要�o�O�浒l送72字�M的�Y料,�^8��字�M是�蟾骖^,是我��定�x的和�O�湎嚓P的��t,後64位是�Y料。
HID��映淌降���F(�@�e只是用程式�a�碛兄�理解,程式�a是��M�a)

int Device_Report(int fd, unsigned char *buffer72)
{
int       ret; /* �Υ�ioctl函�档姆祷刂� */
int      index;
    unsigned char send_data[72]; /* �l送的�Y料   */
unsigned char recv_data[72]; /* 接收的�Y料 */
    struct hiddev_usage_ref uref; /* hid��映淌蕉��x的�Y料封包 */
    struct hiddev_report_info rinfo; /* hid��映淌蕉��x的  */
    memset(send_data, 0, sizeof(send_data));
memset(recv_data, 0, sizeof(recv_data));
    memcpy(send_data, buffer72, 72);
   /* �@在�l送�Y料之前必�呼叫的,初始化�O�� */
    ret = ioctl(fd, HIDIOCINITREPORT, 0);
    if( ret !=0) {
        return NOT_OPENED_DEVICE;/* NOT_OPENED_DEVICE �凫蹲约憾��x巨集 */
    }
    /* HID�O�涿看�鬏�一��字�M的�Y料封包 */
    for(index = 0; index < 72; index++) {
        /* �O置�l送�Y料的��B */
    uref.report_type = HID_REPORT_TYPE_FEATURE;
    uref.report_id = HID_REPORT_ID_FIRST;
    uref.usage_index = index;
    uref.field_index = 0;
    uref.value = send_data[index];
    ioctl(fd, HIDIOCGUCODE, &uref);
    ret=ioctl(fd, HIDIOCSUSAGE, &uref);
    if(ret != 0 ){
           return UNKNOWN_ERROR;
    }
}
/* �l送�Y料 */
rinfo.report_type = HID_REPORT_TYPE_FEATURE;
rinfo.report_id = HID_REPORT_ID_FIRST;
rinfo.num_fields = 1;
ret=ioctl(fd, HIDIOCSREPORT, &rinfo);   /* �l送�Y料 */
if(ret != 0) {
        return WRITE_REPORT;
}
/* 接收�Y料 */
ret = ioctl(fd, HIDIOCINITREPORT, 0);
for(index = 0; index < 72; index++) {
    uref.report_type = HID_REPORT_TYPE_FEATURE;
    uref.report_id = HID_REPORT_ID_FIRST;
    uref.usage_index = index;
    uref.field_index = 0;
    ioctl(fd, HIDIOCGUCODE, &uref);
    ret = ioctl(fd, HIDIOCGUSAGE, &uref);
    if(ret != 0 ) {
        return UNKNOWN_ERROR;
    }
    recv_data[index] = uref.value;
}
memcpy(buffer72, recv_data, 72);
return SUCCESS;
}


libusb��映淌降���F:

int Device_Report(int fd, unsigned char *buffer72)
{
    /* 定�x�O�溆�息�理函式 */
    usb_dev_handle* Device_handle;
   
    /* save the data of send and receive */
    unsigned char   send_data[72];
    unsigned char   recv_data[72];
   
    int              send_len;
    int             recv_len;
   
    /* �Y料置空 */
    memset(send_data, 0 , sizeof(send_data));
    memset(recv_data, 0 , sizeof(recv_data));
   
    /* �@�e的g_list是全域的�Y料��担��e面可以存�ο嚓P�O�涞乃�需�息,��然我�� 也可以�暮��敌�⒅�鬏��M�恚��O�涞挠�息在打�_�O��r初始化,我���⒃卺崦娴目��Y中��描述一下 */
    Device_handle = (usb_dev_handle*)(g_list[fd].device_handle);
    if (Device_handle == NULL) {
        return NOT_OPENED_DEVICE;
}
/* �@��函�登懊嬉呀��f�^,在操作�O�淝笆潜仨�呼叫的, 0是指用 �A�O 的�O�� */
usb_claim_interface(Device_handle, 0);
/* �l送�Y料,所用到的巨集定�x在usb.h可以找到,我列出�泶蠹铱匆幌�
       #define USB_ENDPOINT_OUT       0x00
       #define USB_TYPE_CLASS     (0x01 << 5)
       #define USB_RECIP_INTERFACE 0x01
      
       #define HID_REPORT_SET       0x09 */
send_len = usb_control_msg(Device_handle,
USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
                               HID_REPORT_SET,
                               0x300,
                               0,
                               send_data, 72, USB_TIMEOUT);
/* �l送�Y料有�e�` */
if (send_len < 0) {
        return WRITE_REPORT;
}
if (send_len != 72) {
        return send_len;
}
/* 接收�Y料
       #define USB_ENDPOINT_IN         0x80
       #define USB_TYPE_CLASS          (0x01 << 5)
       #define USB_RECIP_INTERFACE        0x01
       #define HID_REPORT_GET          0x01
    */
recv_len = usb_control_msg(Device_handle,
USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
                               HID_REPORT_GET,
                               0x300,
                                 0,
                               recv_data, 72, USB_TIMEOUT);
                                                   
    if (recv_len < 0) {
        printf("failed to retrieve report from USB device!/n");
        return READ_REPORT;
    }
   
    if (recv_len != 72) {
        return recv_len;
    }
   
   
    /* 和usb_claim_interface��� */
    usb_release_interface(RY2_handle, 0);
    memcpy(buffer72, recv_data, 72);
return SUCCESS;
}


3.4 �P�]�O��
假�O我��定�x的�P�]�O�涞暮��得�是Device_Close()

/* 使用hid��映淌疥P�]�O�� */
int Device_Close()
{
    int handle;
   
handle = open(「hiddev0」, O_RDONLY);
/* �鹘yHID��映淌胶艚校�通�^close()�O��n案就可 */
close( handle );
}
/* 使用libusb�P�]��映淌� */
int Device_Close()
{
/* LIBUSB ��映淌酱蜷_�O�洌��@�e��的是��M�a,不保�C程式�a有用 */
struct usb_device*    udev;
usb_dev_handle*        device_handle;
device_handle = usb_open(udev);
/* libusb函式�焓褂�usb_close�P�]程序 */
usb_close(device_handle);
}


libusb的��映淌娇蚣�
前面我��看了些主要的libusb函�档氖褂茫��@�e我��把前面的�热�w�{下:
一般的��映淌���都包含如下介面:

Device_Find(); /* �ふ以O�浣槊� */
Device_Open(); /* 打�_�O�浣槊� */
Device_Write(); /* ��入�O�浣槊� */
Device_Read(); /* �x取�O�浣槊� */
Device_Close(); /* �P�]�O�浣槊� */


具�w程式�a如下:

#include <usb.h>
/* usb.h�@���^�n案是要包括的,�e面包含了必�要用到的�Y料�Y�� */
/* 我���⒁���O�涞�傩杂靡���Y���w�砀爬� */
typedef struct
{
    struct usb_device*    udev;
    usb_dev_handle*        device_handle;
    /* �@�e可以添加�O�涞钠渌��傩裕��@�e只列出每���O�湟�用到的�傩� */
} device_descript;
/* 用�碓O置�鬏��Y料的�r�g延�t */
#define USB_TIMEOUT     10000
/* �S家ID 和�a品 ID */
#define VENDOR_ID    0xffff    
#define PRODUCT_ID   0xffff
/* �@�e定�x�列��Υ嬖O�涞南嚓P�傩裕�DEVICE_MINOR可以�O置能�蛲��r操作的�O��盗浚�用全域��档哪康脑陟斗奖�Υ�傩� */
#define DEVICE_MINOR 16
int     g_num;
device_descript g_list[ DEVICE_MINOR ];
/* 我�������O�湎日业皆O�洌��K把相�P�息�Υ嬖� g_list 中 */
int Device_Find()
{
    struct usb_bus       *bus;
    struct usb_device *dev;
    g_num = 0;
    usb_find_busses();
    usb_find_devices();
   
    /* �ふ以O�� */
    for (bus = usb_busses; bus; bus = bus->next) {
        for (dev = bus->devices; dev; dev = dev->next) {
if(dev->descriptor.idVendor==VENDOR_ID&& dev->descriptor.idProduct == PRODUCT_ID) {
                    /* �Υ嬖O�溆�息 */
                    if (g_num < DEVICE_MINOR) {
                     g_list[g_num].udev = dev;  
                     g_num ++;
                     }              
            }       
        }
    }
   
    return g_num;
}
/* 找到�O�溽幔�我��根���息打�_�O�� */
int Device_Open()
{
    /* 根��情�r打�_你所需要操作的�O�洌��@�e我���H列出��M�a */
    if(g_list[g_num].udev != NULL) {
        g_list[g_num].device_handle = usb_open(g_list[g_num].udev);
}
}
/* 下面就是操作�O�涞暮��盗耍�我��就不列出�砝�,大家可以�⒖忌厦娴慕榻B */
int DeviceWite(int handle)
{
    /* 填��相�P程式�a,具�w查看�O��f�h*/
}
int DeviceOpen(int handle)
{
    /* 填��相�P程式�a,具�w查看�O��f�h */
}
/* 最後不要忘��P�]�O�� */
void Device_close(int handle)
{
    /* 呼叫usb_close */
}


小�Y
   到此,使用libusb�M行��映淌介_�l介�B完了,通�^��函式�焖�提供的API的使用可以�w��到libusb的易用性。

 

 

//本文转载自http://blog.csdn.net/leino11121/article/details/6344088

//仅供学习参考 欢迎交流

你可能感兴趣的:(职场,休闲,libusb)