首页 通过USB驱动libusb介绍和使用示例

通过USB驱动libusb介绍和使用示例

举报
开通vip

通过USB驱动libusb介绍和使用示例小知识:sudoinsmod/lib/modules/2.6.22-14-generic/kernel/drivers/usb/serial/usbserial.kovendor=0x8086product=0xd001同时插上ttyUSB0和ttyUSB1(ch341),obm能将dkb下载下去,不过自动重起之后,就不能下载接下来的东西了,所以应该,需要close(ttyUSB0_handle);然后进行接下来的下载,分别调用两次不过应该自动关闭了,所以可能还是不能同时插上ttyUSB0和ttyUSB1lsusb...

通过USB驱动libusb介绍和使用示例
小知识:sudoinsmod/lib/modules/2.6.22-14-generic/kernel/drivers/usb/serial/usbserial.kovendor=0x8086product=0xd001同时插上ttyUSB0和ttyUSB1(ch341),obm能将dkb下载下去,不过自动重起之后,就不能下载接下来的东西了,所以应该,需要close(ttyUSB0_handle);然后进行接下来的下载,分别调用两次不过应该自动关闭了,所以可能还是不能同时插上ttyUSB0和ttyUSB1lsusb显示usb设备的vendor和product比如:b074@gliethttp:~$lsusbBus002Device001:ID0000:0000  Bus001Device116:ID8086:d001IntelCorp.Bus001Device003:ID413c:2105DellComputerCorp.Bus001Device002:ID0461:4d15PrimaxElectronics,LtdBus001Device001:ID0000:0000其中Bus001Device116:ID8086:d001IntelCorp.就是vendor=0x8086和product=0xd001能使用dmesg来查看具体的是ttyUSB0还是ttyUSB1了pidofhello.exepidofbash显示进程的pid值波特率:#define  B0  0000000      /*hangup*/#define  B50  0000001#define  B75  0000002#define  B110  0000003#define  B134  0000004#define  B150  0000005#define  B200  0000006#define  B300  0000007#define  B600  0000010#define  B1200  0000011#define  B1800  0000012#define  B2400  0000013#define  B4800  0000014#define  B9600  0000015#define  B19200  0000016#define  B38400  0000017#defineEXTAB19200#defineEXTBB38400#defineCSIZE  0000060#define  CS5  0000000#define  CS6  0000020#define  CS7  0000040#define  CS8  0000060#defineCSTOPB  0000100#defineCREAD  0000200#definePARENB  0000400#definePARODD  0001000#defineHUPCL  0002000#defineCLOCAL  0004000#defineCBAUDEX0010000#define  BOTHER0010000#define  B576000010001#define  B1152000010002#define  B2304000010003#define  B4608000010004//有些CDMA使用该波特率#define  B5000000010005#define  B5760000010006#define  B9216000010007#define  B10000000010010#define  B11520000010011#define  B15000000010012#define  B20000000010013#define  B25000000010014#define  B30000000010015#define  B35000000010016#define  B40000000010017DevelopingLinuxDeviceDriversusingLibusbAPI  Writtenbyvikram_cvk-2004-07-1618:05  IntroductionWeoftencomeacrossasituationwhereaUSBdevicewhichrunsperfectlyon视窗系统platformdoesnotevengetdetectedonLinux.LackofsupportforUSBdevicesisoneofthereasonwhysomepeopledon’tembraceLinux.NowthereisanewAPIbynameLibusbwhichhelpsthedeveloperstodevelopUSBdevicedriversonthefly!    WhatisLibusbLibusbisahigh-levellanguageAPIwhichconcealslow-levelkernelinteractionswiththeUSBmodules.ItprovidesasetoffunctionwhichareadequatetodevelopadevicedriverforaUSBdevicefromtheUserspace.    LibusbisnotcomplexForanywannabeLinuxKernelprogrammersdevelopingdevicedriverasaKernelmoduleisaherculeantask.Developingkernelmodulesrequiresfairdegreeofproficiencyin’C’languageandalsogoodideaofkernelsubsystems,datastructuresetc.Alltheseareenoughtoput-offadeveloperfromventuringintoDeviceDriverprogramming.Libusbhasbeendesignedtoaddressthisshortcoming.SimplifiedinterfaceallowsdeveloperstodevelopUSBdriversfromtheuserspace.LibusblibraryfunctionsprovidehighlevelabstractiontotheKernelstructuresandallowsthedeveloperstohaveaccesstothesestructuresthroughtheUSBFS(USBfilesystem).    ItsCross-platformBeautyofLibusbliesinitscrossplatformfunctionality.Driverwrittenforoneplatformcouldbeeasilyportedontoanotherplatformwithlittleornochanges,currentlyfollowingoperatingsystemsaresupportedbyLibusb.    Linux  FreeBSD  Darwin  OSX  ThisHOWTOfocusesonhowLibusbcanbeusedonLinuxplatform.Forinformationaboutotherplatformsgotohttp://http://libusb.sourceforge.net/.      LIBUSBONLINUXLinuxisthemostpopularplatformfortheLibusbAPI,thereasonbeinggrowingpopularityofLinuxasastableOS.OnLinuxLibusbmakesoftheUSBFSfilesystem.bydefaultUSBFSisautomaticallymountedwhenthesystemisbooted.    WhatisUSBFSUSBFSisafilesystemspecificallydesignedforUSBdevices,bydefaultthisfilesystemgetsmountedwhenthesystemisbootedanditcanbefoundat/proc/bus/usb/.ThisfilesystemconsistsofinformationaboutalltheUSBdevicesthatareconnectedtothecomputer.LibusbmakesuseofthisfilesystemtointeractwiththeUSBdevices.  FollowingCprogramcanbeasteppingstoneintotheworldofLibusb.Thisprogramcanbeusedtogatherallthetechnical/hardwaredetailsofaUSBdeviceconnectedtothecomputer,ensurethatsomeUSBdeviceisconnectedintotheUSBport.  DetailslikeVendor-Id,Product-Id,EndpointaddressesofaUSBdeviceisofparamountimportanceforadevicedriverdeveloper.    /*testlibusb.c*/    #include  #include      voidprint_endpoint(structusb_endpoint_descriptor*endpoint)  {  printf("bEndpointAddress:%02xh\n",endpoint->bEndpointAddress);  printf("bmAttributes:%02xh\n",endpoint->bmAttributes);  printf("wMaxPacketSize:%d\n",endpoint->wMaxPacketSize);  printf("bInterval:%d\n",endpoint->bInterval);  printf("bRefresh:%d\n",endpoint->bRefresh);  printf("bSynchAddress:%d\n",endpoint->bSynchAddress);  }      voidprint_altsetting(structusb_interface_descriptor*interface)  {  inti;    printf("bInterfaceNumber:%d\n",interface->bInterfaceNumber);  printf("bAlternateSetting:%d\n",interface->bAlternateSetting);  printf("bNumEndpoints:%d\n",interface->bNumEndpoints);  printf("bInterfaceClass:%d\n",interface->bInterfaceClass);  printf("bInterfaceSubClass:%d\n",interface->bInterfaceSubClass);  printf("bInterfaceProtocol:%d\n",interface->bInterfaceProtocol);  printf("iInterface:%d\n",interface->iInterface);    for(i=0;ibNumEndpoints;i++)  print_endpoint(&interface->endpoint);  }      voidprint_interface(structusb_interface*interface)  {  inti;    for(i=0;inum_altsetting;i++)  print_altsetting(&interface->altsetting);  }      voidprint_configuration(structusb_config_descriptor*config)  {  inti;    printf("wTotalLength:%d\n",config->wTotalLength);  printf("bNumInterfaces:%d\n",config->bNumInterfaces);  printf("bConfigurationValue:%d\n",config->bConfigurationValue);  printf("iConfiguration:%d\n",config->iConfiguration);  printf("bmAttributes:%02xh\n",config->bmAttributes);  printf("MaxPower:%d\n",config->MaxPower);    for(i=0;ibNumInterfaces;i++)  print_interface(&config->interface);  }      intmain(void)  {  structusb_bus*bus;  structusb_device*dev;    usb_init();  usb_find_busses();  usb_find_devices();    printf("bus/deviceidVendor/idProduct\n");    for(bus=usb_busses;bus;bus=bus->next){  for(dev=bus->devices;dev;dev=dev->next){  intret,i;  charstring[256];  usb_dev_handle*udev;    printf("%s/%s%04X/%04X\n",bus->dirname,dev->filename,  dev->descriptor.idVendor,dev->descriptor.idProduct);    udev=usb_open(dev);  if(udev){  if(dev->descriptor.iManufacturer){  ret=usb_get_string_simple(udev,dev->descriptor.iManufacturer,string,sizeof(string));  if(ret>0)  printf("-Manufacturer:%s\n",string);  else  printf("-Unabletofetchmanufacturerstring\n");  }    if(dev->descriptor.iProduct){  ret=usb_get_string_simple(udev,dev->descriptor.iProduct,string,sizeof(string));  if(ret>0)  printf("-Product:%s\n",string);  else  printf("-Unabletofetchproductstring\n");  }    if(dev->descriptor.iSerialNumber){  ret=usb_get_string_simple(udev,dev->descriptor.iSerialNumber,string,sizeof(string));  if(ret>0)  printf("-SerialNumber:%s\n",string);  else  printf("-Unabletofetchserialnumberstring\n");  }    usb_close(udev);  }    if(!dev->config){  printf("Couldn’tretrievedescriptors\n");  continue;  }    for(i=0;idescriptor.bNumConfigurations;i++)  print_configuration(&dev->config);  }  }    return0;  }      Theaboveprogramshouldbecompiledas    (root$)gcc-ousbdevice_detailstestlibusb.c-I/usr/local/include-L.-lnsl-lm-lc-L/usr/local/lib-lusb    (root$)./usbdevice_details(enter)      Followingistheoutputoftheabovecommand,itsthelistingofaUSBpendriveconnectedtomysystem.    Thefirstlinedisplaysthebus-name/device-name&device-id/product-idandrestofthelistingisself-descriptive.      001/0040EA0/2168  -Manufacturer:USB  -Product:FlashDisk  -SerialNumber:4CE45C4E403EE53D  wTotalLength:39  bNumInterfaces:1  bConfigurationValue:1  iConfiguration:0  bmAttributes:80h  MaxPower:100  bInterfaceNumber:0  bAlternateSetting:0  bNumEndpoints:3  bInterfaceClass:8  bInterfaceSubClass:6  bInterfaceProtocol:80  iInterface:0  bEndpointAddress:81h  bmAttributes:02h  wMaxPacketSize:64  bInterval:0  bRefresh:0  bSynchAddress:0  bEndpointAddress:02h  bmAttributes:02h  wMaxPacketSize:64  bInterval:0  bRefresh:0  bSynchAddress:0  bEndpointAddress:83h  bmAttributes:03h  wMaxPacketSize:2  bInterval:1  bRefresh:0  bSynchAddress:0    BeforeexecutingtheaboveprogramdownloadthecurrentversionofLibusblibraryfrom,http://http://libusb.sourceforge.net/.TheaboveprogramcanalsobefoundunderthetestsdirectoryofLibusbdirectory(afteruinstallit)      NowIwillexplaininbriefsomeofthefunctionsandattributesdealtintheaboveprogram.    usb_init()-UsedtoinitializeLibusbandestablishconnectionwithkernelstructures.  usb_find_busses()-LooksforalltheUSBbussesonthecomputer.  usb_find_devices()-LooksforalltheUSBdevicesconnectedtothecomputer.  usb_open(dev)-Opensthedevice’dev’whichisgivenasargumenttothisfunction.  usb_get_string_simple()-Usedtoextractthestringdescriptorofthedevicetakenargument.    ImportantattributesofUSBdevicesusefulindevicedrivercoding  ConfigurationandEndpointsareoneofthetwoimportantdescriptorsofanyUSBdevice.Thesedescriptorsaredefinedusingthe?structusb_config_descriptor?and?struct_usb_endpoint_descriptor?respectively.    dev->descriptor.idVendor?RevealstheVendor-IdoftheUSBdeviceconnectedtothesystem.    dev->descriptor.idProduct-RevealstheProduct-IdoftheUSBdeviceconnectedtothesystem.    dev->descriptor.iManufacturer-RevealsthenameoftheManufacturerUSBdeviceconnectedtothesystem.    EndpointAddress:CombinationofendpointaddressandendpointdirectiononaUSBdevice.    InterfaceNumber:OneoftheseveralinterfacesthatisallocatedtotheconnectedUSBdevice.    AlternateSetting:ThisispartoftheasingleinterfaceallocatedtotheUSBdevice.      PrerequisitesforLibusbprogramming  LinuxsystemwithKernel2.4aboveseries.  ProficiencyinClanguage.  GoodunderstandingofUSBdeviceinternals.  IdeaaboutUSBFS.      HopethisHOWTOhasenlightenedyouaboutLibusbAPIandIexpectthisHOWTOwillgiveyouaheadstartinyourdevicedriverprogrammingendeavor.ThisHOWTOisjustanintroductiontoLibusb,forcompletedocumentationpleasegotohttp://http://libusb.sourceforge.net/    AboutMyselfMynameisVikramC,I’malinuxfreakandcurrentlyworkingasLinuxdeveloperinthecityofHyderabadIndia.Youcanreachmeatvikram_147@hotmail.com/vikram@asrttechnologies.com//================================================2008年03月19日星期三  10:31驱动研发向来是内核研发中工作量最多的一块,随着USB设备的普及,大量的USB设备的驱动研发也成为驱动研发者手头上做的最多的事情。本文主要介绍Linux平台下基于libusb的驱动研发,希望能够给从事Linux驱动研发的朋友带来些帮助,更希望能够给其他平台上的无驱设计带来些帮助。文章是我在工作中使用libusb的一些总结,难免有错误,如有不当的地方,还请指正。    Linux平台上的usb驱动研发,主要有内核驱动的研发和基于libusb的无驱设计。对于内核驱动的大部分设备,诸如带usb接口的hid设备,linux本身已自带了相关的驱动,我们只要操作设备文件便能完成对设备大部分的操作,而另外一些设备,诸如自己设计的硬件产品,这些驱动就需要我们驱动 工程 路基工程安全技术交底工程项目施工成本控制工程量增项单年度零星工程技术标正投影法基本原理 师研发出相关的驱动了。内核驱动有他的好处,然而内核驱动在某些情况下会遇见如下的一些问题:1当使用我们产品的客户有2.4内核的平台,同时也有2.6内核的平台,我们要设计的驱动是要兼容两个平台的,就连makefile我们都要写两个。2当我们要把linux移植到嵌入平台上,你会发现原先linux自带的驱动移过去还挺大的,我的内核当然是越小越好拉,这样有必要么。这还不是最郁闷的地方,如果嵌入平台是客户的,客户要购买你的产品,你忽然发现客户设备里的系统和你的环境不相同,他没有你要的驱动了,你的程式运行不了,你会先想:“没关系,我写个内核驱动加载一下不就行了“。却发现客户连insmod加载模块的工具都没移植,那时你就看看老天,说声我怎么那么倒霉啊,客户可不想你动他花了n时间移植的内核哦3花了些功夫写了个新产品的驱动,挺有成就感啊,代码质量也是相当的有水准啊。正当你沉醉在你的代码中时,客服不断的邮件来了,“客户需要2.6.5内核的驱动,config文件我已发你了”“客户需要双核的2.6.18-smp的驱动”“客户的平台是自己制定的是2.6.12-xxx“  你恨不得把驱动的原始码给客户,这样省得编译了。你的一部分工作时间编译内核,制定驱动有问题产生必然会有想办法解决问题的人,libusb的出现给我们带来了某些方便,即节约了我们的时间,也降低了公司的成本。所以在一些情况下,就能考虑使用libusb的无驱设计了。    下面我们就来周详讨论一下libusb,并以写一个hid设备的驱动来讲解怎么运用libusb,至于文章中涉及的usb 协议 离婚协议模板下载合伙人协议 下载渠道分销协议免费下载敬业协议下载授课协议下载 的知识,限于篇幅,就不周详讲解了,相关的可自行查看usb相关协议。一libusb介绍  libusb设计了一系列的外部API为应用程式所调用,通过这些API应用程式能操作硬件,从libusb的原始码能看出,这些API调用了内核的底层接口,和kerneldriver中所用到的函数所实现的功能差不多,只是libusb更加接近USB 规范 编程规范下载gsp规范下载钢格栅规范下载警徽规范下载建设厅规范下载 。使得libusb的使用也比研发内核驱动相对容易的多。Libusb的编译安装请查看Readme,这里不做详解二libusb的外部接口2.1初始化设备接口这些接口也能称为核心函数,他们主要用来初始化并寻找相关设备。usb_init函数定义:voidusb_init(void);从函数名称能看出这个函数是用来初始化相关数据的,这个函数大家只要记住必须调用就行了,而且是一开始就要调用的.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成功,Libusb库的使用使用libusb之前你的linux系统必须装有usb文件系统,这里还介绍了使用hiddev设备文件来访问设备,目的在于不仅能比较出usb的易用性,还提供了一个转化成libusb驱动的案例。3.1find设备所有驱动第一步首先是寻找到要操作的设备,我们先来看看HID驱动是怎样寻找到设备的。我们假设寻找设备的函数Device_Find(注:代码只是为了方便解说,不确保代码的健全)/*我们简单看一下使用hid驱动寻找设备的实现,然后在看一下libusb是怎么寻找设备的*/intDevice_Find(){    chardir_str[100];  /*这个变量我们用来保存设备文件的目录路径*/    charhiddev[100];    /*这个变量用来保存设备文件的全路径*/DIRdir;            /*申请的字符串数组清空,这个编程习惯要养成*/memset(dir_str,0,sizeof(dir_str));memset(hiddev,0,sizeof(hiddev));    /*hiddev的设备描述符不在/dev/usb/hid下面,就在/dev/usb下面这里我们使用opendir函数来检验目录的有效性打开目录返回的值保存在变量dir里,dir前面有声明*/dir=opendir("/dev/usb/hid");    if(dir){      /*程式运行到这里, 说明 关于失联党员情况说明岗位说明总经理岗位说明书会计岗位说明书行政主管岗位说明书 存在/dev/usb/hid路径的目录*/      sprintf(dir_str,"/dev/usb/hid/");      closedir(dir);    }else{      /*如果不存在hid目录,那么设备文件就在/dev/usb下*/      sprintf(dir_str,"/dev/usb/");    }    /*DEVICE_MINOR是指设备数,HID一般是16个*/for(i=0;i    /*获得全路径的设备文件名,一般hid设备文件名是hiddev0到hiddev16*/      sprintf(hiddev,"%shiddev%d",dir_str,i);      /*打开设备文件,获得文件句柄*/      fd=open(hiddev,O_RDWR);      if(fd>0){        /*操作设备获得设备信息*/        ioctl(fd,HIDIOCGDEVINFO,&info);              /*VENDOR_ID和PRODUCT_ID是标识usb设备厂家和产品ID,驱动都需要这两个参数来寻找设备,到此我们寻找到了设备*/        if(info.vendor==VENDOR_ID&&info.product==PRODUCT_ID){            /*这里添加设备的初始化代码*/                          device_num++;  /*找到的设备数*/        }        close(fd);      }    }    returndevice_num;      /*返回寻找的设备数量*/}我们再来看libusb是怎么来寻找和初始化设备intDevice_Find(){structusb_bus          *busses;    int                    device_num=0;    device_num=0;      /*记录设备数量*/        usb_init();        /*初始化*/    usb_find_busses();  /*寻找系统上的usb总线*/    usb_find_devices();/*寻找usb总线上的usb设备*/        /*获得系统总线链表的句柄*/busses=usb_get_busses();    structusb_bus      *bus;    /*遍历总线*/    for(bus=busses;bus;bus=bus->next){      structusb_device*dev;      /*遍历总线上的设备*/      for(dev=bus->devices;dev;dev=dev->next){        /*寻找到相关设备,*/if(dev->descriptor.idVendor==VENDOR_ID&&dev->descriptor.idProduct==PRODUCT_ID){            /*这里添加设备的初始化代码*/                          device_num++;  /*找到的设备数*/}                }          }    returndevice_num;      /*返回设备数量*/}注:在新版本的libusb中,usb_get_busses就能不用了,这个函数是返回系统上的usb总线链表句柄这里我们直接用usb_busses变量,这个变量在usb.h中被定义为外部变量所以能直接写成这样:structusb_bus    *bus;      for(bus=usb_busses;bus;bus=bus->next){            structusb_device*dev;      for(dev=bus->devices;dev;dev=dev->next){        /*这里添加设备的初始化代码*/      }}3.2打开设备假设我们定义的打开设备的函数名是device_open,/*使用hid驱动打开设备*/intDevice_Open(){    inthandle;    /*传统HID驱动调用,通过open打开设备文件就可*/handle=open(“hiddev0”,O_RDONLY);}/*使用libusb打开驱动*/intDevice_Open(){/*LIBUSB驱动打开设备,这里写的是伪代码,不确保代码有用*/structusb_device*    udev;usb_dev_handle*      device_handle;/*当找到设备后,通过usb_open打开设备,这里的函数就相当open函数*/device_handle=usb_open(udev);}3.3读写设备和操作设备假设我们的设备使用控制传输方式,至于批处理传输和中断传输限于篇幅这里不介绍我们这里定义三个函数,Device_Write,Device_Read,Device_ReportDevice_Report功能发送接收函数Device_Write功能写数据Device_Read  功能读数据Device_Write和Device_Read调用Device_Report发送写的信息和读的信息,研发者根据发送的命令协议来设计,我们这里只简单实现发送数据的函数。假设我们要给设备发送72字节的数据,头8个字节是 报告 软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载 头,是我们定义的和设备相关的规则,后64位是数据。HID驱动的实现(这里只是用代码来有助理解,代码是伪代码)intDevice_Report(intfd,unsignedchar*buffer72){int      ret;/*保存ioctl函数的返回值*/int    index;    unsignedcharsend_data[72];/*发送的数据*/unsignedcharrecv_data[72];/*接收的数据*/    structhiddev_usage_refuref;/*hid驱动定义的数据包*/    structhiddev_report_inforinfo;/*hid驱动定义的    memset(send_data,0,sizeof(send_data));memset(recv_data,0,sizeof(recv_data));    memcpy(send_data,buffer72,72);  /*这在发送数据之前必须调用的,初始化设备*/    ret=ioctl(fd,HIDIOCINITREPORT,0);    if(ret!=0){      returnNOT_OPENED_DEVICE;/*NOT_OPENED_DEVICE属于自己定义宏*/    }    /*HID设备每次传输一个字节的数据包*/    for(index=0;index      /*设置发送数据的状态*/    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){        returnUNKNOWN_ERROR;    }}/*发送数据*/rinfo.report_type=HID_REPORT_TYPE_FEATURE;rinfo.report_id=HID_REPORT_ID_FIRST;rinfo.num_fields=1;ret=ioctl(fd,HIDIOCSREPORT,&rinfo);  /*发送数据*/if(ret!=0){      returnWRITE_REPORT;}/*接受数据*/ret=ioctl(fd,HIDIOCINITREPORT,0);for(index=0;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){      returnUNKNOWN_ERROR;    }    recv_data[index]=uref.value;}memcpy(buffer72,recv_data,72);returnSUCCESS;}libusb驱动的实现intDevice_Report(intfd,unsignedchar*buffer72){    /*定义设备句柄*/    usb_dev_handle*Device_handle;        /*savethedataofsendandreceive*/    unsignedchar  send_data[72];    unsignedchar  recv_data[72];        int          send_len;    int          recv_len;        /*数据置空*/    memset(send_data,0,sizeof(send_data));    memset(recv_data,0,sizeof(recv_data));        /*这里的g_list是全局的数据变量,里面能存储相关设备的所需信息,当然我们也能从函数形参中传输进来,设备的信息在打开设备时初始化,我们将在后面的总结中周详描述一下*/    Device_handle=(usb_dev_handle*)(g_list[fd].device_handle);    if(Device_handle==NULL){      returnNOT_OPENED_DEVICE;}/*这个函数前面已说过,在操作设备前是必须调用的,0是指用默认的设备*/usb_claim_interface(Device_handle,0);/*发送数据,所用到的宏定义在usb.h能找到,我列出来大家看一下      #defineUSB_ENDPOINT_OUT      0x00      #defineUSB_TYPE_CLASS    (0x01      #defineUSB_RECIP_INTERFACE0x01            #defineHID_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);/*发送数据有错误*/if(send_len      returnWRITE_REPORT;}if(send_len!=72){      returnsend_len;}/*接受数据      #defineUSB_ENDPOINT_IN      0x80      #defineUSB_TYPE_CLASS        (0x01      #defineUSB_RECIP_INTERFACE      0x01      #defineHID_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      printf("failedtoretrievereportfromUSBdevice!\n");      returnREAD_REPORT;    }        if(recv_len!=72){      returnrecv_len;    }            /*和usb_claim_interface对应*/    usb_release_interface(RY2_handle,0);    memcpy(buffer72,recv_data,72);returnSUCCESS;}3.4关闭设备假设我们定义的关闭设备的函数名是Device_Close()/*使用hid驱动关闭设备*/intDevice_Close(){    inthandle;    handle=open(“hiddev0”,O_RDONLY);/*传统HID驱动调用,通过close()设备文件就可*/close(handle);}/*使用libusb关闭驱动*/intDevice_Close(){/*LIBUSB驱动打开设备,这里写的是伪代码,不确保代码有用*/structusb_device*    udev;usb_dev_handle*      device_handle;device_handle=usb_open(udev);/*libusb库使用usb_close关闭程式*/usb_close(device_handle);}libusb的驱动框架前面我们看了些主要的libusb函数的使用,这里我们把前面的内容归纳下:一般的驱动应该都包含如下接口:Device_Find();/*寻找设备接口*/Device_Open();/*打开设备接口*/Device_Write();/*写设备接口*/Device_Read();/*读设备接口*/Device_Close();/*关闭设备接口*/具体代码如下:#include/*usb.h这个头文件是要包括的,里面包含了必须要用到的数据结构*//*我们将一个设备的属性用一个结构体来概括*/typedefstruct{    structusb_device*    udev;    usb_dev_handle*      device_handle;    /*这里能添加设备的其他属性,这里只列出每个设备要用到的属性*/}device_descript;/*用来设置传输数据的时间延迟*/#defineUSB_TIMEOUT    10000/*厂家ID和产品ID*/#defineVENDOR_ID    0xffff    #definePRODUCT_ID  0xffff/*这里定义数组来保存设备的相关属性,DEVICE_MINOR能设置能够同时操作的设备数量,用全局变量的目的在于方便保存属性*/#defineDEVICE_MINOR16int    g_num;device_descriptg_list[DEVICE_MINOR];/*我们写个设备先找到设备,并把相关信息保存在g_list中*/intDevice_Find(){    structusb_bus      *bus;    structusb_device*dev;    g_num=0;    usb_find_busses();    usb_find_devices();        /*寻找设备*/    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){              /*保存设备信息*/              if(g_num                g_list[g_num].udev=dev;                  g_num++;                }                    }            }    }        returng_num;}/*找到设备后,我们根据信息打开设备*/intDevice_Open(){    /*根据情况打开你所需要操作的设备,这里我们仅列出伪代码*/    if(g_list[g_num].udev!=NULL){      g_list[g_num].device_handle=usb_open(g_list[g_n
本文档为【通过USB驱动libusb介绍和使用示例】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
老张师傅
20余年电工实际工作经验,目前在国企担任电工工程师
格式:doc
大小:59KB
软件:Word
页数:39
分类:管理学
上传时间:2023-03-13
浏览量:14