​ v4l2框架由4个主要的部分(数据结构)组成:
v4l2_devices(包括v4l2_subdev) :v4l2_device管理所有的设备
media_device : meida_device框架管理运行时的pipeline
videobuf2:videobuf存储缓冲的数据
controls :controls包含主要控制接口

一 硬件

二 软件

2.1 v4l2驱动框架

2.1.1 v4l2驱动框架简述
2.1.2 v4l2驱动核心结构体

2.2 v4l2核心驱动框架

2.3 v4l2下层接口驱动框架


一 硬件

常用的电脑摄像头是USB接口,主流的智能手机摄像头是MIPI接口,树莓派等硬件却常常为CSI接口本项目是智能手机 camera采用MIPI接口,电路框架以及电路图如下:


camera传感器分前后两个,分别是前置摄像头和后置摄像头,两个camera都挂载在i2c总线上

二 软件

回顾:
Linux中,所有的外设都被当作“文件”处理,就是我们常说的“设备文件”,可以像访问普通文件一样访问外设,对外设进行读写操作。linux驱动按照面向对象的不同被划分为“面向字符设备”,“面向块设备”,“面向网络设备”三大类设备。字符设备和块设备驱动在文件系统中形成类似文件的“虚拟文件”,即节点(node),在/dev目录下统一处理,系统调用open read write等进行操作,而面向网络接口的设备不会被映射到文件系统中,被分配的设备名类似eth0等等,他的驱动调用方式也不是open等。

v4l2驱动框架概述:
V4L2(video for linux two)是linux为视频设备提供的一套标准接口,主要包括一套V4L2相关的底层数据结构 和 V4L2相关的底层驱动的接口作用是使得程序有发现和操作设备的能力。V4L2驱动框架分为 V4L2核心部分,V4L2下层接口部分两部分,其中 V4L2核心部分主要功能是构建内核中标准的视频设备驱动框架以及注册字符设备为上层用户提供访问接口, V4L2下层接口部分的主要功能是挂接底层硬件IC。

重点内容 v4l2驱动框架分层:
第一层 v4l2核心驱动框架 :video_device 以及 v4l2_device 的创建、初始化、注册
第二层 v4l2下层接口驱动框架 :将camera sensor挂接到i2c总线上

2.1 v4l2驱动框架

2.1.1 v4l2驱动框架简述

V4L2驱动的代码在 drivers\media\v4l2-core 文件夹下,打开该目录可以看到如下一系列文件,看似很多其实可以归类,比如:
videobufxx_xxx.c系列文件是用于实现视频的内存分配的
videobuf2_xxx系列文件是对应V4L2
videobuf—xxx.c系列文件是对应于 V4L(video for linux one)
v4l2-dev.c对应于video_device的实现
v4l2-device.c对应 v4l2_device的实现
v4l2-ioctl.c对应 ioctl的实现
v4l2-subdev.c对应 42vl_subdev的实现等等。。。

video驱动代码位于 drivers\media 下,该路径下有很多子目录,其中比如 i2c mmc usb tuners radio等目录都是对应各个subdev的实现,platform目录用于存放不同soc的驱动代码

