UVC摄像头(1)驱动层——精简结构框架

* “本文写的是USB摄像机linux驱动层简单介绍,linux的USB驱动非常复杂,坑很大,搞懂全部的七八成就是大神级别的人物了。我刚开始上手UVC驱动非常晕,超多结构体,还是指针形式,封装层数庞大,各种bind,以前linux驱动基本没碰过,只看过开发板手册里的LED驱动,现在直接做USB驱动,只能一步步来,不心急。”*

我们现在要做的是驱动一个USB接口摄像机,所以写的是USB设备的代码,而不是USB主机host。
这个驱动名称可以称作Linux USB Gadget类软件。

Linux USB Gadget软件分为三层。这三层其中两层是与硬件无关的,分别是Gadget功能驱动层、USB设备层。UDC层与硬件有关。
代码很复杂,我们简化一下,三个层主要用到的结构体如下,各项参数设置都与他们有关系

Gadget功能驱动层:usb_composite_driver
USB设备层:  usb_composite_dev与usb_gadget_driver
UDC层:  usb_gadget

1. linux驱动程序框架

这是给新手看的,高手略过

module_init(webcam_init);//初始化
module_exit(webcam_cleanup);//卸载

本驱动是用的平台驱动,webcam_cleanup是卸载入口,很简单,我们先从简单的来

2. 两个入口

webcam_cleanup(void)
{
    usb_composite_unregister(&webcam_driver);
}

里面调用的是usb_gadget_unregister_driver方法,这是Linux USB Gadget系统的方法,我们完全不用看,了解他的作用就行。
接下来看

webcam_init(void)
{
    return usb_composite_probe(&webcam_driver, webcam_bind);
}

代码很简单,就一个函数,很轻松,这个心态要保持
这里的webcam_driver就是usb_composite_driver类型的结构体,是最上层的Gadget功能驱动层

3. 进入初始化

static struct usb_composite_driver webcam_driver = {
    .name       = "g_webcam",
    .dev        = &webcam_device_descriptor,
    .strings    = webcam_device_strings,
    .max_speed  = USB_SPEED_HIGH,
    .unbind     = webcam_unbind,
};

在usb_composite_probe里面填充composite_driver结构体。composite_driver是usb_gadget_driver结构体,所以开始连接USB设备层,之后执行此函数

usb_gadget_probe_driver(&composite_driver, composite_bind);

这里面定义了usb_gadget结构体,出现了最底层的UDC层。之后把它传到。

composite_bind(struct usb_gadget *gadget)

这里面定义了一个usb_composite_dev结构体cdev,这是USB设备层的,所以关系挺复杂的,我们暂时不去理解。
之后填充cdev结构体,毫无疑问,它保存了上层的很多信息。
这个函数有点复杂,主要用到了这几个接口

composite_gadget_bind(cdev);//这个函数里面内容有点多,之后我会再发一篇文作基础介绍
override_id(cdev, &cdev->desc.iManufacturer);
device_create_file(&gadget->dev, &dev_attr_suspended);

这些是三个层里最底层的,最后一个函数都是创建文件了

4.之后

composite_bind结束之后回到了usb_gadget_probe_driver,然后执行

usb_gadget_start(udc->gadget, driver, bind);

这是库里面的方法,很简单易懂,就是开始运行。

结语

一些参数都是围绕这3层的4个结构体相关的,linux已经做好了框架,我们只需要填充进去就行。细看里面的参数,会发现非常庞大,全部看完肯定晕,所以先去看你想了解的地方,一块一块慢慢啃,一口啃完大象绝对会吐出来的。

学习LiunxC语言书写方法

1.结构体作形参

fun(*struct x){
 struct *example = &x;
}

2.指针函数

int foo(int x,int y);
int fun(char a,int (*pfun)(int x,inty)){
    pfun(1,2);
}
调用:fun('c',foo);

猜你喜欢

转载自blog.csdn.net/schumi2000/article/details/82017651