Linux摄像头V4L2驱动框架分析1

学习V4L2(V4L2:vidio for linux version 2)摄像头驱动框架,需要分析vivi.c(虚拟视频硬件相关)驱动源码程序,

vivi.c(虚拟视频驱动程序的分析)

https://download.csdn.net/my

通过分析vivi.c结构如下

vivi_init

   -->vivi_create_instance

        -->v4l2_device_register   // 不是主要, 只是用于初始化一些东西,比如自旋锁、引用计数

                 vfd = video_device_alloc(); //分配video_device结构体

             1.  *vfd = vivi_template; // 设置

              .fops           = &vivi_fops,
              .ioctl_ops    = &vivi_ioctl_ops,
              .release      = video_device_release,

     2.  vfd->v4l2_dev = &dev->v4l2_dev;

     3.  设置"ctrl属性"(用于APP的ioctl):(设置ctrl的属性让ioctl调用或者使用例如亮度等在驱动程序中抽象出来一个结构体 v4l2_ctrl,每个Ctrl对应其中的一项(音量、亮度等等)v4l2_ctrl_handler来管理他们)
               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);      

    4. video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);  //注册

       --> __video_register_device(vdev, type, nr, 1, vdev->fops->owner);

         -->vdev->cdev = cdev_alloc();  (v4l2.dev.c程序中)

           vdev->cdev->ops = &v4l2_fops;

           cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);

vivi.c的open,read,write,ioctl过程

1)open

app:     open("/dev/video0",....)向下层调用
-------------------------------------------------------------------
drv:     v4l2_fops.v4l2_open
           vdev = video_devdata(filp);  // 根据次设备号从数组中得到video_device

       return video_device[iminor(file->f_path.dentry->d_inode)];

   if (vdev->fops->open)     //如果有open函数
      if (video_is_registered(vdev))
        ret = vdev->fops->open(filp);//调用open 函数
          调用vivi.c 里的v4l2_fh_open函数

2)read

app:     read("/dev/video0",....)向下层调用
-------------------------------------------------------------------

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

       调用vivi.c 里的vivi_read
3)ioctl
app:   ioctl 
----------------------------------------------------
drv:   v4l2_fops.unlocked_ioctl => v4l2_ioctl
                struct video_device *vdev = video_devdata(filp);
             if (video_is_registered(vdev))
       ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
                       调用vivi.c 里的video_ioctl2
                                video_usercopy(file, cmd, arg, __video_do_ioctl); //从用户空间把用户的命令cmd复制进来,调用__video_do_ioctl
                                    __video_do_ioctl
                                        struct video_device *vfd = video_devdata(file); //根据次设备号从数组中得到video_device
                                        switch (cmd) { .....     // 根据APP传入的cmd来获得、设置"某些属性"

V4L2驱动架构(通过上面的分析)

通过V4L2驱动框架知道如何编写V4L2驱动

1. 分配、设置、注册:v4l2_device --》 v4l2_device_register()(辅助作用,提供自旋锁、引用计数等功能)

2. 分配一个video_device:video_device_alloc()

3. 设置

1)vfd->v4l2_dev  

2)  .fops             设置vfd的fops 里的open、read、write 被上层调用
  .ioctl_ops      设置属性被上层调用    

3)注册:video_register_device()

4. 接下来,应用层App可以通过ioctl来设置(获得)亮度等某些属性,在驱动程序里,谁来接收、存储、设置到硬件(提供这些信息)?

 在驱动程序中抽象出来一个结构体v4l2_ctrl,每个Ctrl对应其中的一项(音量、亮度等等);

 v4l2_ctrl_handler来管理他们,在vivi.c的vivi_create_instance函数中:

  1.初始化
    v4l2_ctrl_handler_init
  2.设置
    v4l2_ctrl_new_std
    v4l2_ctrl_new_custom
    这些函数就是创建各个属性,并且放入v4l2_ctrl_handler的链表
  3.跟vdev关联
    dev->v4l2_dev.ctrl_handler = hdl;

 

 

 

 

 

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值