V4l2驱动框架图如下所示:

 用户空间       v42l 应用接口(open read write)-------------------------------------------------内核空间         第一层  v4l2核心驱动框架示例:drivers/media/platform/vivi.cv42l核心驱动 : 对应video_device(v4l2核心驱动框架)video设备驱动 : 对应v4l2_device(v4l2核心驱动框架)第二层  v4l2下层接口驱动框架示例:drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.cvideo子设备驱动 :对应v4l2_subdev(v4l2下层接口驱动框架)-------------------------------------------------video设备接口-------------------物理底层  -------------------------------------------------v4l2核心:此部分视频设备核心。对应结构体video_device,是v4l2驱动框架向上层用户提供的接口video设备驱动:此部分驱动需要我们填充,代表一个v4l2设备,主要工作是根据 4vl2提供的驱动模型,完成对具体视频设备硬件底层实现,Linux提供4vl2示例代码:vivi.cvideo子设备驱动:4vl2驱动所连接的子设备,如摄像头传感器IC,解编码器IC,音频IC等等,对应结构体v4l2_subdev,是v4l2驱动框架向下提供的接口v42l 应用接口: 应用程序通过V4L2提供read()、write()、ioctl()编程接口,来控制操作视频设备,如:设置图像分辨率、视频数据格式、开始/结束视频捕获等等。video设备:视频设备按照输入输出来区分,摄像头属于输入设备,显示器属于输出设备video设备接口:本文讨论的是摄像头,所以此处的设备接口即摄像头接口,一般目前流行的camera接口有 mipi 和 usb,mipi是当前主流的便携式设备(手机)camera接口本文项目也是mipi接口。一般的usb接口camera常见于台式或者笔记本上,usb协议有专门针对video设备的接口类
2.1.2 v4l2驱动核心结构体说明

struct video_device :保存管理v4l2_device设备(4vl2设备)数据,注册成功之后 以类似/dev/videoxxx的字符设备形式提供给上层,包含底层驱动结构体 v4l2_device 以及 为上层提供的接口 cdev

struct v4l2_device :代表一个 4vl2设备,保存设备实例的数据

struct v4l2_subdev :由于目前 v4l2驱动 随着需求以及硬件的变化越来越复杂,,因为v4l2驱动需要支持音频,视频,解码,编码等ic,使得大部分 v4l2设备都包含了多个子设备IC,例如 解编码器,传感器,摄像头控制器等等,所以在/dev目录下不仅仅要建立v4l2的节点,还需要建立各个IC的设备节点,如fb,i2c,input,alsa等设备节点,通常这些IC通过i2c总线与主板连接,以上设备统称为 sub-devices 子设备,代表 实实在在的camera等传感器设备,通常指挂在i2c总线。驱动需要与子设备进行通信,这些子设备一般情况下就是音频处理,编解码器等,camera常见的子设备有传感器和摄像头控制器,为了方便代码管理,内核 v4l2 提供了一个统一的接口给这些子设备,即 v4l2_subdev 结构体

//kernel/include/media/v4l2-dev.hstruct video_device{const struct v4l2_file_operations *fops;//设备操作函数集struct cdev *cdev;     //字符设备 对应上层接口 open/read/writestruct v4l2_device *v4l2_dev;  //v4l2 设备 int minor;    //system系统之 的 video-xxx的次设备号const struct v4l2_ioctl_ops *ioctl_ops;//具体功能的实现函数......};// /kernel/include/media/v4l2-device.hstruct v4l2_device {...struct list_head subdevs;    //用链表管理注册的subdev...};// kernel/inlcude/media/v4l2-subdev.hstruct v4l2_subdev {...struct list_head list;     /* 链接至 v4l2_device */  struct v4l2_device *v4l2_dev; //struct v4l2_deviceconst struct v4l2_subdev_ops *ops;//设备功能集...};struct v4l2_subdev_ops {const struct v4l2_subdev_core_ops    *core;//通用操作集合const struct v4l2_subdev_tuner_ops    *tuner;//调谐器操作合集const struct v4l2_subdev_audio_ops  *audio;//音频操作合集const struct v4l2_subdev_video_ops   *video;//视频操作合集const struct v4l2_subdev_vbi_ops *vbi;const struct v4l2_subdev_ir_ops        *ir;const struct v4l2_subdev_sensor_ops *sensor;const struct v4l2_subdev_pad_ops    *pad;};
open /dev/videoxx --> cdev->file_oprations ---> file_oprations->v4l2_file_oprations.open

2.2 v4l2核心驱动框架

内核提供了示例驱动:drivers/media/platform/vivi.c
主要工作:
1 构建video_device结构,包括.fops以及.ioctl_ops
2 初始化 v4l2_device结构体(代表一个 v4l2设备)
3 注册video_device结构体(video_device 是内核对 v4l2_device的官方封装,用于管理v4l2_device数据),向上层用户提供访问接口

