嵌入式Linux下USB摄像头驱动程序开发

摘要:介绍了嵌入式Linux系统中USB设备驱动程序开发的基本原理,通过分析USB驱动程序开发的程序框架和重要数据结构,实现了USB摄像头的嵌入式Linux驱动程序,并在S3C2440的平台上实现了图像采集。

关键词:嵌入式Linux;驱动程序;USB摄像头

中图分类号:TP319文献标识码:A文章编号:1672-7800(2013)001-0093-03

0引言

在我们今天的生活中,摄像头广泛应用于视频聊天以及视频实时监控中。世面上摄像头种类繁多,其中USB接口的摄像头价格便宜,性能也很高,因而更适宜推广使用。

主控和传感芯片是摄像头的重要部件。主控芯片负责图像采集、压缩以及与主机进行信息传递。通过摄像头进行图像采集,同时摄像头与嵌入式模块连接,通过嵌入式模块上的无线网卡把采集的图像发送出去。嵌入式模块上使用的是Linux系统,嵌入式Linux系统的源代码方便开发,内核运行稳定并具有可裁减性,对大多数硬件都可以支持,是嵌入式系统领域最重要的操作系统。

本文重点分析了USB摄像头驱动模块的整体结构及驱动程序的实现。

1Linux设备驱动的基本概念

设备驱动程序是一种可以使计算机和设备进行通信的特殊程序,可以说相当于硬件的接口,操作系统只有通过这个接口,才能控制硬件设备的工作,假如某设备的驱动程序未能正确安装,便不能正常工作。应用程序把硬件设备看作是一个设备文件,这样它对硬件设备进行操作就可以像操作普通文件一样。设备驱动程序被看作是内核的构成部分,其完成的功能有:设备的初始化和释放、数据从内核到硬件、从硬件读取数据、接收应用程序传送给设备文件的数据,返回其请求的数据。

Linux内核对外围设备控制操作是通过驱动程序来完成,所以每个设备都需要有驱动程序,否则设备将无法正常工作。

4结语

对中国象棋的文化底蕴进行研究,设计并制作象棋多媒体学习软件,内容涉及象棋文化、口诀、技巧、各棋子基本走法、经典棋局、大师风采等方面,能够丰富人们的精神生活,普及传统文化,发扬中华文明。

象棋多媒体学习软件界面美观,多种媒体效果丰富,交互性强,内容易扩充。适用于不同年龄段、不同就学阶段、不同工作岗位的人群,适用范围广。既可用于象棋自学,也可用于象棋培训。

目前,象棋软件主要为实战型,以博弈为主,面向的对象为精通象棋棋艺的人群,象棋多媒体学习软件面向的对象为普通大众,操作简单,使用者可以通过该软件,熟悉象棋文化,掌握下棋方法和技巧,了解象棋大师和经典棋局,更易于普及和推广中国象棋及其文化,促进象棋竞技的发展。

参考文献:

[1]李松福.象棋史话[M].北京:人民体育出版社,1981.

[2]郭志菊,李树新.象棋文化熟语语义解构[J].汉字文化,2002(2).

[3]丁桂兴.象棋运动好处多[J].教育与管理,2009(12).

[4]刘殿中.象棋实战指南/象棋新编教程[M].北京:北京体育大学出版社,2003.

[5]程明松.中国象棋谱大全[M].成都:蜀蓉棋艺出版社,2003.

[6]李京文.Authorware案例教程[M].北京:中国水利水电出版社,2010.

[7]缪亮.多媒体技术实用教程[M].北京:清华大学出版社,2007.

(责任编辑:孙娟)

2Linux2.6下USB摄像头驱动的实现

2.1USB驱动程序框架

Linux系统里,每一个完备的USB驱动程序都是由USBCore、USB主控制器驱动(HCD)和USB设备驱动3部分组成,其层次关系如图1所示。其中,USBcore完成一些重要的功能,它初始化整个USB系统,申请structbus_typeusb_bus_type结构体,然后扫描USB总线,并为连接的USB设备分配一个structdevice。主机控制器驱动(HCD)必须位于USB软件的最底层,HCD提供主机控制器硬件的抽象,隐藏硬件的细节,在主机控制器之下是物理的USB及所有与之连接的USB设备。而HCD只对USBcore负责。USBcore将用户的请求映射到相关的HCD,用户不能直接访问HCD。

图1USB子系统各模块层次关系

2.2USB摄像头驱动程序编写

驱动程序的编写是要为应用程序提供其可调用的open、read、write、ioctrl。在驱动程序中,依据设备功能的要求对file_operations的函数实现尤为重要,在驱动程序初始化时,file_operations的变量会注册到系统中去,file_operations提供了许多接口,不需要的就初始化为NULL。对设备进行任何操作,file_operations中的函数指针都会被相应地调用。

本USB驱动开发是以LinuxKernel源码中usb_skeleton.c提供的USB驱动程序为原型,编出的一个USB设备的驱动。

在LinuxUSB子系统里注册是USB驱动程序完成的第一个步骤,同时这个驱动程序支持的设备类型在此时确定,支持的设备从系统插入或拔出时的动作也同时规定好。全部这些信息都被传送到USB子系统中。下面举例说明USB摄像头的注册和注销:

structusb_driverabc_driver={

#ifLINUX_VERSION_CODE

.owner=THIS_MODULE,

#endif

.name="abc",

.id_table=device_table,

.probe=abc_probe,

.disconnect=abc_disconnect

};

intinitusb_abc_init(void)

{……

abc_create();

……

if(usb_register(&abc_driver)<0)

return-1;

……

}

