当前位置:   article > 正文

linux下使用libusb获取系统usb设备具体信息_libusb 对应

libusb 对应



一、libusb简介

libusb库提供的api接口供应用层调用,可以对系统中的usb设备操作,如reset一个usb设备,或者获取其具体信息,如configuration、interface及settings等。libusb遵循posix协议,可以跨平台使用,Linux下默认预装libusb1.0版本,开发者可以直接使用,只是在编译时需要链接lib库。

二、libusb的api介绍

1. libusb_init和libusb_exit及struct libusb_context

代码中调用libusb接口函数需要先建立上下文环境,其中结构体struct libusb_context代表一段libusb的会话,官方文档中有对这个结构的说明[libusb]。libusb_init()表示开启会话,libusb_exit()表示结束会话。通俗的理解就是struct libusb_context* ctx中的ctx代表一把钥匙,libusb_init(&ctx)表示开启,libusb_exit(null)表示锁上。

2. libusb中几个重要的数据结构体和接口函数

libusb_device **list;这个结构体用来列举当前系统中的usb设备。

libusb_device_handle *  handle;这个结构体是用来处理具体list中的usb设备的。

上面两个结构体的使用方式:

ssize_t num_devs = libusb_get_device_list(ctx, &list);根据ctx获取系统中的usb设备,返回设备个数,list指向链表头。

libusb_device *dev = list[i];
        libusb_open(dev,&handle);

获取第i个设备并使用handle进行处理。

struct libusb_device_descriptor desc; usb设备描述结构体。

struct libusb_config_descriptor conf;  usb设备配置描述结构体。

libusb_get_device_descriptor(dev, &desc);获取usb设备描述。

libusb_get_config_descriptor(dev, j, &conf); 获取usb设备配置描述。

uint8_t bnum = libusb_get_bus_number(dev); 获取usb设备总线号。
uint8_t dnum = libusb_get_device_address(dev); 获取usb设备端口号。比方3-1.1。

除上述一些接口外还有其它一些接口函数,具体用法可以到官网上查询。

三、 使用libusb获取当前usb设备的具体信息。

  1. #include<stdio.h>
  2. #include<libusb.h>
  3. //#include <libusb-1.0/libusb.h>
  4. #include<sys/types.h>
  5. #include<errno.h>
  6. #include<sys/stat.h>
  7. #include<fcntl.h>
  8. #include<unistd.h>
  9. #include<stdlib.h>
  10. int get_configuration(libusb_device* dev, struct libusb_config_descriptor *config)
  11. {
  12. int ret = 0;
  13. ret = libusb_get_config_descriptor(dev, 0, &config);
  14. return ret;
  15. }
  16. static void dump_altsetting(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface)
  17. {
  18. // char cls[128], subcls[128], proto[128];
  19. // char *ifstr;
  20. // get_class_string(cls, sizeof(cls), interface->bInterfaceClass);
  21. // get_subclass_string(subcls, sizeof(subcls), interface->bInterfaceClass, interface->bInterfaceSubClass);
  22. // get_protocol_string(proto, sizeof(proto), interface->bInterfaceClass, interface->bInterfaceSubClass, interface->bInterfaceProtocol);
  23. // ifstr = get_dev_string(dev, interface->iInterface);
  24. printf(" Interface Descriptor:\n"
  25. " bLength %5u\n"
  26. " bDescriptorType %5u\n"
  27. " bInterfaceNumber %5u\n"
  28. " bAlternateSetting %5u\n"
  29. " bNumEndpoints %5u\n"
  30. " bInterfaceClass %5u\n"
  31. " bInterfaceSubClass %5u\n"
  32. " bInterfaceProtocol %5u\n",
  33. interface->bLength, interface->bDescriptorType, interface->bInterfaceNumber,
  34. interface->bAlternateSetting, interface->bNumEndpoints, interface->bInterfaceClass,
  35. interface->bInterfaceSubClass,interface->bInterfaceProtocol);
  36. // free(ifstr);
  37. }
  38. static void dump_interface(libusb_device_handle *dev, const struct libusb_interface *interface)
  39. {
  40. int i;
  41. for (i = 0; i < interface->num_altsetting; i++)
  42. dump_altsetting(dev, &interface->altsetting[i]);
  43. }
  44. static int list_devices(libusb_context *ctx)
  45. {
  46. libusb_device **list;
  47. struct libusb_device_descriptor desc;
  48. struct libusb_config_descriptor* conf;
  49. libusb_device_handle * handle = NULL;
  50. int config= 0;
  51. int ret;
  52. int status;
  53. ssize_t num_devs, i, j, k;
  54. status = 1; /* 1 device not found, 0 device found */
  55. num_devs = libusb_get_device_list(ctx, &list);
  56. if (num_devs < 0)
  57. goto error;
  58. for (i = 0; i < num_devs; ++i) {
  59. libusb_device *dev = list[i];
  60. libusb_open(dev,&handle);
  61. libusb_get_configuration(handle,&config);
  62. uint8_t bnum = libusb_get_bus_number(dev);
  63. uint8_t dnum = libusb_get_device_address(dev);
  64. libusb_get_device_descriptor(dev, &desc);
  65. status = 0;
  66. printf("device:%04x:%04x\n",desc.idVendor,desc.idProduct);
  67. printf("bDeviceSubClass = %5u\n",desc.bDeviceSubClass);
  68. printf("bDeviceClass = %5u\n",desc.bDeviceClass);
  69. printf("bDeviceProtocol = %5u\n",desc.bDeviceProtocol);
  70. for( j = 0; j < desc.bNumConfigurations; ++j) {
  71. ret = libusb_get_config_descriptor(dev, j, &conf);
  72. if (ret) {
  73. fprintf(stderr, "Couldn't get configuration "
  74. "descriptor %lu, some information will "
  75. "be missing\n", j);
  76. } else {
  77. printf("bNumberInterfaces = %5u\n",conf->bNumInterfaces);
  78. printf("bConfigurationValue = %5u\n",conf->bConfigurationValue);
  79. for (k = 0 ; k < conf->bNumInterfaces ; k++)
  80. dump_interface(handle, &conf->interface[k]);
  81. libusb_free_config_descriptor(conf);
  82. }
  83. }
  84. }
  85. libusb_free_device_list(list, 0);
  86. error:
  87. return status;
  88. }
  89. int main(int argc, char* args[])
  90. {
  91. int err = 0;
  92. libusb_context *ctx;
  93. err = libusb_init(&ctx);
  94. if (err) {
  95. fprintf(stderr, "unable to initialize libusb: %i\n", err);
  96. return EXIT_FAILURE;
  97. }
  98. list_devices(ctx);
  99. return 0;
  100. }

