USB摄像头驱动思路
出入口函数注册usb_driver
结构体,设置probe
,disconnect
,id_table
等参数,其中probe函数用于设置usb控制接口的信息,设置video_device
结构体,设置它的release
, fops
,ioctl_ops
函数。并且注册这个结构体
1.首先会调用myuvc_open
函数,
2.调用querycap表明它是个摄像头,且打开数据流传输,
3.列举支持哪些的数据格式
4.返回当前所使用的格式
5.强制设置该格式,测试驱动是否支持这种格
6.APP调用该ioctl让驱动程序分配若干个缓存(作为整体一次性分配), APP将从这些缓存中读到视频数据。
7.查询缓存状态, 比如地址信息(APP可以用mmap进行映射)
8.把缓冲区放入队列, 底层的硬件操作函数将会把数据放入这个队列的缓存。APP传入的v4l2_buf
可能有问题, 要做判断。修改状态 ,放入2个队列
队列1: 供APP使用
- 当缓冲区没有数据时,放入
mainqueue
队列
- 当缓冲区有数据时, APP从
mainqueue
队列中取出
队列2: 供产生数据的函数使用
- 当采集到数据时,从
irqqueue
队列中取出第1个缓冲区,存入数据
9.启动传输
- 向USB摄像头设置参数: 比如使用哪个format, 使用这个format下的哪个frame(分辨率)
1.1 根据一个结构体uvc_streaming_control
设置数据包: 可以手工设置,也可以读出后再修改
1.2 调用usb_control_msg
发出数据包
d. 设置VideoStreaming Interface所使用的setting
d.1 从myuvc_params
确定带宽
d.2 根据setting的endpoint能传输的wMaxPacketSize
找到能满足该带宽的setting
2. 分配设置URB
3. 提交URB以接收数据
10.APP通过poll/select确定有数据后, 把缓存从队列中取出来
11.之前已经通过mmap映射了缓存, APP可以直接读数据
12.再次调用myuvc_vidioc_qbuf
把缓存放入队列
13.持续poll
14.停止,kill URB,free URB,设置VideoStreaming Interface为setting 0关闭USB接口