TShopping

標題: Android/Linux USB Gadget:三层架构 [打印本頁]

作者: david0zan    時間: 2014-5-15 01:13
標題: Android/Linux USB Gadget:三层架构

相關詳細文章轉帖來自  http://blog.csdn.net/arnoldlu/article/details/9291883

1.前言Linux Gadget的一点研究后陆续续关注了很久Android USB Gadget,一直想写点什么记录一些认识,可是Linux USB实在是太复杂,让人有点无从下笔的感觉。它的复杂并不是说不可以被人理解,而且涉及的面很广。USB Host的驱动关注比较少,就对USB device驱动的认识来说,需从两大方面去对它进行认识和了解,一方面是USB协议本身,如果连USB端点、设备描述符、接口、复合设备等概念都不清楚的话,那是无法理解Linux USB device驱动的;另外方面就是USB Gadget架构。而本文就是基于对USB Gadget架构的一点认识而记录的。
2.Android USB Android设备的USB口实现了OTG的功能,也就是一般Android设备可以充当Host和Device角色,而我们使用得最多的就是它的Device角色。Android系统开发者更改传统了Linux USB Gadget实现,在传统Linux Gadget架构上实现了一个复合设备:adb和mtp。其中adb就不用多说,玩过Android都懂,mtp就是常见的U盘功能。Android USB Gadget设备驱动就是Linux的USB Gadget设备驱动。
3.USB Gadget的三层架构一般网上关于介绍USB Gadget的资料都是基于Linux2.6.32或在这之前的版本,作者在关注了Linux2.6.37和Linux3.0.4版本的内核,USB Gadget的一些API已经与Linux2.6.32的不同了。但是那些关键的数据结构还是一样滴。
Linux USB Gadget分三层架构:
层次关系从上到下
一层:USB Gadget功能层。BSP/Driver开发者通常是要实现这一层,从而实现一个具体的设备驱动,如Anddroid在此层实现了adb,mtp,mass_storage等。浏览参考关注此层代码时,会发现“composite”是此层的关键字,此层中关键的数据结构是:struct  usb_composite_driver。这一层的驱动文件一般为:driver/usb/gadget/android.c(android实现的)或driver/usb/gadget/serial.c(传统Linux实现的USB转串口)。

二层:USB设备层。这一层是Linux内核开发维护者实现的,与我们没太大关系,不用我们操心,我们只关心其的一些接口就行。浏览参考关注此层时,会发现“gadget”是此层的关键字,此层的关键数据结构是:usb_gadget_driver,usb_composite_dev。这层主要的一个驱动文件为:driver/usb/gadget/composite.c

三层:USB设备控制器驱动层。这一层主要是与CPU、CPU USB控制器有关,与硬件紧密相关,这一层也比较头痛,主要它和USB控制器牵扯在一起,涉及有寄存器、时钟、DMA等等。但是这一层往往是由芯片厂商去实现。我们一般仅需在板级文件中处理好所需要的USB接口即可。这层的关键字就是“UDC”,主要驱动文件命名含“udc”关键字,一般与CPU或芯片厂商有关,如driver/usb/gadget/xxx_udc.c。
4.USB Gadget的三层架构的关系可以用一句简单的话去概括三层的关系:USB Gadget功能层调用USB设备层的接口,USB设备层调用USB设备控制器驱动层的接口,然后USB设备控制器驱动层回调USB设备层,USB设备层回调USB Gadget功能层。
【强调本文只是想捋清楚层次的关系而已,对里面的一些函数,甚至USB gadget如果运作、整个驱动如何处理USB协议等等不做太多说明,后面会在其他文章中陆续补充。】
4.1从Android的gadget功能层去看三层架构的关系浏览driver/usb/gadget/android.c源码。
先看init函数,
[cpp] view plaincopy



[cpp] view plaincopy



composite_driver是定义在driver/usb/gadget/composite.c中,
[cpp] view plaincopy



[cpp] view plaincopy



可见它是一个全局的结构体,android.c中重新实现了它的setup和disconnect方法。然后调用函数usb_gadget_probe_driver(&android_usb_driver,android_bind);向USB设备层进行探测和注册。
【PS:2.6.32内核在init函数后面调用usb_composite_register(&android_usb_driver)进行注册,2.6.37内核以后统一改为usb_gadget_probe_driver。】
usb_gadget_probe_driver(&composite_driver, composite_bind)函数定制在driver/usb/gadget/composite.c

[cpp] view plaincopy



[cpp] view plaincopy



函数usb_gadget_probe_driver调用usb_gadget_probe_driver相关USB设备控制器驱动层进行注册。

【PS:2.6.32内核在init函数后面调用usb_gadget_register_driver(&composite_driver)进行注册,2.6.37内核以后统一改为usb_gadget_probe_driver(&composite_driver, composite_bind);】


usb_gadget_probe_driver()函数是每一个USB设备控制器驱动要实现的,这个函数与硬件紧密相关。

至此可以看到三层的关系:USB Gadget功能层调用USB设备层的接口,USB设备层调用USB设备控制器驱动层的接口。
4.2从传统Linux的gadget功能层去看三层架构的关系发现打字好累,分析传统Linux的gadget功能层代码(如:driver/usb/gadget/serial.c)发现其实和android一样,所以不写了。


后面会继续分析gadget层中对USB协议的实现,如怎么枚举设备,USB描述符怎么传递,数据怎么收发等。。。








歡迎光臨 TShopping (http://www.tshopping.com.tw/) Powered by Discuz! X3.2