出入口函数注册usb_driver结构体,设置probe,disconnect,id_table等参数,其中probe函数用于设置usb控制接口的信息,设置video_device结构体,设置它的release, fops,ioctl_ops函数。并且注册这个结构体
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SRBkKUfZ-1580791207434)(https://i.imgur.com/NO1inqk.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HHbiRVN4-1580791207435)(https://i.imgur.com/BkfUYVr.jpg)]
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接口