USB摄像头驱动的移植 linux

 

USB摄像头驱动的移植
一、驱动程序中的重要数据结构
    Linux系统下,USB设备驱动程序完全符合通用设备驱动的准则,不同的是Linux操作系统中有一个叫做“USB CORE”的子系统,它的作用是提供支持USB设备驱动程序的API(应用编程接口)和USB的主机驱动程序。它提供了许多数据结构、宏定义和功能函数来对硬件或设备进行支持。

    在Linux下编写USB设备的驱动程序从严格意义上讲,就是使用这些USB核心的子系统定义的数据结构、宏和函数来编写数据的处理功能。
    USB核子系统定义的usb driver结构是与设备驱动程序开发直接相关的核心数据结构。usb driver定义在内核源代码的中。函数probe和disconnect是结构中最重要的两个函数


1、probe函数
    当驱动程序向子系统注册后,插入一个新的USB设备后,总是要自动进入该函数进行设备驱动程序查找。驱动程序会为这个新加入系统的设备向内部的数据结构建立一个新的实例

   在这个函数中,参数dev指定了包含设备说明的内容。而参数interface指明了该设备所含接口的数目。通常情况下,probe函数执行一些功能,来检测新加入的USB设备硬件中的生产厂商和产品定义以及设备所属的类或子类定义是否与驱动程序相符,若相符,再比较接口的数目与本驱动程序支持设备的接口数目是否相符。一般在probe函数中也会解析USB设备的说明,从而确认新加入的USB设备会使用这个驱动程序


2、disconnect函数

    当一个USB设备从系统拔掉后,为这个设备服务的设备驱动程序的disconnect函数会自动被调用。在该函数中参数dev指定了设备的内容,参数drv_context返回由probe函数注册的结构driver context的指针。在执行了disconnect函数后,所有为USB设备分配的数据结构,内存空间都会被释放。
   本项目驱动程序spca5xx用两个函数调用spca5xx._probe和spca5xx_disconnect来支持USB设备的即插即用功能。如下:
static struct usb_driver spca5xx_driver=

{
"spca5xx",
spca5xx_probe, //注册设备自我侦测功能
spca5xx_disconnect,//注册设备自我断开功能
{NULL,NULL}
);


二、驱动程序模块
    我们以成功移植到系统平台的中星微USB摄像头驱动程序spac5xx为例来说明驱动程序的构架。
    驱动程序spac5xx是按照标准的USB VIDEO设备的驱动框架编写(其具体的驱动框架可参照/usr/src/linux/drivers/usb/usbvideo.C文件),采用了显式的模块初始化和卸载函数,即调用module init函数来初始化一个模块,并在卸载时调用moduel exit函数。
   整个源程序由四个主体部分组成:初始化模块卸载模块,上层软件接口模块,数据传输模块。其具体实现如下:
  1、初始化模块:
module——init(usb_spca5xx_init);
static int—init usb_spca5xx_init(void)
{
#ifdef CONFIG—PROe-FS
proc_spca50x_create();//建立PROC设备文件
#endif净CONFIG—PROC—FS^|
if(usbregister(&spca5xx_driver)<0)//注册USB设备驱动
retum-1;
info(”spca5xx driver%s registered”,version);

return O;
)
  2、卸载模块:
module——exit(usb_spca5xx_exit);
tatic void—exit usb_spca5xx_exit(void)
{
usb_deregister(&spca5xx_driver);//注销USB设备驱动
info(”driver spca5xx deregistered”);
#ifdefCONFIG_PROC_FS
proe_spca50xdestroy O;//撤消PROC设备文件
#endif/*CONFIG_PROC_FS*/
}

3、上层软件接口模块:
    该模块通过fileoperations数据结构实现设备的系统调用。由于摄像头的功能在于数据采集,不需要向摄像头输出,因此没有实现write系统调用。其关键的数据结构如下:

static struct file_operations spca5xx fops={
.owner=TmS_MODULE,
.open=spca5xxopen,//open功能
.release=spca5xx_elose,//close功能
.read=spcaSxxread,//read功能
.mmap=spca5xx_mmap,∥内存映射功能
.ioctl=spca5xx_ioctl,//文件信息获取
.1lseek=no llseek,//文件定位功能未实现
);


4、数据传输模块:
源程序采用tasklet来实现同步快速传递数据,并通过spcadecode.C上的软件解码模块实现图形信息的解码。在spcaopen函数中,子函数spcaS0x_init_iSOC实现数据采集功能。当设备被打开时,同步传输数据也开始,并通过spca50xmove_data函数将数据传递给驱动程序,驱动程序通过轮询的办法实现对数据的访问。

三、驱动程序移植过程
    Linux下的设备驱动程序可以按照两种方式进行编译,一种是直接静态编译成内核的一部分,另一种则是编译成可以动态加载的模块

   如果编译进内核的话,会增加内核的大小,还要改动内核的源文件,不利于调试,所以本项目摄像头驱动使用模块方式加载。在系统平台上安装USB摄像头驱动,首先把USB控制器驱动模块静态编译进内核,使平台中支持USB接口,再在需要使用摄像头采集时使用insmode命令动态加载其驱动模块(spca5xx.o)。具体步骤如下:
1、下载spca5xx一20060402.tar.gz解压到当前工作目录。
2、在/spcaSxx.20060402下修改Makefile如下:
(1)KINCLUDE=/arm/yc/linux/include注:/arm/yc/linux为linux源码存放目录
(2)#MODULE_INSTALLDIR=/Iib/modules/$(KERNEL-yERSION)/kernel/drivers/usb/
(3)CC=arm_linux_gcc
(4)LD=ILrlTI··linux··ld
(5)#CFLAGS+=-mpreferred—stack-boundary=2
3、主机上make编译生成可加载驱动文件spca5xx.0。
4、将spca5xx.o烧写到开发板/web目录下
5、在开发板上插入摄像头,终端输入#cd web,#insmod spca5xx.0加载驱动成功。
从驱动程序可以得到摄像头的信息:采用Vimicro Zc301图像处理芯片,JPEG图像压缩输出方式,感光端采用M1360,最大分辨率640X480。
6、查看/dev下出现/dev/v41/videoO,因为采集图象调用内核的V4L函数,需要建立一个连接/dev/vidoO,方法为#In.s/dev/v41/videoO/dev/videoO
7、/dev/videoO表示USB摄像头设备文件。应用程序打开设备文件,通过调用文件操
作函数即可读取视频图像数据

你可能感兴趣的:(linux移植)