写一个USB摄像头驱动程序:
怎么写摄像头驱动程序:
1.分配video_device结构体:video_device_alloc函数
2.设置 .fops .ioctl_ops(里面需要设置11项) 如果要用内核提供的缓冲区操作函数,还需要构造一个videobuf_queue_ops结构体。
3.注册:video_register_device函数
怎么写USB摄像头驱动程序:
1.构造一个usb_driver
2.设置
.probe:
/***把摄像头驱动程序放在里面*******/
2.1分配video_device结构体:video_device_alloc函数
2.2设置 .fops .ioctl_ops(里面需要设置11项) 如果要用内核提供的缓冲区操作函数,还需要构造一个videobuf_queue_ops结构体。
2.3注册:video_register_device函数
/**********/
.id_table:表示支持哪些USB设备
3.注册
UVC驱动:USB Video Class 路径:drivers\media\video\uvc\
Uvc_driver.c分析:
1.usb_register(&uvc_driver.driver);
2.uvc_probe
Uvc_register_video
Vdev=video_device_alloc();
Vdev->fops=&uvc_fops;
Video_register_device
//分析可知,UVC驱动中的probe函数还是包含了之前说的摄像头驱动程序的主体。
uvc_specification UVC示例文档中:
USB摄像头示例中阐述:一定有用于控制的VideoControl Interface(VC),但是不一定有用于传输的VideoStreaming Interface(VS)。
VC内部抽象出Unit和Terminal两个概念。
Units有Select Unit(SU)和Process Unit(PU),Terminal有Input terminal(IT),Camera terminal(CT),Output terminal(OT)。SU用于选择哪一路信号,PU用于设置亮度、白平衡等。terminal用于内外连接,里面的称为unit。一般经常使用IT,而不用CT,SU为多路选择器。
通过VidiocControl Interface来控制,通过VideoStreaming Interface 来读视频数据。
VC里有多个Unit/Terminal等功能模块,可以通过访问这些模块来控制,比如调亮度。
Ioctl中VIDIOC_S_FMT对应函数中,先调用VIDIOC_TRY_FMT所对应的函数,然后再调用进行设置。但是注意VIDIOC_S_FMT对应的函数进行的操作将格式保存在数组中,还未发给USB摄像头。
上面提及的ioctl操作并没有涉及与硬件的交互,只有执行VIDIOC_STREAMON命令才会将之前设置的格式发送给USB,然后启动摄像头。这里通过的是UVC 的video streaming 接口来发送格式等数据。
如果想对摄像头的属性进行设置,如亮度、白平衡等,需要调用VIDIOC_S_CTRL ioctl操作,并通过video control interface 接口来发送属性数据。除此之外还需要entity_id变量标记需要发送到VC中的哪一个units/terminals。
总结:
1.UVC设备有2个interface:videocontrol interface 和videostream interface。
2.VideoControl Interface 用于控制,比如设置亮度,它内部有多个units/terminals,程序中都称为entity,每一个都有一个entity_id进行标识。
3.VideoStreaming Interface用于获得视频数据,也可以用来设置format/frame(格式/分辨率、位宽等)(VS可能有多种format,一个format有多种frame,frame用来表示分辨率等多种信息)。
4.我们在设置format时只是简单的使用video->streaming->format[fmt->index]等数据,这些数据哪来的?应是设备被枚举时设置的,也就是分析它的描述符时设置。
5.UVC驱动的重点在于:
描述符的分析
属性的控制:通过VideoControl Interface来控制。
格式的选择:通过VideoStreaming Interface来设置。
数据的获得:通过VideoStreaming Interface的URB来获得。