作者:陨落星辰W_955 | 来源:互联网 | 2023-06-16 13:25
一、摄像头驱动开发
1.摄像头驱动架构
- 视频监控本就是嵌入式Linux的重要应用场合,所以如何合理高效的管理摄像系统,便成为嵌入式Linux一大热点!当前最流行的摄像头软件架构就是V4L2架构,从字面意思知道是专门为Linux设计的一个视频子系统的第二个版本。V4L2有一段历史了。早在1998的时候就出现了,经过长足的发展,它于2002年11 月,发布2.5.46 时,融入了内核主干之中。然而直到今天,仍有一部分内核驱动不支持新的API,这种新旧API 的转换工作仍在进行。它的主要功能是使程序具有发现设备和操作设备的能力.它主要是用一系列的回调函数来实现这些功能。像设置摄像头的频率、帧频、视频压缩格式和图像参数等等。当然也可以用于其他多媒体的开发,如音频等。但是该架构目前只能用于Linux操作系统上。整个V4L2的架构示意图如下:
- 可以看出,整个架构主要分为四个部分:
- 用户空间的应用程序:比如后面要用到的Motion以及ffmpeg等开源应用程序
- V4L2核心组件(驱动核心):这是Linux内核专门用来管理视频子系统的核心组件,也正是由于这个组建的存在,才让我们可以在用户空间使用统一的一套编程接口API去控制底层的不同硬件。
- 具体的V4L2驱动:这部分主要是针对不同的摄像头有不同的驱动程序,这写驱动程序相互独立,但是共同注册到V4L2子系统下,以便和用户空间应用程序进行通信。
- 底层硬件:就是实际的摄像头等物理硬件。
- V4L2核心是Linux系统自带的组件,它可以屏蔽摄像头驱动层的差异,不管底层的摄像头有什么差异,上层应用统一调用V4L2来实现对摄像头的操作,因此驱动程序和应用程序都需要遵循V4L2规范。
2.摄像头驱动使能
- 由于本项目采用的是基于ZC3XX系列芯片的USB摄像头,所以需要在内核里面添加该USB摄像头驱动。以后如果换成别的摄像头,根据自己摄像头的驱动芯片加载合适的驱动模块到内核即可,毕竟现在Linux支持了市面上大部分的摄像头,一般能购买到的摄像头都有相应的驱动程序,只需要自己在内核使能即可!按照如下步骤可以使能USB摄像头。
2.1 进入配置菜单
- 在内核源代码顶层目录执行 make menuconfig ARCH=arm命令。进入配置菜单。
2.2 依次选择如下配置选项:
- Device Drivers --->(毫无疑问,只要是添加驱动都是要进入这个选项)
- Multimedia devices --->(显然视频摄像头属于多媒体范畴)
- [*] Video capture adapters --->(视频捕获也即是摄像头)
- [*] V4L USB devices --->(我们采用的是USB摄像头)
- <*> GSPCA based webcams --->&#xff08;万能摄像头驱动&#xff09;
- <*> ZC3XX USB Camera Driver&#xff08;我们采用的具体USB摄像头对应的驱动程序&#xff09;
2.3 保存配置文件&#xff0c;退出配置模式&#xff0c;开始编译新内核
- #make uImage ARCH&#61;arm CROSS_COMPILE&#61;arm-linux-
- 拷贝uImage到/tftpboot/目录下
2.4 下载并启动linux内核
- 往开发板上插入摄像头后&#xff0c;会弹出相应提示&#xff0c;同时使用ls /dev/可以查看是否有vedeo的驱动文件&#xff0c;如果有则说明驱动开发成功。
3. 摄像头驱动测试
3.1 初步测试
- 插上USB摄像头看开发板串口控制台的提示&#xff0c;有如下信息输出:
- 由上面的提示信息我们知道&#xff0c;驱动使能成功&#xff0c;再通过ls命令查看dev目录下的设备文件&#xff0c;即ls /dev有&#xff1a;
- 表明我们的USB摄像头在开发板的系统里创建的对应设备文件是/dev/video0&#xff0c;当然读者要根据自身实际情况判断对应的设备文件是什么&#xff0c;有可能是video3&#xff0c;video4等。
3.2 编写应用程序进行测试
- 使用camera.c&#xff08;下接会讲如何编写&#xff09;文件交叉编译出在开发板运行的测试应用程序。在编译之前要记得修改文件里打开的设备文件&#xff0c;也就是前面说的/dev/video0&#xff0c;根据再记得设备文件修改open函数&#xff0c;如果传递给你open函数的参数不是你摄像头对应的实际设备文件&#xff0c;那么打开会有无法预知的结果&#xff0c;有可能失败&#xff0c;也可能打开某个文件导致抓取的图片是空的等情况。修改完毕以后使用如下命令进行编译&#xff1a;arm-linux-gcc -g camera.c -o camera
- 得到的camera就是可执行文件&#xff0c;将他复制到开发板的文件系统的根目录&#xff0c;并在开发板的串口控制台执行./camera命令&#xff0c;Mini2440有如下提示&#xff1a;
- 同时在根目录生成test.jpg文件&#xff0c;通过windows的samba可以查看 其效果如下所示&#xff1a;
二、V4L2图像编程接口深度学习
1.相关介绍
- Video for Linuxtwo(Video4Linux2)简称V4L2&#xff0c;是V4L的改进版。V4L2是linux操作系统下用于采集图片、视频和音频数据的API接口&#xff0c;配合适当的视频采集设备和相应的驱动程序&#xff0c;可以实现图片、视频、音频等的采集。在远程会议、可视电话、视频监控系统和嵌入式多媒体终端中都有广泛的应用。
- 在Linux下&#xff0c;所有外设都被看成一种特殊的文件&#xff0c;称为“设备文件”&#xff0c;可以象访问普通文件一样对其进行读写。一般来说&#xff0c;采用V4L2驱动的摄像头设备文件是/dev/video0。V4L2支持两种方式来采集图像&#xff1a;内存映射方式(mmap)和直接读取方式(read)。V4L2在include/ linux/videodev.h文件中定义了一些重要的数据结构&#xff0c;在采集图像的过程中&#xff0c;就是通过对这些数据的操作来获得最终的图像数据。Linux系统V4L2的能力可在Linux内核编译阶段配置&#xff0c;默认情况下都有此开发接口。
- 摄像头所用的主要是capature了&#xff0c;视频的捕捉&#xff0c;具体linux的调用可以参考下图。
}
我们可以得出如下的操作流程&#xff1a;
- 1. 打开摄像头设备文件。
- 2. 获取驱动信息-VIDIOC_QUERYCAP&#xff1b;在此之后可以获取更多的信息&#xff0c;不仅仅是本程序中后面的获取设置图像格式&#xff0c;我们还可以获取摄像头所支持的图像格式等信息。
- 3. 设置图像格式-VIDIOC_S_FMT&#xff1b;
- 4. 申请帧缓冲区-VIDIOC_REQBUFS&#xff1b;在Linux里面&#xff0c;必须要有帧缓冲区才可以进行图像的捕获&#xff0c;有了帧缓冲区以后&#xff0c;可以将帧缓冲区设置为输入队列&#xff0c;经过驱动程序以后&#xff0c;就将图像信息写到帧缓冲区&#xff0c;写入图像数据以后的帧缓冲区会加入输出队列&#xff0c;用户空间的应用程序最重要取出输出队列的帧缓冲区&#xff0c;然后读里面的内容&#xff0c;最后将被读取数据以后的帧缓冲区再次放回到输入队列&#xff0c;如此循环完成视频监控功能。但是要注意的是&#xff0c;这里申请的帧缓冲区是内核空间的&#xff0c;所以应用程序不能直接访问&#xff0c;需要通过映射等操作。而且输入队列和输出队列都是帧缓冲构成的。
- 5. 获取帧缓冲的地址以及长度信息-VIDIOC_QUERYBUF&#xff1b;
- 6. 使用mmap将内核空间的帧缓冲映射到用户空间&#xff1b;
- 7. 帧缓冲入队列-VIDIOC_QBUF&#xff1b;
- 8. 开始采集图像-VIDIOC_STREAMON&#xff1b;在此之后需要使用select函数等待输出缓冲有数据可读再进行下一步操作。
- 9. 取出帧缓冲&#xff08;出队&#xff09;-VIDIOC_DQBUF&#xff1b;
- 10. 访问帧缓冲读取数据-使用write等函数将数据写入到目标文件。
- 11. 帧缓冲重新入队列-VIDIOC_QBUF&#xff1b;已经读取过数据的帧缓冲要放入输入队列。
- 12. 关闭相关设备和文件进行以及解除映射等扫尾工作。