Linux攝像頭驅動學習之:(一)V4L2_框架分析


這段時間開始搞安卓camera底層驅動了,把以前的的Linux視頻驅動回顧一下,本篇主要概述一下vfl2(video for linux 2).

一. V4L2框架: video for linux version 2
虛擬視頻驅動vivi.c分析:
1.分配video_device
2.設置
3.注冊:video_register_device

vivi_init
    vivi_create_instance
        v4l2_device_register   // 不是主要, 只是用於初始化一些東西,比如自旋鎖、引用計數
        video_device_alloc
        // 設置
          1. vfd:
            .fops           = &vivi_fops,
            .ioctl_ops  = &vivi_ioctl_ops,
            .release = video_device_release,
          2.
            vfd->v4l2_dev = &dev->v4l2_dev;
          3. 設置"ctrl屬性"(用於APP的ioctl):
             v4l2_ctrl_handler_init(hdl, 11);
             dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
               V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
             dev->brightness = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
               V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
             dev->contrast = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
               V4L2_CID_CONTRAST, 0, 255, 1, 16);                       
        video_register_device(video_device, type:VFL_TYPE_GRABBER, nr)
            __video_register_device
                vdev->cdev = cdev_alloc();
                vdev->cdev->ops = &v4l2_fops;
                cdev_add
               
                video_device[vdev->minor] = vdev;

          if (vdev->ctrl_handler == NULL)
           vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
               
               

分析vivi.c的open,read,write,ioctl過程
1. open
app:     open("/dev/video0",....)
---------------------------------------------------
drv:     v4l2_fops.v4l2_open
            vdev = video_devdata(filp);  // 根據次設備號從數組中得到video_device
            ret = vdev->fops->open(filp);
                        vivi_ioctl_ops.open
                            v4l2_fh_open

2. read
app:    read ....
---------------------------------------------------
drv:    v4l2_fops.v4l2_read
            struct video_device *vdev = video_devdata(filp);
            ret = vdev->fops->read(filp, buf, sz, off);

3. ioctl
app:   ioctl
----------------------------------------------------
drv:   v4l2_fops.unlocked_ioctl
            v4l2_ioctl
                struct video_device *vdev = video_devdata(filp);
                ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
                            video_ioctl2
                                video_usercopy(file, cmd, arg, __video_do_ioctl);
                                    __video_do_ioctl
                                        struct video_device *vfd = video_devdata(file);
                                        根據APP傳入的cmd來獲得、設置"某些屬性"v4l2_ctrl_handler的使用過程:
    __video_do_ioctl
        struct video_device *vfd = video_devdata(file);     case VIDIOC_QUERYCTRL:
     {
      struct v4l2_queryctrl *p = arg;
   
      if (vfh && vfh->ctrl_handler)
       ret = v4l2_queryctrl(vfh->ctrl_handler, p);
      else if (vfd->ctrl_handler)  // 在哪設置?在video_register_device
       ret = v4l2_queryctrl(vfd->ctrl_handler, p);
                   // 根據ID在ctrl_handler里找到v4l2_ctrl,返回它的值...}
                                                
                                                  

[18721.327983] usb 2-1: USB disconnect, address 4
[18724.929301] usb 2-1: new full speed USB device using uhci_hcd and address 5
[18725.196200] usb 2-1: configuration #1 chosen from 1 choice
[18725.204999] uvcvideo: Found UVC 1.00 device <unnamed> (1b3b:2977)
[18725.222065] input: UVC Camera (1b3b:2977) as /devices/pci0000:00/0000:00:07.2/usb2/2-1/2-1:1.0/input/input7
[25252.578719] usb 2-1: USB disconnect, address 5

由以上usb攝像頭插入的dmesg打印信息,搜索UVC關鍵字得到相關代碼:uvc.driver.c ->uvc_driver結構體->video_register_device方法。

 

二、如何寫v4l2驅動:

 ①構造、設置、注冊: v4l2_device : v4l2_device_register, v4l2_device

 ②分配:video_device, video_device_alloc

 ③設置: a. vfd->v4l2_dev

     b. vfd: .fops = ***.open/read/write  <-上層app調用

          .ioctl_ops  <-驅動程序 v4l2_fops {open,read,write,"ioctl"}

       c.APP通過ioctl來設置,獲得亮度 等信息。

    驅動程序: v4l2_ctrl : 屬性。

       v4l2_ctrl_handler : 管理 ===>(1)初始化:v4l2_ctrl_handler_init

                        (2)設置:v4l2_ctrl_new_std , v4l2_ctrl_new_custom ,設置創建v4l2_ctrl並加入鏈表。

                          (3)跟vdev關聯: v4l2_dev.ctrl_handler = hdl  

                          video_dev -> v4l2_dev.

     

具體驅動代碼的編寫將在下篇繼續....


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM