基于Linux操作系统的视频采集卡驱动程序设计
DMA结构:
struct saa7146_video_dma {
u32 base_odd;
u32 base_even;
u32 prot_addr;
u32 pitch;
u32 base_page;
u32 num_line_byte;
};
工作流程
v4l2_extension调用v4l2_register_device()函数注册设备,V4l2_register_device()函数进而调用v4l2_init_done()函数(v4l2_device结构中的int(*initialize)()字段已被初始化为该函数)通过写 I/O地址空间具体的初始化设备,设置采集图像的默认参数等。这时候设备已经做好了采集图像的准备工作。
下面通过典型的read一桢图像来分析具体的工作流程:
应用程序首先调用系统调用open()来打开设备,v4l2将该调用映射为初始化设备时已经设置好的v4l2_device结构中的 int(*open)(),在本文中即为v4l2_open();打开设备成功read一桢图像数据的命令,此时系统通过v4l2_device结构中已经设置好的int(*open)()字段调用相应的函数v4l2_read(),该调用负责分配内核内存缓冲区,并将采集到的数据从内核空间复制到用户空间,这样应用程序就获得了一桢数据;
当v4l2_capability结构中的V4L2_CAP_STREAMING标志被设置时,这表明设备支持流采集。V4L2 的流驱动程序维护两个组织成FIFO的缓冲区队列:发送队列和接收队列。由于应用程序受到网络延迟,进程抢占或随机磁盘存储的影响,维护两个队列就可以把异步的视频采集或输出操作与应用程序分离开,从而降低丢失数据的可能性。设备采集到图像后可以用DMA 方式直接将数据放入应用程序分配好的缓冲区中,这就大大提升了整个系统的性能。
4.2.3 测试驱动程序[6]
首先编译上述模块,然后通过命令insmod链接进内核。用于测试的简单应用程序主体部分如下所示:
vid = open(device, O_RDONLY);/*打开设备*/
err = ioctl(vid, VIDIOC_QUERYCAP, cap); /*查询设备支持的功能*/
err = ioctl(vid, VIDIOC_G_FMT, fmt);/*设置采集图像的格式*/
data = malloc(fmt.fmt.pix.sizeimage);/*分配用户空间缓冲区*/
n = read(vid, data, fmt.fmt.pix.sizeimage);/*获取一桢数据*/
该应用程序运行后经检查得到了预期的结果,并且在基于该驱动程序的CDMA无线视频传输系统中满足了应用的需要,获得了理想的效果。
5 结论
本文作者创新点:详细阐述了Linux环境下利用V4L2API开发视频采集设备驱动程序的流程,并将该驱动程序实际的应用到我们自己研发的CDMA无线视频传输系统中,获得了满意的实时效果,在此也希望对从事同类开发的人员有所裨益。
参考文献
1 Alessandro Rubini Jonathan Corbet,Linuxdevice driver,2nd Edition,O’Reilly,2001.7
2 Philip SAA7146A datasheet,1998.4
3 Philip SAA7111A datasheet,1998.5
4 http://linux.bytesex.org/v4l2/
5 PCI SIG,PCI Local Bus Specification Revision 2.2,1998.12
6 王多智,嵌入式linux下sram驱动程序的开发原理及应用,微计算机信息,2005年第5期
linux操作系统文章专题:linux操作系统详解(linux不再难懂)linux相关文章:linux教程
评论