void__exitusb_abc_exit(void)

{……

abc_destroy();

……}

module_init(usb_abc_init);

module_exit(usb_abc_exit);

在abc_driver结构中,字符串name表明了驱动程序。probe和disconnect是函数指针。

当系统检测到USB摄像头插入时系统会检测它的VendorID和ProductID,如果与驱动模块的注册内容匹配,则调用abc_probe()函数,abc_probe()函数向视频子系统注册,生产厂商号码(VendorID)和产品号(ProductID)在驱动模块加载初始化的时候就向系统注册了。参数dev表明设备信息,参数id则表明USB设备的生产厂商及产品号。如果USB设备通过了probe函数的验证,则usbvideo_RegisterVideoDevice()函数调用向videodev系统注册:

intabc_probe(structusb_interface*intf,conststructusb_device_id*id)

{

……

/*Initvideostuff*/

abc->vdev=video_device_alloc();

if(!abc->vdev)

gotoerror;

memcpy(abc->vdev,&abc_template,sizeof(abc_template));

……}

其中abc_template设备文件操作函数

Staticstructvideo_deviceabc_template={

.name="GSPCAUSBCamera",

.vfl_type=VID_TYPE_CAPTURE,

#ifLINUX_VERSION_CODE<=KERNEL_VERSION(2,6,23)

.hardware=VID_HARDWARE_GSPCA,

#endif

.fops=&abc_fops,

.release=video_device_release,

.minor=-1,};

staticstructv4l2_file_operationsabc_fops={

.owner=THIS_MODULE,

.open=abc_open,

.release=abc_close,

.read=abc_read,

.mmap=abc_mmap,

.ioctl=abc_ioctl,

.unlocked_ioctl=video_ioctl2,

};

其中abc_open()完成设备的打开和初始化。部分代码如下:

staticintabc_open(structvideo_device*vdev,intflags)

{……

abc_alloc(abc);

abc_init_source(abc);

abc_initDecoder(abc);

abc_init_isoc(abc);

……}

abc_read()调用函数copy_to_user(buf,frame->data,count)将数据由内核空间传送到进程的用户空间。代码如下:

staticlongabc_read(structvideo_device*dev,char*buf,unsignedlongcount,intnoblock)

{……

l=copy_to_user(buf,frame->data,count);

……}

当拔掉摄像头,abc_disconnect()函数会调用:

staticvoidabc_disconnect(structusb_device*dev,void*ptr)

{……

video_uegister_device(abc->vdev);

abc->dev=NULL;

up(&abc->lock);

/*Freethememory*/

if(abc&&!abc->user){

spca5xx_dealloc(abc);

kfree(abc);

abc=NULL;

……};

3摄像头驱动的移植与测试

将该驱动移植到友善之臂S3C2440开发板上,该开发板是基于S3C244X处理器的开发平台,同时具有串口、USB接口、网口、JTAG接口等较全面的接口,可以在Linux下工作,便于调试和测试。

本文摄像头的测试程序是基于Video4Linux完成USB摄像头图像和视频获取,其中Video4Linux(简V4L)是Linux中关于视频设备的内核驱动,它为针对视频设备的应用程序编程提供一系列接口函数,这些视频设备包括现今市场上流行的TV卡、视频捕捉卡和USB摄像头等。

编程的思想如下:①打开摄像头;②初始化摄像头状态;③进行视频采集;④对采集的视频进行处理;⑤关闭摄像头。

在主函数main()中,open()函数打开摄像头设备,init_videoIn()函数初始化摄像头设备并且设置图像帧的参数,grab()函数中采用read()系统调用获得图像数据,并把获得的数据以文件形式保存起来,close_v4l()函数关闭USB摄像头设备。下面给出测试程序的基本架构:

intmain(intargc,char**argv){

……

vd->fd=open(vd->videodevice,O_RDWR);

init_videoIn(structvdIn*vd,char*device,intwidth,int

height,intformat,intgrabmethod);

……

grab();

……

close_v4l(&videoIn);

}

4结语

本文全面阐述了嵌入式Linux系统中USB子系统的架构和基本工作原理,详细介绍了USB摄像头驱动程序的开发过程。该摄像头驱动经过测试运行稳定,可用于实际应用。

参考文献:

[1]毛德操,胡希明.Linux内核源代码情景分析[M].杭州:浙江大学出版社,2001.

[2]魏永明,骆刚,姜军.Linux设备驱动程序[M].北京:中国电力出版社,2002.

[3]探矽工作室.嵌入式系统开发圣经[M].北京:中国青年出版社,2002.

[4]杜春雷.ARM体系结构与编程[M].北京:清华大学出版社,2003.

[5]马忠梅,马广云,徐英慧.ARM嵌入式处理器结构与应用基础[M].北京:北京航空航天大学出版社,2002.

[6]倪继利.Linux内核分析及编程[M].北京:电子工业出版社,2005.

[7]万健,冯华,任彧.嵌入式系统中USB块数据传输的设计与实现[J].计算机工程与设计,2005(11).

[8]李光明,姚斌.基于ARM7和嵌入式Linux系统下USB接口的设计[J].计算机工程与设计,2006(6).

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

[10]Compaq,HewlettPackard,Intel,Lucent,Microsoft,NEC.Philipsuniversalserialbusspecificatioevision2.0[S].2000.

[11]SAMSUNG.S3C2410A200MHzand266MHz32bitRISCmicroprocessoruser"smanualrevision1.0[Z].2004.

(责任编辑:孙娟)

推荐访问:嵌入式 程序开发 摄像头驱动 USB Linux