Linux USB 驱动开发实例(一) —— USB摄像头驱动实现源码分析

  Spac5xx的实现是按照标准的USB VIDEO设备的驱动框架编写(其具体的驱动框架可参照/usr/src/linux/drivers/usb/usbvideo.c文件),整个源程序由四个主体部分组成:

设备模块的初始化模块和卸载模块,上层软件接口模块,数据传输模块


具体的模块分析如下:

 一、初始化设备模块

        该驱动采用了显式的模块初始化和消除函数,即调用module_init来初始化一个模块,并在卸载时调用moduel-exit函数

        其具体实现如下: 

1、模块初始化:

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. module_init (usb_spca5xx_init);   
  2.   
  3. static int __init  usb_spca5xx_init (void)   
  4. {    
  5. #ifdef CONFIG_PROC_FS                       
  6.     proc_spca50x_create ();//建立PROC设备文件   
  7. #endif /* CONFIG_PROC_FS */      
  8.     if (usb_register (&spca5xx_driver) < 0) //注册USB设备驱动      
  9.         return -1;      
  10.     info ("spca5xx driver %s registered", version);     
  11.     return 0;   
  12. }  

2、模块卸载:

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. module_exit (usb_spca5xx_exit);   
  2.   
  3. static void __exit  usb_spca5xx_exit (void)   
  4. {      
  5.     usb_deregister (&spca5xx_driver); //注销USB设备驱动     
  6.     info ("driver spca5xx deregistered");   
  7. #ifdef CONFIG_PROC_FS      
  8.     proc_spca50x_destroy ();//撤消PROC设备文件   
  9. #endif /* CONFIG_PROC_FS */   
  10. }   


关键数据结构 USB驱动结构,即插即用功能的实现 

[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. static struct usb_driver spca5xx_driver = {          
  2.     "spca5xx",           
  3.     spca5xx_probe, //注册设备自我侦测功能          
  4.     spca5xx_disconnect,//注册设备自我断开功能          
  5.     {NULL,NULL}   
  6. };  

用两个函数调用spca5xx_probe 和spca5xx_disconnect来支持USB设备的即插即用功能:

a -- spca5xx_probe 具体实现如下:
[cpp]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. static void * spca5xx_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)   
  2. {      
  3.     struct usb_interface_descriptor *interface;          //USB设备接口描述符   
  4.     struct usb_spca50x *spca50x;                    //物理设备数据结构     
  5.     int err_probe;     
  6.     int i;      
  7.     if (dev->descriptor.bNumConfigurations != 1)        //探测设备是不是可配置       
  8.         goto nodevice;     
  9.     if (ifnum > 0)       
  10.         goto nodevice;      
  11.     interface = &dev->actconfig->interface[ifnum].altsetting[0];    
  12.     MOD_INC_USE_COUNT;      
  13.     interface = &intf->altsetting[0].desc;     
  14.     if (interface->bInterfaceNumber > 0)       
  15.         goto nodevice;      
  16.     if ((spca50x = kmalloc (sizeof (struct usb_spca50x), GFP_KERNEL)) == NULL) //分配物理地址空间       
  17.     {          
  18.         err ("couldn't kmalloc spca50x struct");         
  19.         goto error;       
  20.     }      
  21.   
  22.     memset (spca50x, 0, sizeof (struct usb_spca50x));     
  23.     spca50x->dev = dev;      
  24.     spca50x->iface = interface->bInterfaceNumber;      
  25.     if ((err_probe = spcaDetectCamera (spca50x)) < 0)       //具体物理设备查找,匹配厂商号,设备号(在子程序中)         
  26.     {          
  27.         err (" Devices not found !! ");         
  28.         goto error;       
  29.     }      
  30.     PDEBUG (0, "Camera type %s ", Plist[spca50x->cameratype].name)  
  31.     for (i = 0; i < SPCA50X_NUMFRAMES; i++)        
  32.         init_waitqueue_head (&spca50x->frame[i].wq);     //初始化帧等待队列       
  33.         init_waitqueue_head (&spca50x->wq);            //初始化驱动等待队列     
  34.   
  35.     if (!spca50x_configure (spca50x))                  //物理设备配置(主要完成传感器侦测和图形参数配置),主要思想是给控制寄存器写值,读回其返回值,以此判断具体的传感器型号       
  36.     {          
  37.         spca50x->user = 0;          
  38.         init_MUTEX (&spca50x->lock);                  //信号量初始化         
  39.         init_MUTEX (&spca50x->buf_lock);          
  40.         spca50x->v4l_lock = SPIN_LOCK_UNLOCKED;         
  41.         spca50x->buf_state = BUF_NOT_ALLOCATED;       
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值