//v4l2_device设备的自定义封装
struct vivi_dev {
struct list_head           vivi_devlist;
struct v4l2_device     v4l2_dev;//v4l2_device设备
struct video_device    vdev;
...
...
};//file_operations的一个子集
static const struct v4l2_file_operations vivi_fops = {
.owner      = THIS_MODULE,
.open           = v4l2_fh_open,
.release        = vb2_fop_release,
.read           = vb2_fop_read,
.poll       = vb2_fop_poll,
.unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
.mmap           = vb2_fop_mmap,
};static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
.vidioc_querycap      = vidioc_querycap,
.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
.vidioc_enum_framesizes   = vidioc_enum_framesizes,
.vidioc_reqbufs       = vb2_ioctl_reqbufs,
.vidioc_create_bufs   = vb2_ioctl_create_bufs,
.vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
.vidioc_querybuf      = vb2_ioctl_querybuf,
.vidioc_qbuf          = vb2_ioctl_qbuf,
.vidioc_dqbuf         = vb2_ioctl_dqbuf,
.vidioc_enum_input    = vidioc_enum_input,
.vidioc_g_input       = vidioc_g_input,
.vidioc_s_input       = vidioc_s_input,
.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
.vidioc_g_parm        = vidioc_g_parm,
.vidioc_s_parm        = vidioc_s_parm,
.vidioc_streamon      = vb2_ioctl_streamon,
.vidioc_streamoff     = vb2_ioctl_streamoff,
.vidioc_log_status    = v4l2_ctrl_log_status,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};//struct video_device 的构造
static const struct video_device vivi_template = {
.name       = "vivi",
.fops           = &vivi_fops,//用户open相关内容
.ioctl_ops  = &vivi_ioctl_ops, //用户iotrl对应的相关内容
.release    = video_device_release_empty,
};//注册camera设备
static int __init vivi_create_instance(int inst)
{struct vivi_dev *dev;struct video_device *vfd;int ret;//注册 v4l2_device设备,内部只是一些初始化v4l2_device行为,并无实质注册动作ret = v4l2_device_register(NULL, &dev->v4l2_dev);//注册 video_device设备: VFL_TYPE_GRABBER : 代表camera video设备类型ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
}

2.3 v4l2下层接口驱动框架

不同的camera有不同的驱动,但是他都凌驾在i2c的控制器上。故实现camera的驱动,通常都是实现i2c_driver和i2c_client的相关内容。
drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c: 挂载在i2c总线上面的 camera sensor
先注册platform平台,然后挂载到i2c总线上。

