基于cortexA8 的V4L2 视频采集驱动设计
2015-09-19刘泽,陈洋,陈林
刘 泽,陈 洋,陈 林
(重庆邮电大学,重庆400065)
嵌入式视频采集系统软件平台大多用的是Linux 系统,V4L2 是Linux 内核采用的视频采集基本框架,相比于V4L,V4L2 更灵活,扩展性也更好一些,由于V4L2 对V4L 的改动较大,两者并不兼容[1]。V4L2 支持多种设备,并且支持视频采集接口、视频输出接口等。视频采集采用的流水线方式使得V4L2 的操作极其简单方便。V4L2 中还提供大量API 来对摄像头进行基本操作,这些操作主要通过调用ioctl 来实现设备打开、关闭,以及图像格式、曝光、增益等操作[2],一般V4L2 驱动是让CPU 通过I2C 总线对图像传感器进行读写操作,I2C 总线包括数据总线和时钟总线,主要由三部分构成:I2C 总线驱动、I2C 设备驱动和I2C 核心[3]。
本文采用MT9M001 图像传感器,开发出支持曝光、增益以及图片尺寸大小等参数设置的驱动程序,CPU 采用TI 公司的AM3354,由于该芯片并没有标准的摄像头接口,硬件方案采用CPLD+SRAM 方式对CMOS 传感器采集数据进行预处理和缓存,并参照Linux 自带虚拟摄像头ViVi,设计出具有两个线程的驱动程序,详细给出了非标准摄像头接口的V4L2驱动程序的设计过程,最后调用动态库API 来实现抓图。
1 V4L2 介绍
Linux 提供了虚拟摄像头驱动程序ViVi,其框架也是基于V4L2 标准,V4L2 主要包括V4L2 驱动核心、字符设备驱动核心、平台V4L2 驱动以及具体传感器驱动,见图1。
图1 V4L2 驱动框架
V4L2 作为两层驱动系统,在videodev 顶层模块,初始化时会被注册为主设备号为81 的字符设备,底层则是以videodevice 为核心的V4L2 驱动,该结构主要包含了功能函数以及视频设备的属性。此外videodev 模块还提供video_device_register 函数API 来注册V4L2 驱动,生成视频设备节点,比如/dev/video1 等。V4L2 驱动源码位于内核目录/driver/media/video 下面,主要核心代码文件有[4]:
1)v4l2-dev.c 视频捕捉接口,主要数据结构为:struct video-device,主要用于射频设备的注册。
2)v4l2-device.c v4l2 提供设备描述,主要用于注册v4l2设备。
3)v4l2-ioctl.c 为ioctl 提供了通用框架,主要是为了实现结构体v4l2_ioctl_ops 视频操作相关联下的API。
4)v4l2-mem2mem.c 内存之间的操作函数,是内核和视频设备缓冲之间的框架。
5)v4l2-common.c 通用视频的设备接口,此文件替换videodevice.c 文件配备常规内核分配。
在V4L2 核心中,提供了一套标准API 来用于视频处理缓冲器,这些API 允许驱动程序用自己的方式实现read()、mmap()等[5]。
目前设备上的视频缓冲器,支持线性存取DMA 的方式。Videobuf 层实现了用户空间与驱动程序之间数据传输的粘合性,主要用于帧缓冲管理和分配。Videobuf 层的更多相关信息,在内核目录的Documentation/video4linux/videobuf 中有详细说明。
2 系统平台
2.1 MT9M001 图像传感器
图像传感器采用的是micron 公司的MT9M001 CMOS 图像传感器,该传感器帧率最大为30 f/s(帧/秒),即1 s 最大可以采集30 帧图像数据,最大支持130 万像素。性能优异,由于图像传感器采集的数据是10 位的灰度值,实际采集使用时舍去两位,保存为8 位位图格式来降低存储空间。
2.2 cortex A8 硬件平台
主控芯片采用的是cortex A8 系列的ARM 处理器AM3354,工作时钟最大为800 MHz,具有抗高温、抗干扰等特点,完全可以满足高清工业相机对CPU 的要求。
3 V4L2 驱动设计
3.1 驱动程序执行流程
在主线程中,会注册I2C 设备,通过检查设备的名字,若有相同名字的设备probe 函数便会被调用,在驱动探测函数中需要使能图像传感器。通过传感器的ID 号0x8431 来完成初始化。
reg_write(cmos_mt9m001_client,MT9M001_CHIP_ENABLE,1);
mid=reg_read(cmos_mt9m001_client,MT9M001_CHIP_VERSION);
if(mid!=0x8431)return ENXIO;
若能识别传感器ID 号,说明传感器被正确连接。应用程序调用open 打开注册的视频设备节点时,驱动中的open 函数会被执行,在open 函数中会创建一个负责读取传感器数据的子线程,在子线程被创建后会一直休眠。
kthread_run(cmos_buffer,dev,dev->v4l2_dev.name);
set_current_state(TASK_INTERRUPTIBLE);
wait_for_completion(&thread_completion);
此处采用CPLD 来预处理一帧的图像数据,当CPLD 完成一帧数据的预处理后,通过CPLD 产生边沿触发信号来对视频数据进行读取,同时在open 函数中会申请cpld_int 内核中断函数:
ret =request_irq(CPLD_IRQ,cpld_int,IRQF_TRIGGER_FALLING,"frame_interrupt",NULL);
CPLD 完成预处理后会向CPU 发出中断,中断函数会被调用,在中断处理函数中会调用完成量唤醒创建的子线程。
子线程会对缓冲区队列数据进行处理,其运行结束后会唤醒应用程序采集,一帧图像数据处理完成,总结主次线程流程见图2。
图2 主次线程执行流程
在内核下的video_buf.c 中提供了V4L2 视频缓冲区内存管理的函数,视频的数据队列通过videobuf_queue 结构体来管理,在此结构体中通过videobuf_queue_ops 结构体来进行相关视频缓冲区操作,数据结构里主要提供API 来进行缓存区的具体操作。buffer_prepare 用来准备好队列中的帧缓冲,buffer_queue 用来将buffer 加入对列,buffer_cleanup 则用来清除对列[6]。
3.2 采集流程
视频采集主要基于ioctl 操作集来实现,Linux 内核专门提供v4l2_ioctl_ops 结构体来管理缓冲区数据。常用函数说明如表1。
表1 v4l2_ioctl_ops 操作集
表中每一个ioctl 对应一个API 接口,这些API 需要手动实现[7]。视频采集一帧数据流程如图3 所示。
图3 视频采集基本流程
在对图像数据进行采集时,在没有DMA 情况下,直接read 和write 方式从内核空间拷贝大量数据到用户空间的方式,不仅耗费大量内存,效率也十分低下[8]。本驱动采用内存映射的方式,向内和空间申请2 ~4 个缓冲区,当应用程序调用mmap 函数时,驱动程序不再是直接拷贝数据到用户空间,而是利用mmap 来建立缓冲区和用户空间的映射,即直接对用户空间进行操作,效率大大提高。驱动程序建立映射只需对数据结构v4l2_file_operations 成员函数mmap 填充即可。
3.3 高级功能
本驱动中还支持设置采集图片尺寸大小以及曝光、增益等的设置。其中v4l2_ctrl_ops 结构体中的成员函数s_ctrl 用来设置曝光增益值,而g_volatile_ctrl 用来获取曝光值。
4 测试
硬件环境搭载好后,通过makefile 将驱动程序生成.ko 文件,将.ko 文件用insmod 命令安装驱动。会在文件目录/dev下自动生成video1 文件,此文件就是V4L2 驱动挂载点,对驱动程序进行测试时,将测试程序封装为动态库,动态库中各个API 说明如表2。
表2 动态库API 功能说明
上述API 中,CameraImageProcess 比较关键,因为其预留出图像数据数组指针,实际需要对图像进行分析处理时,只需获得该API 参数指针进行操作即可,图4 和图5 为调用封装动态库采集图片。
5 结束语
本文针对cortexA8 硬件平台以及cmos 图像传感器mt9m001,实现一款针对非标准摄像头接口的V4L2 驱动,详细阐述了程序的设计思路以及实现应用程序动态库的封装,并在驱动程序中实现了对曝光、增益值得设置。最后通过调用应用程序封装的动态库采集图片来验证驱动的正确性,对没有标准摄像头接口的平台开发具有一定借鉴意义。
图4 未设置曝光增益采集的图片
图5 加入曝光增益设置采集的图片
[1]王飞,孔聪. 基于V4L2 的Linux 摄像头驱动的实现[J]. 电子科技,2012,25(2):86-87.
[2]黄俊伟,巴义. 基于V4L2 移动视频监控系统的研究与设计[J]. 电视技术,2012,36(17):159-162.
[3]宋宝华.Linux 设备驱动开发详解[M].北京:人民邮电出版社,2008.
[4]蔡小伟.基于ARM cortex A8 的嵌入式视频监控系统设计[D].南昌:南昌大学,2013.
[5]廖梦云,赵利,莫金旺.基于CMOS 图像传感器的嵌入式视频采集系统设计[J].计算机系统应用,2009(5):194-197.
[6]余臣.高分辨率高速CMOS 相机的硬件设计[D].成都:电子科技大学,2011.
[7]刘登诚,沈苏彬,李莉. 基于V4L2 的视频驱动程序设计与实现[J].微计算机信息,2011,27(10):56-58.
[8]丛培超.高帧高清CMOS 工业摄像机设计与实现[D].大连:大连理工大学,2013.