这段时间开始搞安卓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.

    

具体驱动代码的编写将在下篇继续....

Linux摄像头驱动学习之:(一)V4L2_框架分析的更多相关文章

  1. Linux 网卡驱动学习(一)(分析一个虚拟硬件的网络驱动样例)

    在Linux,网络分为两个层,各自是网络堆栈协议支持层,以及接收和发送网络协议的设备驱动程序层. 网络堆栈是硬件中独立出来的部分.主要用来支持TCP/IP等多种协议,网络设备驱动层是连接网络堆栈协议层 ...

  2. Linux摄像头驱动学习之:(六)UVC-基本框架代码分析

    仿照内核的自带UVC(usb video class)驱动程序写的一版简化驱动,仅供学习,实际项目开发中应该尽量使用内核自带的驱动,除非内核自带的驱动不支持此款硬件才需要自己写驱动. 下面就直接上代码 ...

  3. Linux摄像头驱动学习之:(四)UVC-摄像头驱动框架分析

    UVC: USB Video ClassUVC驱动:drivers\media\video\uvc\ uvc_driver.c分析:1. usb_register(&uvc_driver.dr ...

  4. Linux摄像头驱动学习之:(五)UVC-分析设备描述符

    linux系统上插上USB摄像头设备后,内存就会有相应的设备描述符信息,后期可以根据这些信息进一步写驱动程序. 流程:Device(设备) -> Configuration(配置) -> ...

  5. Linux摄像头驱动学习之:(三)从零写虚拟驱动(仿照vivi.c)

    本篇仿照vivi.c 写虚拟视频驱动,代码(myvivi.c+fillbuf.c+Makefile)如下: //==========================myvivi.c========== ...

  6. Linux摄像头驱动学习之:(二)通过虚拟驱动vivi分析摄像头驱动

    一.通过指令 "strace -o xawtv.log xawtv" 得到以下调用信息:// 1~7都是在v4l2_open里调用1. open2. ioctl(4, VIDIOC ...

  7. Linux内核驱动学习(八)GPIO驱动模拟输出PWM

    文章目录 前言 原理图 IO模拟输出PWM 设备树 驱动端 调试信息 实验结果 附录 前言 上一篇的学习中介绍了如何在用户空间直接操作GPIO,并写了一个脚本可以产生PWM.本篇的学习会将写一个驱动操 ...

  8. 找回了当年一篇V4L2 linux 摄像头驱动的博客

    从csdn找回 , 无缘无故被封了..当时损失不少啊!!!!!!!!! linux 摄像头驱动 :核心数据结构:    /**     * struct fimc_dev - abstraction ...

  9. Linux内核驱动学习(十)Input子系统详解

    文章目录 前言 框架 如何实现`input device` 设备驱动? 头文件 注册input_dev设备 上报按键值 dev->open()和dev->close() 其他事件类型,处理 ...

随机推荐

  1. 解决淘宝sui插件后退bug

    淘宝的sui插件在微信里,第一次访问没有问题,跳转走以后,再后退回来, 插件就无法正常加载. 一下是官方给出的说法 切换到的新页面中的 js 不执行 由于浏览器安全性考虑的限制以及可能的 js 重复执 ...

  2. mustache.js渲染带事件的模板

    http://zccst.iteye.com/blog/2183111 最近遇到这样一个问题,预览内容可点击,问题是通过$.Mustache.render("templateId" ...

  3. java源程序---可执行文件(.exe)----安装包

    众所周知,java源程序都可以导出为(executable jar file)可执行的.jar文件,但是该.jar文件需要在jre环境下才能执行. 那么如何能在没有装jre的电脑上运行呢?(那就要顺带 ...

  4. 深入理解JVM虚拟机-7虚拟机类加载机制

    虚拟机把描述类的数据从Class文件夹加载到内存,并对数据进行小燕.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是虚拟机的类加载机制. 下面所说的Class文件不是具体的某个文件 ...

  5. mysql数据库回滚

    在应用$mysqli时,因没常用到数据回滚,老忘,整理下,做个记录. $mysqli->autocommit(FALSE);//自动提交设置关闭 $mysqli->query(" ...

  6. 滚动条--nicescroll插件(兼容各种浏览器,低至IE5)

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  7. [svn] 分支开发

    参考博客: http://www.cnblogs.com/cxd4321/archive/2012/07/12/2588110.html (1)为什么要使用SVN分支开发和主干合并? 目的:在SVN下 ...

  8. Maven基础知识和环境搭建

    基本概念和生命周期 Maven是现在流行的构建自动化工具,提供了软件构建过程中全生命周期的管理. 基础目录结构 基础目录结构如下: 根目录:存放pom.xml 和所有的子目录 ${basedir}/s ...

  9. python中read、readline和readlines

    f  = file('test.txt' , 'r') all_data = f.read()   # 字符串类型 f.read(8)                         #读取固定大小的 ...

  10. 整理的一些模版LCS(连续和非连续)

    对于连续的最大串,我们称之为子串....非连续的称之为公共序列.. 代码: 非连续连续 int LCS(char a[],char b[],char sav[]){ int lena=strlen(a ...