Linux USB Gadget--各环节的整合
Linux USB Gadget软件结构一文中分析Linux USB Gadget软件分为三层。这三层其中两层是与硬件无关的,分别是Gadget功能驱动层,USB设备层。一层是与硬件相关的是UDC层。每一层都提供一种关键的数据结构与函数与其他层交互。
Gadget功能驱动层: 最主要的结构是struct usb_composite_driver,这个结构在这层定义,并且实现结构中的各个函数。
USB设备层: 最主要的数据结构是struct usb_composite_dev与usb_gadget_driver。前一个代表一个USB设备,而后一个是Gadget驱动,与UDC层交互。
UDC层: 最主要的数据结构是struct usb_gadget,通常包含在其他结构体中。这个结构体代表了一个USB设备控制器的所有关于USB通信的信息。
UDC层提供usb_gadget_unregister_driver(struct usb_gadget_driver *driver)函数,这个函数由USB设备层调用,USB设备层将自己定义的struct usb_gadget_driver结构变量传递给他。USB设备层提供usb_composite_register(struct usb_composite_driver *driver)函数,这个函数由Gadget功能驱动层调用,Gadget功能驱动层将自己定义的struct usb_composite_driver
结构变量传递给他。下面详细分析一下这三层是如何结合在一起的。我们将以zero Gadget功能驱动为例子,s3c2410_udc作为底层UDC。
首先先看一下zero Gadget功能驱动,他是作为一个模块注册到内核中的,首先分析一下他的模块初始化函数:
很简单,只是调用了usb_composite_register,传递给他的参数是zero_driver。这个结构体如下定义:
以上函数都是在zero.c中实现的,比较重要的函数是zero_bind。目前暂时不列出这个函数,等用到的时候再说。下面看一下usb_composite_register函数,他是由USB设备层提供的,定义在composite.c中:
这个函数主要的目的是初始化两个结构体变量,一个是composite_driver,这个是USB设备层定义的一个全局struct usb_gadget_driver变量,如下:
这些函数都要在USB设备层实现。usb_composite_register将composite_driver的function初始化为"zero"。driver是 struct device_driver结构体。linux设备模型中使用。名字初始化为“zero”。另外一个变量是composite,它是一个USB设备层定义的struct
usb_composite_driver的指针,这样composite就指向了zero_driver。因此zero Gadget功能驱动层就和USB设备层联系到了一起。最后usb_composite_register函数调用usb_gadget_register_driver,开始向UDC层联系。这个函数定义在UDC层,系统每个UDC都要实现这样一个函数。我们看一下s3c2410_udc这个函数的实现: