USB Gadget zero应用实例程序

1. 编写程序1.1 编程思路涉及的程序如下图所示:
pc 端基于 libusb 编写应用程序,开发板端直接使用 linux 自带的 usb gadget 驱动 zero.c【/drivers/usb/gadget/legacy/zero.c】。
应用程序编程框架如下:
找到设备选择配置:zero.c 提供了两种配置,loopback、sourcesink得到端点:找到 interface 进而得到 endpoint读写数据:操作 endpoint1.2 zero 设备的描述符在 ubuntu 里执行如下命令,根据 vid:pid 获取设备信息:
$ lsusb -v -d 0525:a4a0可以列出 zero 设备的描述符:
bus 001 device 002: id 0525:a4a0 netchip technology, inc. linux-usb gadget zerocouldn't open device, some information will be missingdevice descriptor: blength 18 bdescriptortype 1 bcdusb 2.00 bdeviceclass 255 vendor specific class bdevicesubclass 0 bdeviceprotocol 0 bmaxpacketsize0 64 idvendor 0x0525 netchip technology, inc. idproduct 0xa4a0 linux-usb gadget zero bcddevice 4.09 imanufacturer 1 iproduct 2 iserial 3 bnumconfigurations 2 configuration descriptor: blength 9 bdescriptortype 2 wtotallength 69 bnuminterfaces 1 bconfigurationvalue 3 iconfiguration 4 bmattributes 0xc0 self powered maxpower 2ma interface descriptor: blength 9 bdescriptortype 4 binterfacenumber 0 balternatesetting 0 bnumendpoints 2 binterfaceclass 255 vendor specific class binterfacesubclass 0 binterfaceprotocol 0 iinterface 0 endpoint descriptor: blength 7 bdescriptortype 5 bendpointaddress 0x81 ep 1 in bmattributes 2 transfer type bulk synch type none usage type data wmaxpacketsize 0x0200 1x 512 bytes binterval 0 endpoint descriptor: blength 7 bdescriptortype 5 bendpointaddress 0x01 ep 1 out bmattributes 2 transfer type bulk synch type none usage type data wmaxpacketsize 0x0200 1x 512 bytes binterval 0 interface descriptor: blength 9 bdescriptortype 4 binterfacenumber 0 balternatesetting 1 bnumendpoints 4 binterfaceclass 255 vendor specific class binterfacesubclass 0 binterfaceprotocol 0 iinterface 0 endpoint descriptor: blength 7 bdescriptortype 5 bendpointaddress 0x81 ep 1 in bmattributes 2 transfer type bulk synch type none usage type data wmaxpacketsize 0x0200 1x 512 bytes binterval 0 endpoint descriptor: blength 7 bdescriptortype 5 bendpointaddress 0x01 ep 1 out bmattributes 2 transfer type bulk synch type none usage type data wmaxpacketsize 0x0200 1x 512 bytes binterval 0 endpoint descriptor: blength 7 bdescriptortype 5 bendpointaddress 0x82 ep 2 in bmattributes 1 transfer type isochronous synch type none usage type data wmaxpacketsize 0x0400 1x 1024 bytes binterval 4 endpoint descriptor: blength 7 bdescriptortype 5 bendpointaddress 0x02 ep 2 out bmattributes 1 transfer type isochronous synch type none usage type data wmaxpacketsize 0x0400 1x 1024 bytes binterval 4 configuration descriptor: blength 9 bdescriptortype 2 wtotallength 32 bnuminterfaces 1 bconfigurationvalue 2 iconfiguration 5 bmattributes 0xc0 self powered maxpower 2ma interface descriptor: blength 9 bdescriptortype 4 binterfacenumber 0 balternatesetting 0 bnumendpoints 2 binterfaceclass 255 vendor specific class binterfacesubclass 0 binterfaceprotocol 0 iinterface 6 endpoint descriptor: blength 7 bdescriptortype 5 bendpointaddress 0x81 ep 1 in bmattributes 2 transfer type bulk synch type none usage type data wmaxpacketsize 0x0200 1x 512 bytes binterval 0 endpoint descriptor: blength 7 bdescriptortype 5 bendpointaddress 0x01 ep 1 out bmattributes 2 transfer type bulk synch type none usage type data wmaxpacketsize 0x0200 1x 512 bytes binterval 0它有 2 个配置:
第 1 个配置(bconfigurationvalue = 2)对应 loopback 功能:里面有 1 个接口,接口有 1 个 setting,下面有 2 个 endpoint第 2 个配置(bconfigurationvalue = 3)对应 sourcesink 功能:里面有 1 个接口,接口有 2 个 setting 第 1 个 setting 下面有 2 个 endpoint:都是 bulk 端点第 2 个 setting 下面有 4 个 endpoint:2 个是 bulk 端点,另外 2 个是 isochronous 端点1.3 编程参考 libusb 示例:libusbexamplesxusb.c
#include #include #include #include #include #include #define driver_vendor_num 0x0525 /* netchip */#define driver_product_num 0xa4a0 /* linux-usb gadget zero */int get_bulk_endpoint(libusb_device *dev, int *in_ep, int *out_ep, int *in_ep_maxlen){ struct libusb_config_descriptor *config; const struct libusb_endpoint_descriptor *ep; int r; int iface_idx; int found = 0; r = libusb_get_active_config_descriptor(dev, &config); if (r interface[0]; int altsetting_idx = 0; const struct libusb_interface_descriptor *altsetting = &iface- >altsetting[altsetting_idx]; int ep_idx; for (ep_idx = 0; ep_idx bnumendpoints; ep_idx++) { const struct libusb_endpoint_descriptor *ep = &altsetting- >endpoint[ep_idx]; if ((ep- >bmattributes & libusb_transfer_type_mask) == libusb_transfer_type_bulk) { if (ep- >bendpointaddress & libusb_endpoint_in) { *in_ep = ep- >bendpointaddress; *in_ep_maxlen = ep- >wmaxpacketsize; found++; } else { *out_ep = ep- >bendpointaddress; found++; } } } } libusb_free_config_descriptor(config); return (found == 2) ? 0 : -1;}void printusage(char *name){ printf(usage:n); printf(%s -l : list bconfigurationvalue of all configsn, name); printf(%s -s , name); printf(%s -wstr : write stringn, name); printf(%s -rstr : read stringn, name); printf(%s -w : write bytesn, name); printf(%s -r : read 32 bytesn, name);}int main(int argc, char **argv){ int err = 0; libusb_device *dev, **devs; int num_devices; int endpoint; int interface_num = 0; int found = 0; int transferred; int count = 0; unsigned char buffer[1024]; struct libusb_config_descriptor *config_desc; struct libusb_device_handle *dev_handle = null; int i; int in_ep, out_ep; int in_ep_maxlen; if (argc == 1) { printusage(argv[0]); return 0; } /* libusb_init */ err = libusb_init(null); if (err < 0) { fprintf(stderr, failed to initialise libusb %d - %sn, err, libusb_strerror(err)); exit(1); } /* open device */ dev_handle = libusb_open_device_with_vid_pid(null, driver_vendor_num, driver_product_num); if (!dev_handle) { printf(can not open zero devicen); return -1; } dev = libusb_get_device(dev_handle); /* 想选择某一个配置, 先知道它的bconfigurationvalue */ if (!strcmp(argv[1], -l)) { for (i = 0; i bconfigurationvalue); libusb_free_config_descriptor(config_desc); } return 0; } /* 想选择某一个配置 */ if (!strcmp(argv[1], -s) && (argc == 3)) { i = strtoul(argv[2], null, 0); libusb_set_auto_detach_kernel_driver(dev_handle, 0); libusb_detach_kernel_driver(dev_handle, 0); //libusb_release_interface(dev_handle, 0); err = libusb_set_configuration(dev_handle, i); if (err) { fprintf(stderr, could not set configuration as %d, err = %dn, i, err); return -1; } return 0; } err = libusb_get_configuration(dev_handle, &i); fprintf(stdout, current config: %dn, i); /* 想读写数据需要得到 endpoint */ err = get_bulk_endpoint(dev, &in_ep, &out_ep, &in_ep_maxlen); if (err) { fprintf(stderr, could not get bulk endpointsn); goto exit; } fprintf(stdout, in_ep = 0x%x, out_ep = 0x%xn, in_ep, out_ep); /* claim interface */ libusb_set_auto_detach_kernel_driver(dev_handle, 1); err = libusb_claim_interface(dev_handle, interface_num); if (err) { fprintf(stderr, failed to libusb_claim_interfacen); goto exit; } /* write string */ if (!strcmp(argv[1], -wstr) && (argc == 3)) { memset(buffer, 0, 32); strncpy(buffer, argv[2], 32); err = libusb_bulk_transfer(dev_handle, out_ep, buffer, 32, &transferred, 1000); if (err) { fprintf(stderr, libusb_bulk_transfer err = %dn, err); goto exit; } if (transferred != 32) { fprintf(stderr, transferred != 32n); } goto exit; } /* read string */ if (!strcmp(argv[1], -rstr)) { memset(buffer, 0, 32); err = libusb_bulk_transfer(dev_handle, in_ep, buffer, 32, &transferred, 1000); if (err) { fprintf(stderr, libusb_bulk_transfer err = %dn, err); goto exit; } if (transferred != 32) { fprintf(stderr, transferred != 32n); } printf(read string: %sn, buffer); goto exit; } /* write datas */ if (!strcmp(argv[1], -w) && (argc >= 3)) { memset(buffer, 0, 32); /* argv[2],... */ for (i = 2; i < argc; i++) buffer[i-2] = strtoul(argv[i], null, 0); err = libusb_bulk_transfer(dev_handle, out_ep, buffer, argc - 2, &transferred, 1000); if (err) { fprintf(stderr, libusb_bulk_transfer err = %dn, err); goto exit; } if (transferred != argc - 2) { fprintf(stderr, transferred != %dn, argc - 2); } goto exit; } /* read datas */ if (!strcmp(argv[1], -r)) /* 读source/sink这个配置里的端点时, 它一次性返回512字节的数据 */ { memset(buffer, 0, 1024); err = libusb_bulk_transfer(dev_handle, in_ep, buffer, in_ep_maxlen, &transferred, 1000); if (err) { fprintf(stderr, libusb_bulk_transfer err = %dn, err); goto exit; } if (transferred != in_ep_maxlen) { fprintf(stderr, transferred != in_ep_maxlenn); } printf(read datas: n); for (i = 0; i < transferred; i++) { printf(%02x , buffer[i]); if ((i+1) % 16 == 0) printf(n); } printf(n); goto exit; }exit: /* libusb_close */ libusb_release_interface(dev_handle, interface_num); libusb_close(dev_handle); libusb_exit(null); return err;}

石墨烯超级电容器可提供高性能的能量存储
硼砂检测仪的用途及其功能特点的介绍
全球DRAM厂商排名 新美光直追三星
ST 意法半导体推出适合各种汽车系统的惯性模块及ASIL B 认证软件库
深入了解WinDaq导数算法
USB Gadget zero应用实例程序
爱特梅尔针对LIN汽车网络应用发布全新收发器系列ATA666
重磅!华虹无锡项目(一期)12英寸生产线顺利建成投片
华虹无锡项目将迎来首批光刻机搬入 预计2019年第四季度开始300mm晶圆的量产
熔断器参数
中国风电年均新增装机容量到2060年至少达30亿千瓦
亚马逊云科技Amazon Lightsail具备VPS的简易性和AWS的强大功能
如何看懂振荡和调制电路
扫地机器人那个牌子好?老司机支招啦哪种扫地机器人好用?
KPS与京东方绵阳签订OLED显示设备供应合同
无人机使用注意事项及维护保养
北斗三号全球卫星导航系统助力,GECAM 卫星准实时下传伽马暴观测警报
在线扬尘监测仪为城市空气污染保驾护航
罗姆为电动汽车充电桩打造高效解决方案
jquery绑定事件的方法