static const struct of_device_id msm_sensor_driver_dt_match[] = {
{.compatible = "qcom,camera"},
{}
};MODULE_DEVICE_TABLE(of, msm_sensor_driver_dt_match);static struct platform_driver msm_sensor_platform_driver = {
.driver = {.name = "qcom,camera",.owner = THIS_MODULE,.of_match_table = msm_sensor_driver_dt_match,
},
.remove = msm_sensor_platform_remove,
};.....static const struct i2c_device_id i2c_id[] = {
{SENSOR_DRIVER_I2C, (kernel_ulong_t)NULL},
{ }
};static struct i2c_driver msm_sensor_driver_i2c = {
.id_table = i2c_id,
.probe  = msm_sensor_driver_i2c_probe,
.remove = msm_sensor_driver_i2c_remove,
.driver = {.name = SENSOR_DRIVER_I2C,},
};具体i2c挂载sensor代码不做详细说明,只说明框架。设备树:camera sensor的挂接,以及gpio设置
&i2c_3 {
qcom,camera@0 { //后摄像头 0cell-index = <0>;compatible = "qcom,camera";reg = <0x2>;qcom,csiphy-sd-index = <0>;qcom,csid-sd-index = <0>;qcom,mount-angle = <90>;cam_vana-supply = <&pm8909_l17>;cam_vio-supply = <&pm8909_l6>;qcom,cam-vreg-name = "cam_vio", "cam_vana";qcom,cam-vreg-type = <1 0>;qcom,cam-vreg-min-voltage = <0 2800000>;qcom,cam-vreg-max-voltage = <0 2850000>;qcom,cam-vreg-op-mode = <0 80000>;pinctrl-names = "cam_default", "cam_suspend";pinctrl-0 = <&cam_sensor_mclk0_default&cam_sensor_rear_default>;pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>;gpios = <&msm_gpio 26 0>, //后摄像头的 mclk<&msm_gpio 35 0>, //后摄像头的 reset<&msm_gpio 34 0>; //后摄像头的 pwdnqcom,gpio-reset = <1>;qcom,gpio-standby = <2>;qcom,gpio-req-tbl-num = <0 1 2>;qcom,gpio-req-tbl-flags = <1 0 0>;qcom,gpio-req-tbl-label = "CAMIF_MCLK","CAM_RESET1","CAM_STANDBY";qcom,sensor-position = <0>;qcom,sensor-mode = <0>;qcom,cci-master = <0>;status = "ok";clocks = <&clock_gcc clk_mclk0_clk_src>,<&clock_gcc clk_gcc_camss_mclk0_clk>;clock-names = "cam_src_clk", "cam_clk";
};qcom,camera@1 {cell-index = <1>;compatible = "qcom,camera";reg = <0x1>;qcom,csiphy-sd-index = <0>;qcom,csid-sd-index = <0>;qcom,mount-angle = <90>;cam_vana-supply = <&pm8909_l17>;cam_vio-supply = <&pm8909_l6>;qcom,cam-vreg-name = "cam_vio", "cam_vana";qcom,cam-vreg-type = <1 0>;qcom,cam-vreg-min-voltage = <0 2850000>;qcom,cam-vreg-max-voltage = <0 2850000>;qcom,cam-vreg-op-mode = <0 80000>;pinctrl-names = "cam_default", "cam_suspend";pinctrl-0 = <&cam_sensor_mclk1_default &cam_sensor_front_default>;pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front_sleep>;gpios = <&msm_gpio 27 0>,<&msm_gpio 28 0>,<&msm_gpio 33 0>;qcom,gpio-reset = <1>;qcom,gpio-standby = <2>;qcom,gpio-req-tbl-num = <0 1 2>;qcom,gpio-req-tbl-flags = <1 0 0>;qcom,gpio-req-tbl-label = "CAMIF_MCLK","CAM_RESET","CAM_STANDBY";qcom,cci-master = <0>;status = "ok";clocks = <&clock_gcc clk_mclk1_clk_src>,<&clock_gcc clk_gcc_camss_mclk1_clk>;clock-names = "cam_src_clk", "cam_clk";
};
};

综上所述:v4l2框架如下:

关于ioctl,read, write过程日后补充,以上。

