分析的是韦东山第三期视频中的从零编写USB摄像头驱动里的代码
1)入口函数:
注册一个usb_driver结构体:usb_register里面有什么内容?
根据id_table进行匹配 :表示它能支持哪些设备
当接上能够支持的设备的时候,会调用probe函数
2)在probe函数里注册video_device结构体:
分配video_device结构体:video_device_alloc
设置这个结构体
将v4l2_file_operation结构体的内容赋给video_device的fops
使用.open打开对应的设备节点
使用.ioctl传递相应的参数和命令
使用.mmap把缓存映射到应用空间,让应用可以直接操作这块缓存
使用.poll确定缓存是否有数据
使用.close关闭对应的设备节点
将v4l2_ioctl_ops结构体的内容赋给video_device的ioctl_ops
v4l2_ioctl_ops包含了我们需要操作的ioctl函数
注册这个结构体到内核:video_register_device
3)在disconnect函数里卸载video_device结构体:
卸载video_device结构体:video_unregister_device
释放为video_device申请的内存:video_device_release
4)ioctl填充:
(1)获取这是一个什么设备:
myuvc_vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
表示这是一个摄像头设备
具有的性能是图像捕获和流传输
(2)列举这个摄像头设备所能够支持的格式:
myuvc_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
这里只支持一种格式:"YUV 4:2:2 (YUYV)"
视频格式包含在drivers/media/video/uvc/uvc_driver.c的uvc_format_desc结构体里面
(3)返回当前所使用的格式:
myuvc_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
一开始当前所使用的格式是我们初始化时设置在myuvc_format的格式
所以我们直接将我们初始化好的格式赋给v4l2_format结构体即可:memcpy
(4)测试驱动程序是否支持某种格式,如果支持,强制设置为这种格式:
myuvc_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
判断性能格式类型是否图像捕获类型:V4L2_BUF_TYPE_VIDEO_CAPTURE
判断图像格式是否是YUYV:V4L2_PIX_FMT_YUYV
查看支持的分辨率frame是哪几种,强制设置为我们需要的分辨率frame
设置的参数:
f->fmt.pix.width 帧宽
f->fmt.pix.height