上一篇文章中,已经介绍了v4l2_open、v4l2_read、v4l2_write的调用过程,相对于v4l2_ioctl,它们是比较简单的。下面来分析v4l2_ioctl。注意在这里还是分析以vivi.c为例,进行分析。

app:          ioctl

---------------------------------------------------------------------------

drv:           v4L2_fops.unlocked_ioctl

      .v4L2_ioctl

        vdev = video_devdata(filp);

        vdev->fops->unlocked_ioctl(filp, cmd, arg);//调用具体设备提供的unlocked_ioctl,因为本篇文章是以vivi.c为例进行分析,.unlocked_ioctl = video_ioctl2

          video_ioctl2

            video_usercopy(file, cmd, arg, __video_do_ioctl)

              __video_do_ioctl

video_ioctl2 

  long video_ioctl2(struct file *file,unsigned int cmd, unsigned long arg)
  {
    //根据命令cmd的不同,调用__video_do_ioctl,将数据拷贝到内核空间

    return video_usercopy(file, cmd, arg, __video_do_ioctl);
  }

__video_do_ioctl

  //以次设备号为下标,从video_device[]中取出对应的video_device,此处就是vivi_template

  struct video_device *vfd = video_devdata(file);

  //获取vivi_template的ioctl_ops

  const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;

  ---------- 

  switch (cmd) {

    /* --- capabilities ------------------------------------------ */

    case VIDIOC_QUERYCAP://cmd命令
    {
      //v4l2设备的能力结构体

      struct v4l2_capability *cap = (struct v4l2_capability *)arg;

      if (!ops->vidioc_querycap)
        break;

      cap->version = LINUX_VERSION_CODE;

      //根据不同的cmd,调用到了ioctl_ops中的vidioc_querycap
      ret = ops->vidioc_querycap(file, fh, cap);

      ----

      break

    }

现总结一下这个过程:

1、video_device被设置成了vivi_template  //在函数vivi_create_instance中被设置

2、vdev->cdev->ops = &v4l2_fops; //在函数__video_register_device中被设置

3、video_device[vdev->minor] = vdev;//在函数__video_register_device中被设置

当用户空间调用ioctl的时候,v4l2_fops的v4l2_ioctl将被调用;

在v4l2_ioctl中,vivi_template->fops->unlocked_ioctl(filp, cmd, arg) 即video_ioctl2函数会被调用;

在video_ioctl2中,__video_do_ioctl函数会被调用;

在__video_do_ioctl中,根据cmd来调用vivi_template中的vivi_ioctl_ops结构体中对应的函数。

              

初识v4l2(五)-------v4l2_ioctl浅析的更多相关文章

  1. (二) V4L2引入(含浅析UVC)

    title: V4L2引入(含浅析UVC) date: 2019/4/23 19:00:00 toc: true --- V4L2引入(含浅析UVC) 基本框架 V4L2全名是video for li ...

  2. 初识V4l2(二)-------浅析video_register_device

    在V4l2初识(一)中,我们已经知道当插上一个摄像头的时候,在uvc_driver.c中最终会调用函数video_register_device函数.接下来我们就简要分析这个函数做了哪些事情,揭开其神 ...

  3. 初识v4l2(四)-------v4l2_open、v4l2_read、v4l2_write浅析

    原文:https://blog.csdn.net/leesagacious/article/details/49995729 1.app:     open("/dev/video0&quo ...

  4. V4l2初识(七)-----------浅析app获取虚拟摄像头数据的过程

    继续分析数据的获取过程: 1.请求分配的缓冲区: ioctl(4,VIDIOC_REQBUFS) vidioc_reqbufs 2.查询和映射缓冲区   ioctl(4,VIDIOC_QUERYBUF ...

  5. 初识V4L2(三)-------分析vivi.c 虚拟视频驱动

    1.分配video_device结构体 2.设置 3.注册  video_register_device 分析vivi.c: vivi_init( )//入口函数 vivi_create_instan ...

  6. 初识V4L2(一)

    V4L2驱动框架概述 V4L2(video for linux two)是linux为视频设备提供的一套标准接口.它也属于字符设备驱动程序. 首先回顾普通字符设备驱动程序的写法: app :      ...

  7. 初识Haskell 五:自定义数据类型和类型类

    对Discrete Mathematics Using a Computer的第一章Introduction to Haskell进行总结.环境Windows 自定义数据类型 data type de ...

  8. Python正则表达式初识(五)

    正则表达式的内容很丰富,今天小编继续给大家分享Python正则表达式的基础知识.今天要给大家的讲的特殊字符是竖线“|”.竖线“|”实质上是一个或的关系. 1.直接上代码演示,比方说我们需要匹配一个字符 ...

  9. pandas 初识(五)

    1. 如何实现把一个属性(列)拆分成多列,产生pivot,形成向量信息,计算相关性? 例: class_ timestamp count 0 10 2019-01-20 13:23:00 1 1 10 ...

随机推荐

  1. Redis windows版本资源与安装

    这里提供一个windows版本的Redis百度云资源 链接: https://pan.baidu.com/s/19JY_d_J87n98OeAHK9qI4A 密码: d6dq 1,GitHub下载地址 ...

  2. C++ class内的 ++ 重载,左++,右++,重载示例。

    #include <iostream> // overloading "operator ++ " inside class // ++ 是一元操作符 //////// ...

  3. lua 2 变量

    变量在使用前,必须在代码中进行声明,即创建该变量. 编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,用于存储变量的值. Lua 变量有三种类型:全局变量.局部变量.表中的域. Lua 中的 ...

  4. 《Zabbix》

    https://github.com/itnihao/zabbix-rpm https://github.com/itnihao/zabbix-book 一.zabbix支持的主要监控方式: zabb ...

  5. leetcode347. 前 K 个高频元素

    题目最终需要返回的是前 kk 个频率最大的元素,可以想到借助堆这种数据结构,对于 kk 频率之后的元素不用再去处理,进一步优化时间复杂度. 具体操作为: 借助 哈希表 来建立数字和其出现次数的映射,遍 ...

  6. 为什么用时序电路实现CPU

    时序电路 我们带着如下疑问来看时序电路: 1.为什么CPU要用时序电路,时序电路与普通逻辑电路有什么区别. 2.触发器.锁存器以及时钟脉冲对时序电路的作用是什么,它们是如何工作的. 带着这两个问题,我 ...

  7. AtCoder Grand Contest 036

    Preface 这篇已经鸽了好久的说,AGC037都打完了才回来补所以题目可能都记不大清楚了,如有错误请指正 这场感觉难度远高于上一场,从D开始就不会了,E没写(看了题解都不会写),F就是抄曲明姐姐的 ...

  8. Kubernetes容器集群管理环境 - Node节点的移除与加入

    一.如何从Kubernetes集群中移除Node比如从集群中移除k8s-node03这个Node节点,做法如下: 1)先在master节点查看Node情况 [root@k8s-master01 ~]# ...

  9. 简明了解apply()和call()

    apply()和call()都是ES6语法的,并且都是函数的方法. function foo() { alert(this.name) } var obj = { name: '小明' } foo() ...

  10. 发布TS类型文件到npm

    最近发布了@types/node-observer包到npm,这里记录下发布过程 TS类型文件的包名通常以@types开头,使用npm publish发布以@types开头的包时需要使用付费账号.   ...