V4L2视频驱动框架---v4l2_device管理模块简述相关推荐

  1. V4L2视频驱动框架---meida_device管理模块简述

    ​ v4l2框架由4个主要的部分(数据结构)组成: v4l2_devices(包括v4l2_subdev) :v4l2_device管理所有的设备 media_device : meida_devic ...

  2. V4L2视频驱动框架简述(转载)

    摘自:https://blog.csdn.net/LinuxArmbiggod/article/details/80310445 V4L2视频驱动框架简述 奶牛养殖场小马 2018-05-14 15: ...

  3. Linux驱动框架之v4l2视频驱动框架解析

    1.简介 v4l2是专门为linux设备设计的一套视频框架,其主体框架在linux内核,可以理解为是整个 linux 系统上面的视频源捕获驱动框架.其广泛应用在嵌入式设备以及移动端.个人电脑设备上面, ...

  4. 【Linux驱动】Linux--V4L2视频驱动框架

    Linux--V4L2视频驱动框架 Linux--V4L2驱动框架 一.V4L2 框架 二.V4L2驱动主要数据结构 三.V4L2提供的外部接口 四.V4L2驱动框架模板 五.虚拟摄像头驱动 参考资料 ...

  5. DM6446开发攻略:V4L2视频驱动和应用分析

    针对DAVINCI DM6446平台,网络上也有很多网友写了V4L2的驱动,但只是解析Montavistalinux-2.6.10 V4L2的原理.结构和函数,深度不够.本文决定把Montavista ...

  6. 【genius_platform软件平台开发】第五十二讲:Linux系统之V4L2视频驱动详解

    V4L2视频驱动详解 刚建的微信群欢迎加入一起学习.讨论: 1. 简介 1.1 视频输入输出设备(video capture device,video output device) 1.2 VBI设备 ...

  7. 【genius_platform软件平台开发】第五十八讲:Linux系统之V4L2视频驱动-VIDIOC_REQBUFS向驱动申请帧缓冲代码详解

    VIDIOC_REQBUFS向驱动申请帧缓冲代码详解 1. 概述 2. 应用层 3. 内核驱动 3.1 vb2_ioctl_reqbufs函数 3.2 vb2_core_reqbufs函数 3.3 _ ...

  8. Linux V4l2驱动 -- 框架概述

    V4l2框架简述 1 硬件 常用的电脑摄像头是USB接口,主流的智能手机摄像头是MIPI接口,另外还有像树莓派等硬件使用的CSI接口的设备.常用的智能手机Camera采用的MIPI接口,电路框架以及电 ...

  9. 深入学习Linux摄像头(二)v4l2驱动框架

    深入学习Linux摄像头系列 深入学习Linux摄像头(一)v4l2应用编程 深入学习Linux摄像头(二)v4l2驱动框架 深入学习Linux摄像头(三)虚拟摄像头驱动分析 深入学习Linux摄像头 ...

最新文章

  1. poj2739(尺取法+质数筛)
  2. System.IO 的三个抽象类
  3. 云服务器有i5的性能吗,i5云服务器
  4. C语言中printf输出特殊字符(“%d“或者“\n“)
  5. “函数调用的左操作数”的理解
  6. 分布式工作流任务调度系统Easy Scheduler正式开源
  7. linux如何杀死进程最快,如何在Linux系统中杀掉内存消耗最大的进程?
  8. Linux C++ STL用法介绍(1)
  9. c语言代码表白_程序员教你表白:C/C++打造浪漫表白程序,找女朋友从现在开始...
  10. Apache环境利用.htaccess文件设置域名301跳转(不带www跳转到带www)
  11. python 装饰器,登录小练习
  12. java excel导出(基于注解)
  13. 想撤回没门!电脑版微信、QQ 、TIM的防撤回工具
  14. 61家公司入选“2021年大中华区最佳职场”榜单;针对“奥密克戎”!云顶新耀与加拿大生物技术公司研发新型疫苗 | 美通社头条...
  15. python聊天室socket+tkinter_基于socket和tkinter的python网络聊天室程序
  16. icpc 2019 沈阳区域赛
  17. 线上Request method ‘GET‘ not supported 问题
  18. 视频原声能去掉吗?怎么批量处理
  19. day01_xUtils+注解+动画
  20. C语言经典面试题及面试宝典

热门文章

  1. v-chart柱状图点击改变颜色
  2. 惠普触控板使用指南_惠普笔记本怎么关触控板?
  3. can和could的用法_情态动词:can与could的用法详解
  4. BIM电子沙盘编辑软件BIMSHOW开启下载了
  5. android listview 宽度,Android ListView项目没有填充宽度
  6. 读 Linux 像读小说「GitHub 热点速览 v.22.03」
  7. java极光推送如何设置别名_Android 极光推送设置别名
  8. chrome无法从该网站添加应用、扩展程序和用户脚本
  9. 这就是我英语 来自http://www.uuseenews.com.cn/
  10. ASEMI整流桥ABS210参数,ABS210规格书,ABS210特征