Makefile

header_src=/usr/include/libusb-1.0

lsusb : lsusb.c
	gcc lsusb.c -o lsusb -lusb-1.0 -I$(header_src)

clean:
	rm ./lsusb 

四、使用libusb重置usb设备

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <libusb-1.0/libusb.h>
  4. struct libusb_device_handle *devh;
  5. struct libusb_device *dev;
  6. struct libusb_device **devs;
  7. struct libusb_context *ctx;
  8. void resetUSB() {
  9. int success;
  10. int bpoint = 0;
  11. do {
  12. success = libusb_reset_device(devh);
  13. ++bpoint;
  14. if (bpoint > 3) {
  15. success = 1;
  16. }
  17. } while (success < 0);
  18. if (success) {
  19. printf("\nreset usb device failed:%d\n", success);
  20. } else {
  21. printf("\nreset usb device ok\n");
  22. }
  23. }
  24. struct libusb_device* search_device(int _busNum, int _devNum) {
  25. libusb_device *l_dev;
  26. int i = 0;
  27. int l_busNum, l_devNum;
  28. while ((l_dev = devs[i++]) != NULL) {
  29. printf("check against %d device\n", i);
  30. l_busNum =(int) libusb_get_bus_number(l_dev);
  31. l_devNum =(int) libusb_get_device_address(l_dev);
  32. printf("bus number: %d; device number: %d\n", l_busNum, l_devNum);
  33. if ((l_busNum == _busNum) && (l_devNum == _devNum)) {
  34. printf("found device\n");
  35. return l_dev;
  36. }
  37. }
  38. return NULL;
  39. }
  40. int main(int argc, char **argv) {
  41. //parse the input parameters to get the bus number and device number
  42. int l_busNum, l_devNum;
  43. int l_ret;
  44. if (argc < 3) {
  45. printf("not enough arguments!\n");
  46. printf("usage: ./usbreset <bus number> <dev number>\n");
  47. return 0;
  48. }
  49. printf("bus number: %s\n", argv[1]);
  50. printf("dev number: %s\n", argv[2]);
  51. l_busNum = atoi(argv[1]);
  52. l_devNum = atoi(argv[2]);
  53. printf("bus number: %d; dev number: %d\n", l_busNum, l_devNum);
  54. l_ret = libusb_init(&ctx);
  55. if (l_ret ) {
  56. fprintf(stderr, "unable to initialize libusb: %i\n", err);
  57. return EXIT_FAILURE;
  58. l_ret = libusb_get_device_list(NULL, &devs);
  59. if (l_ret < 0) {
  60. return (int) l_ret;
  61. }
  62. dev = search_device(l_busNum, l_devNum);
  63. if (dev == NULL) {
  64. printf("device not found\n");
  65. return 0;
  66. }
  67. l_ret = libusb_open(dev, &devh);
  68. if (l_ret == 0) {
  69. printf("got the usb handle successfully.\n");
  70. } else {
  71. printf("error getting usb handle.\n");
  72. }
  73. //reset the usb device
  74. resetUSB();
  75. //free the device list
  76. libusb_free_device_list(devs, 1);
  77. libusb_exit(NULL);
  78. return 0;
  79. }

五、总结。

libusb是一个应用层处理usb设备的很好的借口代码,相对于udev来说,libusb更加接近usb驱动,能够从系统级别操作或取得usb的信息。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/711524
推荐阅读
相关标签
  

闽ICP备14008679号