TShopping

 找回密碼
 註冊
搜索
查看: 4082|回復: 0
打印 上一主題 下一主題

[教學] Android/Linux USB Gadget:三层架构

[複製鏈接]
跳轉到指定樓層
1#
發表於 2014-5-15 01:13:07 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
 
Push to Facebook

相關詳細文章轉帖來自  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


  • static int __init init(void)  
  • {  
  •     struct android_dev *dev;  
  •     int err;  
  •   
  •     android_class = class_create(THIS_MODULE, "android_usb");  
  •     if (IS_ERR(android_class))  
  •         return PTR_ERR(android_class);  
  •   
  •     dev = kzalloc(sizeof(*dev), GFP_KERNEL);  
  •     if (!dev)  
  •         return -ENOMEM;  
  •   
  •     dev->functions = supported_functions;  
  •     INIT_LIST_HEAD(&dev->enabled_functions);  
  •     INIT_WORK(&dev->work, android_work);  
  •     mutex_init(&dev->mutex);  
  •   
  •     err = android_create_device(dev);  
  •     if (err) {  
  •         class_destroy(android_class);  
  •         kfree(dev);  
  •         return err;  
  •     }  
  •   
  •     _android_dev = dev;  
  •   
  •     /* Override composite driver functions */  
  •     composite_driver.setup = android_setup;  
  •     composite_driver.disconnect = android_disconnect;  
  •   
  •     return usb_composite_probe(&android_usb_driver, android_bind);  
  • }  

[cpp] view plaincopy


  • static int __init init(void)  
  • {  
  •     struct android_dev *dev;  
  •     int err;  
  •   
  •     android_class = class_create(THIS_MODULE, "android_usb");  
  •     if (IS_ERR(android_class))  
  •         return PTR_ERR(android_class);  
  •   
  •     dev = kzalloc(sizeof(*dev), GFP_KERNEL);  
  •     if (!dev)  
  •         return -ENOMEM;  
  •   
  •     dev->functions = supported_functions;  
  •     INIT_LIST_HEAD(&dev->enabled_functions);  
  •     INIT_WORK(&dev->work, android_work);  
  •     mutex_init(&dev->mutex);  
  •   
  •     err = android_create_device(dev);  
  •     if (err) {  
  •         class_destroy(android_class);  
  •         kfree(dev);  
  •         return err;  
  •     }  
  •   
  •     _android_dev = dev;  
  •   
  •     /* Override composite driver functions */  
  •     composite_driver.setup = android_setup;  
  •     composite_driver.disconnect = android_disconnect;  
  •   
  •     return usb_composite_probe(&android_usb_driver, android_bind);  
  • }  

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


  • static struct usb_gadget_driver composite_driver = {  
  •     .speed      = USB_SPEED_HIGH,  
  •   
  •     .unbind     = composite_unbind,  
  •   
  •     .setup      = composite_setup,  
  •     .disconnect = composite_disconnect,  
  •   
  •     .suspend    = composite_suspend,  
  •     .resume     = composite_resume,  
  •   
  •     .driver = {  
  •         .owner      = THIS_MODULE,  
  •     },  
  • };  

[cpp] view plaincopy


  • static struct usb_gadget_driver composite_driver = {  
  •     .speed      = USB_SPEED_HIGH,  
  •   
  •     .unbind     = composite_unbind,  
  •   
  •     .setup      = composite_setup,  
  •     .disconnect = composite_disconnect,  
  •   
  •     .suspend    = composite_suspend,  
  •     .resume     = composite_resume,  
  •   
  •     .driver = {  
  •         .owner      = THIS_MODULE,  
  •     },  
  • };  

可见它是一个全局的结构体,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


  • extern int usb_composite_probe(struct usb_composite_driver *driver,  
  •                    int (*bind)(struct usb_composite_dev *cdev))  
  • {  
  •     if (!driver || !driver->dev || !bind || composite)  
  •         return -EINVAL;  
  •   
  •     if (!driver->iProduct)  
  •         driver->iProduct = driver->name;  
  •     if (!driver->name)  
  •         driver->name = "composite";  
  •     composite_driver.function =  (char *) driver->name;  
  •     composite_driver.driver.name = driver->name;  
  •     composite = driver;  
  •     composite_gadget_bind = bind;  
  •   
  •     return usb_gadget_probe_driver(&composite_driver, composite_bind);  
  • }  

[cpp] view plaincopy


  • extern int usb_composite_probe(struct usb_composite_driver *driver,  
  •                    int (*bind)(struct usb_composite_dev *cdev))  
  • {  
  •     if (!driver || !driver->dev || !bind || composite)  
  •         return -EINVAL;  
  •   
  •     if (!driver->iProduct)  
  •         driver->iProduct = driver->name;  
  •     if (!driver->name)  
  •         driver->name = "composite";  
  •     composite_driver.function =  (char *) driver->name;  
  •     composite_driver.driver.name = driver->name;  
  •     composite = driver;  
  •     composite_gadget_bind = bind;  
  •   
  •     return usb_gadget_probe_driver(&composite_driver, composite_bind);  
  • }  

函数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描述符怎么传递,数据怎么收发等。。。




 

臉書網友討論
*滑块验证:
您需要登錄後才可以回帖 登錄 | 註冊 |

本版積分規則



Archiver|手機版|小黑屋|免責聲明|TShopping

GMT+8, 2024-4-24 16:02 , Processed in 0.055776 second(s), 22 queries .

本論壇言論純屬發表者個人意見,與 TShopping綜合論壇 立場無關 如有意見侵犯了您的權益 請寫信聯絡我們。

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表