APP下载

USB摄像头在嵌入式Linux中的应用

2010-06-28周顶辉王艳秋

装备制造技术 2010年3期
关键词:驱动程序内核调用

周顶辉,王艳秋

(辽宁工业大学通信与信息系统,辽宁 锦州 121000)

随着多媒体、网络技术的迅猛发展和后PC机时代的到来,USB摄像头的应用越来越广泛,例如远程监控、视频电话和视频会议等。摄像头由主控芯片和传感芯片组成,主控芯片负责图像采集、压缩以及和主机的通信。我们使用的是市面上常见的一款CMOS摄像头,主控芯片为台湾松翰科技(Sonix)公司的SN9C288CF6-1,传感芯片是ov7620。本文主要介绍USB协议驱动模块的分层结构、驱动程序的实现过程及设备的硬件初始化。

1 USB协议驱动程序的结构

USB设备驱动程序,主要由USB内核控制模块和设备驱动模块两部分构成。USB内核控制模块封装了支持USB主控制器及USB设备驱动的特定API,通过定义一系列的数据结构、宏和函数,来抽象化硬件,使得系统对各种设备的访问都采用统一的形式,做到了硬件无关。设备驱动模块,主要完成USB设备的注册注销、硬件初始化和为上层应用程序提供接口等工作。由于在Linux系统中,已经内置了USB内核控制模块,我们只需要编写设备驱动程序。

2 设备驱动程序的实现流程

2.1 注册和注销驱动设备

Linux USB驱动程序首先要做的,就是把包含设备信息和相关操作的结构体ov7620_driver注册到USB子系统里,该过程是调用usb_register函数来完成的,具体过程如下:

usb_ov7620_init(void)

{......

proc_ov7620_create();//建立PROC设备文件

if(usb_register(&ov7620_driver)<0)//调用usb_register函数完成注册

return-1;

info("ov7620 driver%s registered",version);

return 0;

};

其中ov7620_driver包含了USB摄像头的相关信息,并提供了当摄像头插入拔出时所对应的操作,结构如下:

static struct usb_driver ov7620_driver={

.name="ov7620",

.id_table=device_table,

.probe=ov7620_probe,

.disconnect=ov7620_disconnect

};

probe和disconnect是函数指针。当插入USB摄像头时,调用ov7620_probe()函数,主要用来检测VID和PID,看USB内核控制模块里有没有匹配的驱动,如果有向Linux的视频子系统注册,并将驱动实现的系统调用,挂到内核中:

ov7620_probe(struct usb_interface*intf,const struct usb_device_id*id)

{......

if((err_probe=spcaDetectCamera(ov7620))<0)//具体物理设备查找,匹配厂商号,设备号

{err("Devices not found!!");goto error;}

……

memcpy(ov7620->vdev,&ov7620_template,sizeof(ov7620_template));

//系统调用的挂接,在此将驱动实现的系统调用,挂到内核中

};

当摄像头从USB总线拔掉,设备指针会调用ov7620_disconnect()函数:

static void ov7620_disconnect(struct usb_interface*intf)

{……

if(ov7620->vdev)

video_unregister_device(ov7620->vdev);//注销video设备

};

2.2 上层应用接口模块

当设备插入USB总线时,系统会调用probe函数探测设备并把系统调用挂接到内核。上层应用程序在获取设备句柄以后,可以直接通过系统调用对设备进行操作,如read、write等。作为摄像头驱动不需要输出功能,因此在程序中没有实现write系统调用。数据结构如下:

static struct file_operations ov7620_fops={

.owner=THIS_MODULE,

.open=ov7620_open,//open功能

.release=ov7620_close,//close功能

.read=ov7620_read,//read功能

.mmap=ov7620_mmap,//内存映射功能

.ioctl=ov7620_ioctl,//文件信息获取

};

ov7620_open完成设备的打开和初始化,并初始化解码器模块。其具体实现如下:

static int ov7620_open(struct video_device*vdev,int flags)

{……

err=ov7620_init_source(ov7620);//初始化控制器和传感器芯片

err=ov7620_init_transfert(ov7620);//初始化URB(usb request block)包,启动摄像头,采用同步传输的方式传送数据

};

ov7620_close函数主要完成设备的关闭,ov7620_mmap和ov7620_read是应用程序读取数据的两个接口函数。ov7620_mmap通过remap_page_range函数实现内存映射,ov7620_read通过copy_to_user实现用户空间和内核空间的数据拷贝,只读取其中一帧大小的数据。

2.3 初始化传感器和控制器

在打开设备时,需要对硬件进行初始化。摄像头由两个主要的芯片组成,图像传感器芯片ov7620和桥接芯片SN9C102P。摄像头的结构框图如图1。桥接芯片提供了开放的源代码,里面提供了对传感器控制的接口函数,如sn9c102_i2c_write,sn9c102_i2c_read等。利用提供的接口函数我们就可以对ov7620的寄存器写值,完成传感器的初始化工作和图像采集控制,过程如下:

sn9c102_i2c_write (ov7620->dev,ov7620_sensor_init [i],8)//ov7630_sensor_init是传感器ov7620寄存器结构。

图1 摄像头的结构框图

3 驱动程序的移植和测试

在PC机上搭建交叉编译环境,系统配置为fedora 7,内核2.6.19,安装的交叉编译工具为arm-linux-gcc-3.4.1。编译环境建立以后,还需要配置Makefile文件,完成后只要在终端里执行make命令就可以生成驱动模块文件。然后通过超级终端下载到Te2440开发板上,用insmod命令加载驱动。在开发板上运行servfox,在PC机上通过spcaview就可以看到图像了。

4 结束语

本文对USB摄像头驱动程序的开发过程,进行了简单的介绍,并介绍了Makefile文件的内容。本文程序结构功能相对简单,在此基础上可以扩展出一个视频监控系统,或者进行图像处理方面的研究。

[1]Alessandro Rubini,Jonathan Corbet.Linux设备驱动程序[M].魏永明,骆 钢,姜 君译.北京:中国电力出版社,2002.

[2]刘春成.基于嵌入式Linux的USB摄像头驱动开发[J].计算机工程与设计,2007,(8):2-3.

[3]魏 武,杨坚锐.嵌入式Linux下USB摄像头驱动程序的开发[J].现代电子技术,2006,(11):3-4.

[4]孙天泽,袁文菊,张海峰.嵌入式设计及Linux驱动开发指南—基于ARM9处理器[M].北京:电子工业出版社,2005.

猜你喜欢

驱动程序内核调用
万物皆可IP的时代,我们当夯实的IP内核是什么?
强化『高新』内核 打造农业『硅谷』
核电项目物项调用管理的应用研究
基于嵌入式Linux内核的自恢复设计
Linux内核mmap保护机制研究
LabWindows/CVI下基于ActiveX技术的Excel调用
基于系统调用的恶意软件检测技术研究
利用RFC技术实现SAP系统接口通信
驱动程序更新与推荐
驱动程序更新与推荐