您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > USB设备驱动开发-USBGadgetDriver
一、LinuxUSBGadgetDriver功能为了与主机端驱动设备的USBDeviceDriver概念进行区别,将在外围器件中运行的驱动程序称为USBGadgetDriver。其中,Host端驱动设备的驱动程序是master或者clientdriver,设备端gadgetdriver是slave或者functiondriver。GadgetDriver和USBHost端驱动程序类似,都是使用请求队列来对I/O包进行缓冲,这些请求可以被提交和取消。它们的结构、消息和常量的定义也和USB技术规范第九章的内容一致。同时也是通过bind和unbind将driver与device建立关系。二、LinuxUSBGadgetDriver核心数据结构1.USB_Gadget对象structusb_gadget{/*readonlytogadgetdriver*/conststructusb_gadget_ops*ops;//Gadget设备操作函数集structusb_ep*ep0;//控制端点,只对setup包响应structlist_headep_list;//将设备的所有端点连成链表,ep0不在其中enumusb_device_speedspeed;//高速、全速和低速unsignedis_dualspeed:1;//是否同时支持高速和全速unsignedis_otg:1;//是否支持OTG(On-To-Go)unsignedis_a_peripheral:1;unsignedb_hnp_enable:1;unsigneda_hnp_support:1;unsigneda_alt_hnp_support:1;constchar*name;//器件名称structdevicedev;//内核设备模型使用};2.Gadget器件操作函数集操作UDC硬件的API,但操作端点的函数由端点操作函数集完成structusb_gadget_ops{int(*get_frame)(structusb_gadget*);int(*wakeup)(structusb_gadget*);int(*set_selfpowered)(structusb_gadget*,intis_selfpowered);int(*vbus_session)(structusb_gadget*,intis_active);int(*vbus_draw)(structusb_gadget*,unsignedmA);int(*pullup)(structusb_gadget*,intis_on);int(*ioctl)(structusb_gadget*,unsignedcode,unsignedlongparam);};3.USBGadgetdriver对象structusb_gadget_driver{char*function;//驱动名称enumusb_device_speedspeed;//USB设备速度类型int(*bind)(structusb_gadget*);//将驱动和设备绑定,一般在驱动注册时调用void(*unbind)(structusb_gadget*);//卸载驱动时调用,rmmod时调用int(*setup)(structusb_gadget*,conststructusb_ctrlrequest*);//处理ep0的控制请求,在中断中调用,不能睡眠void(*disconnect)(structusb_gadget*);//可能在中断中调用不能睡眠void(*suspend)(structusb_gadget*);//电源管理模式相关,设备挂起void(*resume)(structusb_gadget*);//电源管理模式相关,设备恢复/*FIXMEsupportsafermmod*/structdevice_driverdriver;//内核设备管理使用};4.描述一个I/O请求structusb_request{void*buf;//数据缓存区unsignedlength;//数据长度dma_addr_tdma;//与buf关联的DMA地址,DMA传输时使用unsignedno_interrupt:1;//当为true时,表示没有完成函数,则通过中断通知传输完成,这个由DMA控制器直接控制unsignedzero:1;//当输出的最后一个数据包不够长度是是否填充0unsignedshort_not_ok:1;//当接收的数据不够指定长度时,是否报错void(*complete)(structusb_ep*ep,structusb_request*req);//请求完成函数void*context;//被completion回调函数使用structlist_headlist;//被GadgetDriver使用,插入队列intstatus;//返回完成结果,0表示成功unsignedactual;//实际传输的数据长度};5.端点structusb_ep{void*driver_data;//端点私有数据constchar*name;//端点名称conststructusb_ep_ops*ops;//端点操作函数集structlist_headep_list;//Gadget设备建立所有端点的链表unsignedmaxpacket:16;//这个端点使用的最大包长度};6.端点操作函数集structusb_ep_ops{int(*enable)(structusb_ep*ep,conststructusb_endpoint_descriptor*desc);int(*disable)(structusb_ep*ep);structusb_request*(*alloc_request)(structusb_ep*ep,gfp_tgfp_flags);void(*free_request)(structusb_ep*ep,structusb_request*req);int(*queue)(structusb_ep*ep,structusb_request*req,gfp_tgfp_flags);int(*dequeue)(structusb_ep*ep,structusb_request*req);int(*set_halt)(structusb_ep*ep,intvalue);int(*set_wedge)(structusb_ep*ep);int(*fifo_status)(structusb_ep*ep);void(*fifo_flush)(structusb_ep*ep);};7.字符串结构structusb_gadget_strings{u16language;/*0x0409foren-us*/structusb_string*strings;};structusb_string{u8id;//索引constchar*s;};8.UDC驱动程序需要实现的上层调用接口intusb_gadget_register_driver(structusb_gadget_driver*driver);intusb_gadget_unregister_driver(structusb_gadget_driver*driver);三、UDC驱动程序1.UDC层主要数据结构,以S3C2410为例,在driver/usb/gadget/s3c2410_udc.c和s3c2410_udc.h文件中。下面的结构基本上每个UDC驱动程序都会实现,但具体实现的细节又不太相同。但万变不离其宗,宗就是上面介绍的基本gadget驱动数据结构,基本上UDC驱动程序自己实现的数据结构都是都这些基本数据结构的二次封装。a.设备结构structs3c2410_udc{spinlock_tlock;structs3c2410_epep[S3C2410_ENDPOINTS];intaddress;structusb_gadgetgadget;structusb_gadget_driver*driver;structs3c2410_requestfifo_req;u8fifo_buf[EP_FIFO_SIZE];u16devstatus;u32port_status;intep0state;unsignedgot_irq:1;unsignedreq_std:1;unsignedreq_config:1;unsignedreq_pending:1;u8vbus;structdentry*regs_info;};程序中对这个结构的初始化:staticstructs3c2410_udcmemory={.gadget={.ops=&s3c2410_ops,.ep0=&memory.ep[0].ep,.name=gadget_name,.dev={.init_name=gadget,},},/*controlendpoint*/.ep[0]={//structs3c2410_ep.num=0,.ep={//structusb_ep.name=ep0name,.ops=&s3c2410_ep_ops,.maxpacket=EP0_FIFO_SIZE,},.dev=&memory,},/*firstgroupofendpoints*/.ep[1]={.num=1,.ep={.name=ep1-bulk,.ops=&s3c2410_ep_ops,.maxpacket=EP_FIFO_SIZE,},.dev=&memory,.fifo_size=EP_FIFO_SIZE,.bEndpointAddress=1,.bmAttributes=USB_ENDPOINT_XFER_BULK,},.ep[2]={.num=2,.ep={.name=ep2-bulk,.ops=&s3c2410_ep_ops,.maxpacket=EP_FIFO_SIZE,},.dev=&memory,.fifo_size=EP_FIFO_SIZE,.bEndpointAddress=2,.bmAttributes=USB_ENDPOINT_XFER_BULK,},.ep[3]={.num=3,.ep={.name=ep3-bulk,.ops=&s3c2410_ep_ops,.maxpacket=EP_FIFO_SIZE,},.dev=&memory,.fifo_size=EP_FIFO_SIZE,.bEndpointAddress=3,.bmAttributes=USB_ENDPOINT_XFER_BULK,},.ep[4]={.num=4,.ep={.name=ep4-bulk,.ops=&s3c2410_ep_ops,.maxpacket=EP_FIFO_SIZE,},.dev=&memory,.fifo_size=EP_FIFO_SIZE,.bEndpointAddress=4,.bmAttributes=USB_ENDPOINT_XFER_BULK,}};不同的UDC,自定义的数据结构不同。但一般都有这样一个数据结构来表示UDC设备,对usb_gadget设备对象进行封装,并包含设备的所有端点。b.端点结构structs3c2410_ep{structlist_headqueue;unsignedlonglast_io;/*jiffiestimestamp*/structusb_gadget*gadget;structs3c2410_udc*dev;conststructusb_endpoint_descriptor*desc;structusb_epep;//封装的structusb_ep结构u8num;unsignedshortfifo_size;u8bEndpointAddress;u8bmAttributes;unsignedhalted:1;unsignedalready_seen:1;un
本文标题:USB设备驱动开发-USBGadgetDriver
链接地址:https://www.777doc.com/doc-2865343 .html