linux usb gadget代码分析--- gadget功能驱动层
p { margin-bottom: 0.25cm; direction: ltr; color: rgb(0, 0, 0); line-height: 120%; text-align: justify; }p.western { font-family: "Times New Roman",serif; font-size: 10pt; }p.cjk { font-family: "SimSu
LinuxUSB Gadget软件分为三层:
Gadget功能驱动层: 最主要的结构是structusb_composite_driver,这个结构在这层定义,并且实现结构中的各个函数。
USB设备层: 最主要的数据结构是structusb_composite_dev与usb_gadget_driver。前一个代表一个USB设备,而后一个是Gadget驱动,与UDC层交互。
UDC层: 最主要的数据结构是structusb_gadget,通常包含在其他结构体中。这个结构体代表了一个USB设备控制器的所有关于USB通信的信息。
在android平台gadget的代码是android.c,它实现了ffs,adb,acm,mtp,ptp,rndis,mass_storage_function,accessory_function,audio_source_function,在代码中这些功能的定义如下:
static struct android_usb_function *supported_functions[] = {
#if (USE_FFS == 1)
&ffs_function,
#endif
&adb_function,
&acm_function,
&mtp_function,
&ptp_function,
&rndis_function,
&mass_storage_function,
&accessory_function,
&audio_source_function,
NULL
};
每个功能都是一个struct android_usb_funtion。
android.c的代码位于gadget功能驱动层,composite.c位于usb设备层,udc-core.c位于udc层。
在gadget功能驱动层,它的相关数据结构定义是:
struct android_dev {
struct android_usb_function **functions;
struct list_head enabled_functions;
struct usb_composite_dev *cdev;
struct device *dev;
bool enabled;
int disable_depth;
struct mutex mutex;
bool connected;
bool sw_connected;
struct work_struct work;
char ffs_aliases[256];
};
(1)struct android_usb_function即是支持的每个功能的数据结构;
(2)enabled_functions是当前使用的功能,应用层可以去设置它;
(3)struct usb_composite_dev是USB设置层的结构,这里与设备层关联;
(4)定义struct work_struct内核线程来监测USB的状态,相关代码是android_work:
static void android_work(struct work_struct *data)
{
struct android_dev *dev = container_of(data, struct android_dev, work);
struct usb_composite_dev *cdev = dev->cdev;
char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
char *connected[2] = { "USB_STATE=CONNECTED", NULL };
char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
char **uevent_envp = NULL;
unsigned long flags;
/* psw0523 add for dwc otg */
#ifdef CONFIG_USB_DWCOTG
if (!cdev) return;
#endif
spin_lock_irqsave(&cdev->lock, flags);
if (cdev->config)
uevent_envp = configured;
else if (dev->connected != dev->sw_connected)
uevent_envp = dev->connected ? connected : disconnected;
dev->sw_connected = dev->connected;
spin_unlock_irqrestore(&cdev->lock, flags);
if (uevent_envp) {
kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp);
pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]);
} else {
pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
dev->connected, dev->sw_connected, cdev->config);
}
}
模块的初始化:
static int __init init(void)
{
struct android_dev *dev;
int err;
android_class = class_create(THIS_MODULE, "android_usb"); //创建/sys/class/android_usb
if (IS_ERR(android_class))
return PTR_ERR(android_class);
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
dev->disable_depth = 1; //初始化disable计数
dev->functions = supported_functions;
INIT_LIST_HEAD(&dev->enabled_functions); //初始化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);
dev = NULL;
return err;
}
_android_dev = dev;
/* Override composite driver functions */
composite_driver.setup = android_setup; //修改compoite的setup函数
composite_driver.disconnect = android_disconnect; //修改compoite的disconnect函数
err = usb_composite_probe(&android_usb_driver, android_bind); //调用USB设备层代码
if (err)
return err;
/*
* Calling usb_gadget_disconnect here. As we will call
* usb_gadget_connect only when config is ready.
*/
usb_gadget_disconnect(dev->cdev->gadget);
return err;
}
android_create_device()的工作是创建android0设备并初始化它的属性:
static int android_create_device(struct android_dev *dev)
{
struct device_attribute **attrs = android_usb_attributes;
struct device_attribute *attr;
int err;
dev->dev = device_create(android_class, NULL,
MKDEV(0, 0), NULL, "android0");
if (IS_ERR(dev->dev))
return PTR_ERR(dev->dev);
dev_set_drvdata(dev->dev, dev);
while ((attr = *attrs++)) {
err = device_create_file(dev->dev, attr);
if (err) {
device_destroy(android_class, dev->dev->devt);
return err;
}
}
return 0;
}
更多推荐
所有评论(0)