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.

    

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

时间: 2024-08-26 03:27:38

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

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

在Linux,网络分为两个层,各自是网络堆栈协议支持层,以及接收和发送网络协议的设备驱动程序层. 网络堆栈是硬件中独立出来的部分.主要用来支持TCP/IP等多种协议,网络设备驱动层是连接网络堆栈协议层和网络硬件的中间层. 网络设备驱动程序的主要功能是: (1)模块载入或内核启动相关的初始化处理 (2)清除模块时的处理 (3)网络设备的检索和探測 (4)网络设备的初始化和注冊 (5)打开或关闭网络设备 (6)发送网络数据 (7)接收网络数据 (8)中断处理(在发送完数据时.硬件向内核产生一个中断.

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

仿照内核的自带UVC(usb video class)驱动程序写的一版简化驱动,仅供学习,实际项目开发中应该尽量使用内核自带的驱动,除非内核自带的驱动不支持此款硬件才需要自己写驱动. 下面就直接上代码了,要根据自己的设备信息修改相关配置参数. 1 #include <linux/kernel.h> 2 #include <linux/list.h> 3 #include <linux/module.h> 4 #include <linux/usb.h> 5

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

UVC: USB Video ClassUVC驱动:drivers\media\video\uvc\ uvc_driver.c分析:1. usb_register(&uvc_driver.driver);2. uvc_probe        uvc_register_video            vdev = video_device_alloc();            vdev->fops = &uvc_fops;            video_register_de

Linux嵌入式驱动学习之路④u-boot编译分析

u-boot编译分析 在配置完成后,执行make开始编译.这里打开Makefile. 首先包含在配置时生成的config.mk all: sinclude $(obj)include/autoconf.mk.dep sinclude $(obj)include/autoconf.mk # load ARCH, BOARD, and CPU configuration include $(obj)include/config.mk //配置时生成的 export ARCH CPU BOARD VE

linux内核驱动学习(八)----驱动分类 | 学习方法 | 硬件访问

驱动分类: 对于驱动,我们一般按两种方法进行分类:常规分类法和总线分类法. 按照常规分类法,可以分为以下三类: 1.字符设备: 以字节为最小访问单位的设备.一般通过字符设备文件来访问字符设备驱动程序.字符驱动程序则负责驱动字符设备, ,这样的驱动通常支持open.close.read.write系统调用,应用程序可以通过设备文件(比如/dev/ttySAC0等)来访问字符设备(串口).例如:串口\led\按键 2.块设备: 以块(一般512字节)为最 小传输单位的设备.大多数UNIX系统中,块设

linux内核驱动学习指南

目录: 1.参考链接 1. 参考链接 小白的博客 ONE_Tech 你为什么看不懂Linux内核驱动源码? 求教怎么学习linux内核驱动 原文地址:https://www.cnblogs.com/agui125/p/10071452.html

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

在Linux,网络分为两个层,分别是网络堆栈协议支持层,以及接收和发送网络协议的设备驱动程序层.网络堆栈是硬件中独立出来的部分,主要用来支持TCP/IP等多种协议,网络设备驱动层是连接网络堆栈协议层和网络硬件的中间层. 网络设备驱动程序的主要功能是: (1)模块加载或内核启动相关的初始化处理 (2)清除模块时的处理 (3)网络设备的检索和探测 (4)网络设备的初始化和注册 (5)打开或关闭网络设备 (6)发送网络数据 (7)接收网络数据 (8)中断处理(在发送完数据时,硬件向内核产生一个中断,告

Linux设备驱动之IIO子系统——IIO框架及IIO数据结构

由于需要对ADC进行驱动设计,因此学习了一下Linux驱动的IIO子系统.本文翻译自<Linux Device Drivers Development >--John Madieu,本人水平有限,若有错误请大家指出. IIO Framework 工业I / O(IIO)是专用于模数转换器(ADC)和数模转换器(DAC)的内核子系统.随着越来越多的具有不同代码实现的传感器(具有模拟到数字或数字到模拟,功能的测量设备)分散在内核源上,收集它们变得必要.这就是IIO框架以通用的方式所做的事情.自20

Linux音频驱动学习之:(1)ASOC分析

一.音频架构概述 (1)ALSA是Advanced Linux Sound Architecture 的缩写,目前已经成为了linux的主流音频体系结构,想了解更多的关于ALSA的这一开源项目的信息和知识,请查看以下网址:http://www.alsa-project.org/.在内核设备驱动层,ALSA提供了alsa-driver,同时在应用层,ALSA为我们提供了alsa-lib,应用程序只要调用alsa-lib提供的API,即可以完成对底层音频硬件的控制. (2)PCM是英文Pulse-c