




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、前言先前已经分析过V4L2的框架,并且使用了xawtv测试了vivi虚拟驱动程序,对框架的分析并没有深入结构,比如说ioctl有很多,但是并不清楚哪些是必须的,哪些可以不要。并且也不知道测试程序是如何拿到视频数据的。本文将介绍如何根据虚拟驱动vivi的使用过程彻底分析摄像头驱动。第1章vivi测试补充加载vivi.ko驱动之前,先加载videobuf-core.kovideobuf-vmalloc.kov4l2-common.ko这3个模块,然后就可以加载vivi.ko成功了。然而换了一台电脑,再执行一遍就不行了,在加载v4l2-common.ko时执行“sudo insmod v4l2-co
2、mmon.ko”打印信息提示如下: Insmod:error inserting v4l2-common.ko:-1 Unknown symbol in module使用dmesg命令查看详细信息:v4l2_common:Unknown symbol v4l2_device_register_subdevv4l2_common:Unknown symbol v4l2_device_unregister_subdev那么为什么原来的电脑可以正常加载驱动,现在的电脑就不行了呢?1.2 加载vivi.ko失败原因这是因为先前电脑测试时是先插上的UVC摄像头测试的,这时电脑会自动加载对应的v4l2相关
3、的驱动ko,这个时候再加载vivi.ko驱动的时候就不缺少相应的symbol。而换了一台电脑没有插uvc摄像头驱动,所以问题就出现了。解决办法-依次执行下面三步骤:sudo modprobe vivi /安装ubuntu自带的驱动程序sudo rmmod vivi /卸载内核自带的vivi驱动sudo insmod vivi.ko /安装自己编译出的vivi.ko1.3 insmod与modprobe第2章分析xawtv源码2.1 获取xawtv源码下载源码后建立一个sourceinsight工程,当然可以从main开始分析,看看涉及到哪些系统调用。但是这样会非常复杂,因为xawtv除了调用v
4、ivi驱动程序之外,还有其他很多的工作,如何快捷的知道有哪些调用呢?有一个办法,使用strace工具可以看出xawtv使用了哪些系统调用。2.2 strace工具使用方法:strace o xxx.log cmdcmd为命令,执行cmd命令时会将涉及到的系统调用(open,read,write都会记录到到xxx.log中。执行”strace o xawtv.log xawtv”,在当前目录生成xawtv.log,将该文件拷到PC机上,下面对该文件进行分析。2.3 分析xawtv.log使用UltraEdit打开xawt.log,xawtv不指定设备打开时是默认打开video0,因此上节操作的是
5、video0,因为文件内容比较多,我们需要先得到我们关系的东西,搜索“/dev/video0”,得到如下图: 可以看出open打开两次,第一次打开后发现ioctl用不了,因此close,然后打开第2次。可以看出open之后,得到一个文件句柄“4”,后面接了一大堆ioctl。搜索“(4,”,就可以看出涉及到哪些调用了。勾选搜索对话框的“列出包含字符串的行”,搜索如下图: 复制搜索到的结果,存为新的文件“xawtv涉及的vivi驱动的系统调用.txt”。从xawtv.log可以看出,open之后,涉及到的第一个系统调用是:open("/dev/video0", O_RDWR|O
6、_LARGEFILE = 4ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0x8f0b998 = -1 EINV AL (Invalid argumentclose(4ioctl失败,然后关闭。我们重点关注第2次open后面的内容,如下: 详细如下:open("/dev/video0", O_RDWR|O_LARGEFILE = 4ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0xbf90a2e4 = 0ioctl(4, VIDIOC_G_FMT or VT_SENDSIG, 0xbf90a218 = 0i
7、octl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, 0xc02c564a, 0xbf90a0f8 = -1 EINV AL (Invalid argumentioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, 0xc02c564a, 0xbf90a0f8 = -1 EINV AL (Invalid argumentioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, 0xc02c
8、564a, 0xbf90a0f8 = -1 EINV AL (Invalid argumentioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = -1 EINV AL (Invalid argumentioctl(4, V
9、IDIOC_QUERYCAP or VT_OPENQRY, 0xbf90a124 = 0ioctl(4, VIDIOC_G_INPUT, 0xbf909fcc = 0ioctl(4, VIDIOC_ENUMINPUT, 0xbf909fcc = 0fstat64(4, st_mode=S_IFCHR|0660, st_rdev=makedev(81, 0, . = 0ioctl(4, MA TROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0xbf90a018 = -1 EINV AL (Invalid argumentioctl(4, VIDIOC_QUERY
10、CAP or VT_OPENQRY, 0x8f0b998 = 0fcntl64(4, F_SETFD, FD_CLOEXEC = 0ioctl(4, VIDIOC_ENUMINPUT, 0x8f0bacc = 0ioctl(4, VIDIOC_ENUMINPUT, 0x8f0bb18 = 0ioctl(4, VIDIOC_ENUMINPUT, 0x8f0bb64 = 0ioctl(4, VIDIOC_ENUMINPUT, 0x8f0bbb0 = 0ioctl(4, VIDIOC_ENUMINPUT, 0x8f0bbfc = -1 EINV AL (Invalid argumentioctl(4
11、, VIDIOC_ENUMSTD, 0x8f0bf8c = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0bfcc = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c00c = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c04c = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c08c = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c0cc = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c10c = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c14c = -1 E
12、INV AL (Invalid argumentioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x8f0c38c = 0ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x8f0c3cc = 0ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x8f0c40c = 0ioctl(4, VIDIOC_G_PARM, 0x8f0ba00 = 0ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x8f0cb8c = 0ioctl(4, MATROX
13、FB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x8f0cbd0 = 0ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x8f0cc14 = 0ioctl(4, VIDIOC_G_STD, 0xbf90a3a8 = 0ioctl(4, VIDIOC_G_INPUT, 0xbf90a3bc = 0ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbf90a3b4 = 0ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xb
14、f90a3b4 = 0ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbf90a3b4 = 0ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbf90a3b4 = 0ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbf90a3c4 = 0ioctl(4, VIDIOC_TRY_FMT, 0x8f0dca4 = 0ioctl(4, VIDIOC_S_FMT or VT_RELDISP, 0xbf909cf4 = 0ioctl(4, VIDIOC_TRY_
15、FMT, 0x8f0dca4 = 0ioctl(4, VIDIOC_REQBUFS or VT_DISALLOCA TE, 0x8f0dd80 = 0ioctl(4, VIDIOC_QUERYBUF or VT_RESIZE, 0x8f0dd94 = 0ioctl(4, VIDIOC_QUERYBUF or VT_RESIZE, 0x8f0ddd8 = 0ioctl(4, VIDIOC_QBUF, 0x8f0dd94 = 0ioctl(4, VIDIOC_QBUF, 0x8f0ddd8 = 0ioctl(4, VIDIOC_STREAMON, 0xbf909fcc = 0ioctl(4, MA
16、TROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbf90a3b0 = 0ioctl(4, MATROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbf90a3b0 = 0ioctl(4, MATROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbf90a3b0 = 0ioctl(4, MATROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbf90a3b0 = 0ioctl(4, VIDIOC_S_INPUT, 0xbf90a424 = 0ioctl(4, VIDIOC_S_STD, 0x8f0bf90
17、 = 0ioctl(4, VIDIOC_DQBUF, 0xbf90a2a0 = 0ioctl(4, VIDIOC_QBUF, 0x8f0dd94 = 0ioctl(4, VIDIOC_DQBUF, 0xbf90a2a0 = 0ioctl(4, VIDIOC_QBUF, 0x8f0ddd8 = 0ioctl(4, VIDIOC_DQBUF, 0xbf90a2a0 = 0.由上小节可得系统调用顺序:1、open("/dev/video0", O_RDWR|O_LARGEFILE = 4-打开设备2、ioctl(4, VIDIOC_QUERYCAP3、ioctl(4, VIDIO
18、C_G_FMT-获得摄像头数据的格式4、for( -从上图可以看出连续多次调用,从下面分析xawtv源码也可以看出。ioctl(4, VIDIOC_ENUM_FMT-列举出摄像头支持的格式5、ioctl(4, 0xc02c564a, 0xbf90a0f8 = -1 EINV AL (Invalid argument-Invalid先不管6、ioctl(4, VIDIOC_QUERYCAP7、ioctl(4, VIDIOC_G_INPUT-获得当前使用的输入源8、ioctl(4, VIDIOC_ENUMINPUT-列举出输入源,数据可能有多个通道9、ioctl(4, VIDIOC_QUERYCT
19、RL-查询属性,比如亮度,对比度10、ioctl(4, VIDIOC_QUERYCAP11、fcntl64(4, F_SETFD, FD_CLOEXEC-当应用程序关闭,并且不是直接调用close来关闭这个文件的话,系统帮忙来关闭12、for(ioctl(4, VIDIOC_ENUMINPUT-列举出输入源,数据可能有多个通道13、for(ioctl(4, VIDIOC_ENUMSTD-列举标准制式14、for(ioctl(4, VIDIOC_ENUM_FMT-列举支持的格式15、ioctl(4, VIDIOC_G_PARM-获取参数16、for(ioctl(4, VIDIOC_QUERYCT
20、RL -查询属性,比如亮度,最小值,最大值,默认值17、ioctl(4, VIDIOC_G_STD-获得当前使用的标准制式,摄像头所支持的制式是PAL,还是NTSC等18、ioctl(4, VIDIOC_G_INPUT-当前使用的哪一个通道19、for(ioctl(4, VIDIOC_G_CTRL-获得当前的属性,比如亮度,对比度20、ioctl(4, VIDIOC_TRY_FMT-试试能否支持某种格式,比如RGB,YUV21、ioctl(4, VIDIOC_S_FMT-设置摄像头使用某种格式(尝试成功后22、ioctl(4, VIDIOC_REQBUFS-请求系统分配缓冲区23、ioctl(
21、4, VIDIOC_QUERYBUF-查询所分配的缓冲区24、for(ioctl(4, VIDIOC_QBUF-把缓冲区放入队列25、ioctl(4, VIDIOC_STREAMON-启动摄像头26、for(ioctl(4, VIDIOC_S_CTRL-设置属性,比如亮度27、ioctl(4, VIDIOC_S_INPUT-设置输入源28、ioctl(4, VIDIOC_S_STD-设置标准(制式29、for(select(5, 4, NULL, NULL, 5, 0 /查询是否有数据ioctl(4, VIDIOC_DQBUF-de-queque,把缓冲区从队列中取出/*处理*/ioctl(4
22、, VIDIOC_QBUF-处理完后把缓冲区放入队列VIDIOC_ENUM_FMT有多次使用,在sourcesight里面搜索下xawtv源码,发现在drv0-v4l2.c中有用到VIDIOC_ENUM_FMT,是一个for循环。for (h->nfmts = 0; h->nfmts < MAX_FORMA T; h->nfmts+ h->fmth->nfmts.index = h->nfmts;h->fmth->nfmts.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 = xioctl(h->f
23、d, VIDIOC_ENUM_FMT, &h->fmth->nfmts, EINVALbreak;同样查看源码,VIDIOC_ENUMINPUT,VIDIOC_ENUMSTD也多次调用,是一个for 循环。这些调用都是在drv0-v4l2.c里面的get_device_capabilities(struct v4l2_handle *h函数里面。由上面分析,涉及到的系统调用非常多,而有些是不必要的,下面来做精简。在代码中查找,系统调用在应用程序的函数可以总结如下:/*12都是在v4l2_open里调用*/1. open2. ioctl(4, VIDIOC_QUERYCAP/
24、*37 都是在get_device_capabilities里调用*/3. for(ioctl(4, VIDIOC_ENUMINPUT/ 列举输入源4. for(ioctl(4, VIDIOC_ENUMSTD / 列举标准(制式, 不是必需的5. for(ioctl(4, VIDIOC_ENUM_FMT / 列举格式6. ioctl(4, VIDIOC_G_PARM7. for(ioctl(4, VIDIOC_QUERYCTRL / 查询属性(比如说亮度值最小值、最大值、默认值/*810都是通过v4l2_read_attr来调用的*/8. ioctl(4, VIDIOC_G_STD / 获得当
25、前使用的标准(制式, 不是必需的9. ioctl(4, VIDIOC_G_INPUT10. ioctl(4, VIDIOC_G_CTRL / 获得当前属性, 比如亮度是多少/*未发现在哪儿调用*/11. ioctl(4, VIDIOC_TRY_FMT / 试试能否支持某种格式/*12通过v4l2_setformat调用*/12. ioctl(4, VIDIOC_S_FMT / 设置摄像头使用某种格式/* 1316在v4l2_start_streaming*/13. ioctl(4, VIDIOC_REQBUFS / 请求系统分配缓冲区14. for(ioctl(4, VIDIOC_QUERYB
26、UF / 查询所分配的缓冲区mmap15. for (ioctl(4, VIDIOC_QBUF / 把缓冲区放入队列16. ioctl(4, VIDIOC_STREAMON / 启动摄像头/* 17里都是通过v4l2_write_attr来调用的*/17. for (ioctl(4, VIDIOC_S_CTRL / 设置属性ioctl(4, VIDIOC_S_INPUT / 设置输入源ioctl(4, VIDIOC_S_STD / 设置标准(制式, 不是必需的/*v4l2_nextframe > v4l2_waiton */18. v4l2_queue_allv4l2_waitonfor
27、 (select(5, 4, NULL, NULL, 5, 0 = 1 (in 4, left 4, 985979ioctl(4, VIDIOC_DQBUF / de-queue, 把缓冲区从队列中取出/ 处理, 之以已经通过mmap获得了缓冲区的地址, 就可以直接访问数据ioctl(4, VIDIOC_QBUF / 把缓冲区放入队列总结如下:应用程序通过VIDIOC_REQBUFS请求系统分配缓冲区,用VIDIOC_QUERYBUF来查询系统分配的缓冲区,再用VIDIOC_QBUF把缓冲区放到驱动程序某个队列里面,调用VIDIOC_STREAMON启动摄像头。调用select函数来查询有没有
28、数据,如果驱动程序有了数据,就会把应用程序唤醒,应用程序通过调用VIDIOC_DQBUF来获得缓冲区的信息并处理它,处理完之后再放回队列中。xawtv的几大函数:1. v4l2_open2. v4l2_read_attr/v4l2_write_attr3. v4l2_start_streaming4. v4l2_nextframe/v4l2_waiton2.4 简化vivi的驱动程序应用程序使用ioctl,最终会使用的驱动程序的ioctl,驱动程序vivi.c的ioctl详细列表如下:static const struct v4l2_ioctl_ops vivi_ioctl_ops = .vi
29、dioc_querycap = vidioc_querycap,.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,.vidioc_reqbufs = vidioc_reqbufs,.vidioc_querybuf = vidioc_querybuf,.vidioc_qb
30、uf = vidioc_qbuf,.vidioc_dqbuf = vidioc_dqbuf,.vidioc_s_std = vidioc_s_std,.vidioc_enum_input = vidioc_enum_input,.vidioc_g_input = vidioc_g_input,.vidioc_s_input = vidioc_s_input,.vidioc_queryctrl = vidioc_queryctrl,.vidioc_g_ctrl = vidioc_g_ctrl,.vidioc_s_ctrl = vidioc_s_ctrl,.vidioc_streamon = vi
31、dioc_streamon,.vidioc_streamoff = vidioc_streamoff,#ifdef CONFIG_VIDEO_V4L1_COMPAT.vidiocgmbuf = vidiocgmbuf,#endif;这些ioctl有些是必须的,有些不是必须的,下面先列出结果。摄像头驱动程序必需的11个ioctl/ 表示它是一个摄像头设备.vidioc_querycap = vidioc_querycap,/* 用于列举、获得、测试、设置摄像头的数据的格式*/.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,.vidioc_g_
32、fmt_vid_cap = vidioc_g_fmt_vid_cap,.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,/* 缓冲区操作: 申请/查询/放入队列/取出队列*/.vidioc_reqbufs = vidioc_reqbufs,.vidioc_querybuf = vidioc_querybuf,.vidioc_qbuf = vidioc_qbuf,.vidioc_dqbuf = vidioc_dqbuf,/ 启动/停止.vidioc_streamon
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年中医心理治疗师资格考试试卷及答案
- 2025年英语专业翻译资格考试卷及答案
- 2025年生物学科综合考试试题及答案
- 2025年全国语言文字应用能力测试试题及答案
- 2025年大数据分析师资格考试试题及答案
- 2025年保定市中考二模历史试题及答案
- 法律基础知识考试题库及参考答案
- 七级试题及答案
- 七下生物测试题及答案
- 2025年法医DNA检测试剂项目建议书
- 2024年青海省中考一模语文试题
- 电器安装维修服务合同
- 中信证券公司融资融券业务方案设计
- 2023版煤矿安全管理人员考试题库及解析
- DBJ04T 289-2020 建筑工程施工安全资料管理标准
- 互联网金融(同济大学)知到智慧树章节测试课后答案2024年秋同济大学
- 宏观经济学知到智慧树章节测试课后答案2024年秋浙江大学
- 整体施工劳务服务方案
- 2025年贵州盘江精煤股份有限公司招聘笔试参考题库含答案解析
- 2024年中考数学复习:中点模型专项练习
- 2025年上半年陕西西安市事业单位招聘高层次及紧缺特殊专业人才690人重点基础提升(共500题)附带答案详解-1
评论
0/150
提交评论