1.写代码
(1)框架
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.注册: usb_register
(2)调用过程
file_operation结构体(myuvc_fops)里面的open函数调用ioctl函数(video_ioctl2)
ioctl函数调用_video_do_ioctl函数从而调用v4l2_ioctl_ops结构体
A2 确定是不是视频设备
static int myuvc_vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
A3 枚举所支持的格式
static int myuvc_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f)
A4 返回当前所使用的格式
static int myuvc_vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
A5 尝试驱动程序是否支持某种格式
static int myuvc_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
A6 尝试支持莫种格式之后就设置这种格式
static int myuvc_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
A7 APP调用该ioctl让驱动程序分配若干缓冲区,APP将从这些缓存中读取到视频数据
static int myuvc_vidioc_reqbufs(struct file *file, void *priv,struct v4l2_requestbuffers *p)
A8 查询缓存状态,比如: 地址信息(APP可以用mmap进行地址映射)
static int myuvc_vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *v4l2_buf)
A9 把缓存映射到APP的空间,以后APP就可以直接操作这个空间进行读取信息
static int myuvc_mmap(struct file *file, struct vm_area_struct *vma)
A10 将申请的缓冲区放入队列,底层的硬件操作函数将会把数据放入到这个队列的缓冲区中
static int myuvc_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *v4l2_buf)
A11 启动传输
static int myuvc_vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
应用程序怎么知道缓冲区里面有数据,利用poll函数
A12 APP调用POLL/select来确定缓存是否就绪(有数据)
static unsigned int myuvc_poll(struct file *file, struct poll_table_struct *wait)
A13 APP通过poll/select函数确定了有数据,就把缓存从队列中取出
static int myuvc_vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *v4l2_buf)
A14 之前已经通过了mmap映射了缓存,此时APP就可以直接读数据
A15 再次调用myuvc_vidioc_qbuf,把取出的缓存放入队列
A16 poll…
A17 停止摄像头
static int myuvc_vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type t)