《New-USB-Device-Class-API.pdf》由会员分享,可在线阅读,更多相关《New-USB-Device-Class-API.pdf(30页珍藏版)》请在三个皮匠报告上搜索。
1、New USB Device Class API IntroductionEOSS 2023Johann Fischerjohann.fischernordicsemi.nobPrague,Czech Republic/June 27,20231.Contents2/30Contents I1.Status of new USB device support2.API Requirements3.USBD Class Implementation4.Closing2.Status of new USB device support3/30Three UDC drivers and a driv
2、er skeletonNew class implementationsBluetooth HCI USB transport layerUSB CDC ACMUSB CDC ECMUSB Mass Storage ClassClasses that need to be portedAudio(WIP)HID(WIP)USB DFURNDIS-CDC NCMMass Storage Class3.API Requirements4/30Function Example(Device is in configured state)USB device controllerUSB device
3、supportCDC ACM implementationVirtual UART interfaceZephyr applicationUSB host controllerUSB host supportCDC ACM DriverVirtual UART interfaceRemote applicationSerial connectionUSB connectione.g./dev/ttyACM1compatible=zephyr,cdc-acm-uart;USBD Class APICDC ACM Implementationprovides serial functionalit
4、yto the hostControl PipeInterrupt INBulk IN/OUT3.API Requirements5/30Class implementation provides some functionality to the hostCommunication flow through Control,Interrupt,Bulk.pipesInterface descriptors describe implementation interface3.API Requirements6/30/*Fancyinterfacedescriptor*/staticstruc
5、tfoo_iface_desc structusb_if_descriptorif0;structusb_if_descriptorif1;structusb_ep_descriptorif1_in_ep;structusb_ep_descriptorif1_out_ep;struct usb_desc_header term_desc;_packed foo_desc=.if0=.bLength=sizeof(structusb_if_descriptor),.bDescriptorType=USB_DESC_INTERFACE,.bInterfaceNumber=0,.bAlternate
6、Setting=0,.bNumEndpoints=0,.bInterfaceClass=USB_BCC_VENDOR,.bInterfaceSubClass=0,.bInterfaceProtocol=0,.iInterface=0,.if1=.bLength=sizeof(structusb_if_descriptor),.bDescriptorType=USB_DESC_INTERFACE,.bInterfaceNumber=0,.bAlternateSetting=1,.bNumEndpoints=2,/*/.bInterfaceClass=USB_BCC_VENDOR,.bInterf
7、aceSubClass=0,.bInterfaceProtocol=0,.iInterface=0,.if1_in_ep=.bLength=sizeof(structusb_ep_descriptor),.bDescriptorType=USB_DESC_ENDPOINT,.bEndpointAddress=0 x81,.bmAttributes=USB_EP_TYPE_BULK,.wMaxPacketSize=0,.bInterval=0,.if1_out_ep=.bLength=sizeof(structusb_ep_descriptor),.bDescriptorType=USB_DES
8、C_ENDPOINT,.bEndpointAddress=0 x01,.bmAttributes=USB_EP_TYPE_BULK,.wMaxPacketSize=0,.bInterval=0,.nil_desc=.bLength=0,.bDescriptorType=0,;3.API Requirements7/30Implementation requires at least one interface descriptor”All”the information that the host class driver and the device stackneed to know ab
9、out class implementation is provided by the interfacedescriptorsInterface descriptor(s)is/are part of a configuration descriptorInterface(s)is/are part of a configurationOnly one configuration can be active at a time3.API Requirements8/30Fancy USB device configuration3.API Requirements9/30The applic
10、ation is responsible for configuration and initializationApplication must instantiate one or more USB device instancesApplication must instantiate at least one configuration per deviceinstanceApplication must add desired class instance to specific configurationApplication must initialise specific US
11、B device instanceApplication can enable specific USB device instance3.API Requirements10/30/*application.c*/#include/*Use helper macro todefine a deviceinstance*/USBD_DEVICE_DEFINE(foo_usbd,DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0),0 x2fe3,0 x f f f f);/*Use helper macro todefineatleast one configurat
12、ion*/USBD_CONFIGURATION_DEFINE(foo_config,USB_SCD_SELF_POWERED,200);/*Defineoptionalstringdescriptors*/USBD_DESC_LANG_DEFINE(foo_lang);USBD_DESC_MANUFACTURER_DEFINE(foo_mfr,”Nice company”);USBD_DESC_PRODUCT_DEFINE(foo_product,”Good product”);USBD_DESC_SERIAL_NUMBER_DEFINE(foo_sn,”0123456789ABCDEF”);
13、int main(void)usbd_add_descriptor(&foo_usbd,&foo_lang);usbd_add_descriptor(&foo_usbd,&foo_mfr);usbd_add_descriptor(&foo_usbd,&foo_product);usbd_add_descriptor(&foo_usbd,&foo_sn);usbd_add_configuration(&foo_usbd,&foo_config);usbd_register_class(&foo_usbd,”foo_0”,1);usbd_init(&foo_usbd);for(inti=0;i d
14、atadesc;constuint8_tif_num=descif0.bInterfaceNumber;const structdevice*dev=c_nddatapriv;struct cdc_ecm_eth_data*const data=devdata;/*Update relevant b*Interfacefields*/desciad.bFirstInterface=if_num;descif0_union.bControlInterface=if_num;descif0_union.bSubordinateInterface0=if_num+1;LOG_DBG(”CDC ECM
15、 classinitialized”);i f(usbd_add_descriptor(c_nddatauds_ctx,datamac_desc_nd)LOG_ERR(”Failedto add iMACAddress stringdescriptor”);else descif0_ecm.iMACAddress=datamac_desc_ndidx;return0;4.USBD Class Implementation18/30Class shutdown handler(shutdown)Handler is called as a result of usbd_shutdown()Imp
16、lementation can use it to remove own string descriptorsFinally,the class instance is removed from the configuration by thestack4.USBD Class Implementation19/30Class Enabled handler vs.Update handlerEnabled handler is called when associated configuration is selectedUpdate handler is called when inter
17、face alternate is changedBoth handlers can be used to trigger specifiec actionsCDC ECM uses update handler to enable network interface and startOUT transfersCDC ACM uses enable handler to enable UART RX IRQ4.USBD Class Implementation20/30/*Update handlerin CDC ECM*/staticvoid usbd_cdc_ecm_update(str
18、uctusbd_class_node*const c_nd,constuint8_tiface,constuint8_talternate)struct usbd_cdc_ecm_desc*desc=c_nddatadesc;constuint8_tdata_iface=descif1_1.bInterfaceNumber;const structdevice*dev=c_nddatapriv;struct cdc_ecm_eth_data*data=devdata;LOG_INF(”New configuration,interface%u alternate%u”,iface,altern
19、ate);i f(data_iface=iface&alternate=0)net_if_carrier_off(dataiface);i f(data_iface=iface&alternate=1)net_if_carrier_on(dataiface);i f(cdc_ecm_out_start(c_nd)LOG_ERR(”Failedtostart OUT transfer”);4.USBD Class Implementation21/30Control requestsSeparate handlers for host-to-device and device-to-host r
20、equests.Class implementation does not need to check transfer direction.Protocol errors are indicated by the errno variable.The return valueindicates a non-protocol error.Make supported vendor request visible for the device stack usingUSBD_VENDOR_REQ()macro(Recipient Device)The handler should not all
21、ocate or free the buffer,this is done by thelower level and the device framework.Class must not implement this handler if the control pipe is not used4.USBD Class Implementation22/30/*Example from MSC implementation*/#define BULK_ONLY_MASS_STORAGE_RESET0 xFF/*Make supported vendor requestvisiblefort
22、hedevicestack*/staticconst structusbd_cctx_vendor_req msc_bot_vregs=USBD_VENDOR_REQ(GET_MAX_LUN,BULK_ONLY_MASS_STORAGE_RESET);#define DEFINE_MSC_BOT_CLASS_DATA(x,_)staticstructmsc_bot_ctx msc_bot_ctx_#x;staticstructusbd_class_data msc_bot_class_#x=.desc=(struct usb_desc_header*)&msc_bot_desc_#x,.v_r
23、eqs=&msc_bot_vregs,.priv=&msc_bot_ctx_#x,;USBD_DEFINE_CLASS(msc_#x,&msc_bot_api,&msc_bot_class_#x);4.USBD Class Implementation23/30Transfer request completion handler(request)Class implementation submits transfer requests usingusbd_ep_enqueue()Handler is called as consequence of a completed Interrup
24、t/Bulk/ISOtransfer request,regardless of the resultClass must not implement this handler if only the control pipe is used,e.g.USB DFU class4.USBD Class Implementation24/30/*Example from CDC ECM notificationhandling*/structnet_buf*buf;uint8_t ep;intret;ep=cdc_ecm_get_int_in(c_nd);/*Allocatefrom thegl
25、obal UDC pool*/buf=usbd_ep_buf_alloc(c_nd,ep,sizeof(structcdc_ecm_notification);i f(buf=NULL)return ENOMEM;net_buf_add_mem(buf,¬ification,sizeof(structcdc_ecm_notification);ret=usbd_ep_enqueue(c_nd,buf);i f(ret)LOG_ERR(”Failedto enqueue net_buffor 0 x%02x”,ep);net_buf_unref(buf);returnret;4.USBD
26、Class Implementation25/30/*Example requesthandlerimplementation*/staticintusbd_cdc_ecm_request(structusbd_class_node*const c_nd,structnet_buf*buf,interr)/*.*/structudc_buf_info*bi=udc_get_buf_info(buf);i f(biep=cdc_ecm_get_bulk_out(c_nd)/*Startanothertransfer*/i f(biep=cdc_ecm_get_bulk_in(c_nd)k_sem
27、_give(&datasync_sem);return0;i f(biep=cdc_ecm_get_int_in(c_nd)k_sem_give(&datanotif_sem);return0;4.USBD Class Implementation26/30Synchronous transfersThere is no specific support for synchronous transfersThe implementation should use semaphore.The semaphore will betaken just after the transfer is en
28、queued and given in the transfercompletion handler.4.USBD Class Implementation27/30A few more notesAll handlers are executed in the thread context of the USB devicestack5.Closing28/30Future worksA few more transfer request handling improvements in device supportUSB notifications support for applications5.Closing29/30TroubleshootingPyUSBUSB device support shellVirtual controllers+USB device/host support shellQuestions?