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

深入学习Linux摄像头系列

深入学习Linux摄像头(一)v4l2应用编程

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

深入学习Linux摄像头(三)虚拟摄像头驱动分析

深入学习Linux摄像头(四)三星平台fimc驱动详解

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

一、V4L2 框架

1.1 相关对象

v4l2驱动框架主要的对象有video_devicev4l2_devicev4l2_subdevvideobuf

  • video_device

    一个字符设备,为用户空间提供设备节点(/dev/videox),提供系统调用的相关操作(open、ioctl…)

  • v4l2_device

    嵌入到video_device中,表示一个v4l2设备的实例

  • v4l2_subdev

    依附在v4l2_device之下,并表示一个v4l2设备的子设备,一个v4l2_devide下可以有多个sub_device

  • videobuf

    v4l2驱动的缓存管理

下面有必要对v4l2_device和v4l2_subdev来进行说明

subdev的设计目的是为了多路复用,就是用一个v4l2_device可以服务多个v4l2_subdev

下面以我们手机的摄像头来举例

  • CMOS摄像头

    对于一款CMOS摄像头来说,有两个接口,一个是摄像头接口,一个是I2C接口

    摄像头接口负责传输图像数据,I2C接口负责传输控制信息,所以又可以将CMOS摄像头看作是一个I2C模块

    如下图所示

    在这里插入图片描述

  • 芯片片上资源

    在一款芯片上面,摄像头相关的有摄像头控制器摄像头接口I2C总线

    SOC上可以有多个摄像头控制器,多个摄像头接口,多个I2C总线

    摄像头控制器负责接收和处理摄像头数据,摄像头接口负责传输图像数据,I2C总线负责传输控制信息

    如下图所示

    在这里插入图片描述

对于手机而言,一般都有两个摄像头,一个前置摄像头,一个后置摄像头,其接发下图所示

在这里插入图片描述

我们可以选择让控制器去操作哪一个摄像头,这就做到了使用一个摄像头控制器来控制多个摄像头,这就是多路复用

上面说要使用一个摄像头控制器去操作多个摄像头,这是我们的目的,那么在软件中是怎么实现的呢?

我们回到V4L2来,再来谈v4l2_devicev4l2_subdev

上面我们介绍到v4l2_device表示一个v4l2实例

在V4L2驱动中,使用v4l2_device来表示摄像头控制器

使用v4l2_subdev来表示具体的某一个摄像头的I2C控制模块,进而通过其控制摄像头

v4l2_device里有一个v4l2_subdev链表,可以选择v4l2_device去控制哪一个v4l2_subdev

相信到此,你对v4l2_devicev4l2_subdev就有所了解了

当然某些驱动是没有v4l2_subdev,只有video_device

经过上面的讲解,我们用一张图来总结

在这里插入图片描述

前面说video_device是一个字符设备,从图中可以看出,video_device内含一个cdev

v4l2_device是一个v4l2实例,嵌入到video_device中

v4l2_device维护者一个链表管理v4l2_subdev,v4l2_subdev表示摄像头的I2C控制模块

1.2 V4L2 框架

在理清楚V4L2中的主要对象后,我们来介绍V4L2的框架

在介绍V4L2驱动框架前,我们先回顾一下简单的字符设备的编写

  • 分配一个字符设备(cdev)
  • 设置一个fops
  • 注册字符设备

复杂的字符设备

对于复杂的字符设备,内核都是采用分层的方法,一般分驱动核心层还有硬件相关层

核心层会帮你完成字符设备的分配,fops的设置,注册字符设备,并向硬件相关层提供一个相应的对象和注册接口

硬件相关层则需要分配相应的对象,设置对象和对象的fops,并注册到核心层中

当应用层发生系统调用,会先来到核心层,核心层再通过回调函数调用到硬件相关层的驱动

对于V4L2的驱动框架也是如此,可分为V4L2驱动核心层硬件相关层

下面先用一张图来总结大致V4L2的驱动框架

在这里插入图片描述

从图中可以看出V4L2分为核心层还有硬件相关层

核心层负责注册字符设备,然后提供video_device对象和相应的注册接口给硬件相关层使用

硬件相关层需要分配一个video_device并设置它,然后向核心层注册,核心层会为其注册字符设备并且创建设备节点(/dev/videox)。同时硬件相关层还需要分配和设置相应的v4l2_devicev4l2_subdev,其中v4l2_device的一个比较重要的意义就是管理v4l2_subdev,当然有一些驱动并不需要实现v4l2_subdev,此时v4l2_device的意义就不是很大了

当应用层通过/dev/video来操作设备的时候,首先会来到V4L2的核心层,核心层通过注册进的video_device的回调函数调用相应的操作函数,video_device可以直接操作硬件或者是通过v4l2_subdev来操作硬件

二、V4L2的数据结构

介绍完V4L2的驱动框架后,来看一看内核中各对象的数据结构

2.1 V4L2主要对象的数据结构

  • video_device

    struct video_device
    {
         
         
        /* character device */
    	struct cdev *cdev;
        
        /* v4l2_device parent */
    	struct v4l2_device *v4l2_dev;
    
       	/* device ops */
    	const struct v4l2_file_operations *fops;
        
    	/* ioctl callbacks */
    	const struct v4l2_ioctl_ops *ioctl_ops;
    };
    

    可以看到video_device中含有一个cdev还有v4l2_device,此外还有fops和ioctl_ops,从应用层进行系统调用会经过v4l2的核心层回调到这里

    其中v4l2_file_operationsv4l2_ioctl_ops如下

    struct v4l2_file_operations {
         
         
    	struct module *owner;
    	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    	unsigned int (*poll) (struct file *, struct poll_table_struct *);
    	long (*ioctl) (struct file *, unsigned int, unsigned long);
    	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
    	unsigned long (*get_unmapped_area) (struct file *, unsigned long,
    				unsigned long, unsigned long, unsigned long);
    	int (*mmap) (struct file *, struct vm_area_struct *);
    	int (*open) (struct file *);
    	int (*release) (struct file *);
    };
    

    熟悉v4l2应用编程的应该都知道v4l2有很多ioctl操作,具体实现都在这里

    struct v4l2_ioctl_ops {
         
         
    	int (*vidioc_querycap)(struct file 
<think>好的,我现在要介绍V4L2驱动框架。首先,我需要确认自己对V4L2的理解是否正确。V4L2是Video for Linux 2的缩写,是Linux内核中负责视频设备驱动框架,主要用于摄像头、视频采集卡等设备。用户可能需要了解其架构、主要组件、工作流程以及应用场景。 接下来,我应该从基本概念入手,解释V4L2的作用和重要性。然后,需要分解其核心组件,比如设备节点、API接口、缓冲区管理等。可能还需要提到V4L2支持的设备类型,比如摄像头、收音机等,但重点在视频设备。 然后,驱动框架的结构是关键。用户可能想知道驱动开发者如何利用V4L2框架来开发驱动程序,比如结构体v4l2_device、v4l2_subdev的作用,以及如何注册设备到内核。这里需要确保术语准确,比如video_device结构体、媒体控制器框架的整合。 另外,用户可能对V4L2的用户空间接口感兴趣,比如如何使用ioctl调用与驱动交互,常见的命令如VIDIOC_QUERYCAP、VIDIOC_REQBUFS等。但用户的问题是驱动框架介绍,所以这部分可能需要简要提及,重点放在内核驱动部分。 可能还需要比较V4L2和其他框架的区别,比如与DRM框架的不同应用场景。不过如果用户没有提到,可能不需要深入。 需要检查是否有遗漏的部分,比如V4L2的子设备(subdev)概念,以及管道配置、视频数据流的处理流程(如DMA缓冲区、内存映射等)。此外,媒体控制器在复杂设备中的作用也很重要,比如多子设备的管理。 需要确保技术细节准确,比如V4L2驱动中的关键结构体和函数,例如v4l2_file_operations、v4l2_ioctl_ops等。同时,要说明驱动开发的基本步骤,如初始化、注册设备、设置操作集、处理缓冲区等。 可能需要注意避免过于深入代码细节,而保持框架层面的介绍。同时,要组织内容结构清晰,分点说明,帮助用户逐步理解。 最后,检查是否有错误,比如V4L2是否支持音频设备(其实主要是视频,但可能包括相关音频流),或者是否所有视频设备都通过V4L2驱动。需要确认这些点,确保信息准确。</think>V4L2(Video for Linux 2)是 Linux 内核中用于支持视频和音频设备的标准框架,主要用于摄像头、采集卡、TV调谐器等设备。以下是其核心介绍: --- ### 一、框架定位 - **作用**:提供统一的用户空间 API 和内核驱动模型,管理视频输入/输出、流媒体和控制功能。 - **适用设备**:摄像头、视频采集卡、编解码器、收音机、SDR(软件定义无线电)等。 --- ### 、核心组件 1. **设备节点** 用户通过 `/dev/videoX` 节点访问设备,每个节点对应一个视频设备。 2. **内核对象** - `struct video_device`:表示一个视频设备,关联操作函数集(`v4l2_file_operations`)。 - `struct v4l2_subdev`:描述子设备(如传感器、ISP),支持模块化硬件设计。 - `struct v4l2_device`:管理主设备与子设备的层级关系。 3. **缓冲区管理** - 支持多种内存类型:DMA 缓冲区(`DMABUF`)、用户空间内存(`USERPTR`)等。 - 关键机制:通过 `videobuf2` 框架实现高效数据流传输。 --- ### 三、驱动开发流程 1. **初始化** - 注册 `v4l2_device` 主设备。 - 创建并配置 `video_device`,绑定操作集(如 `v4l2_ioctl_ops`)。 2. **子设备管理** - 使用 `v4l2_subdev` 注册传感器、ISP 等子模块。 - 通过媒体控制器框架(Media Controller)建立硬件管道链接。 3. **流控制** - 实现缓冲区申请(`VIDIOC_REQBUFS`)、启停流(`VIDIOC_STREAMON/OFF`)。 - 处理数据流中断或 DMA 传输。 --- ### 四、用户空间交互 - **IOCTL 命令**:用户通过 `ioctl()` 调用控制设备,例如: ```c VIDIOC_QUERYCAP // 查询设备能力 VIDIOC_S_FMT // 设置视频格式 VIDIOC_REQBUFS // 申请缓冲区 ``` - **数据流模式**:支持 `mmap()` 内存映射或 `read()` 直接读取。 --- ### 五、典型应用场景 1. **摄像头采集** 通过 `Video Capture` 接口获取图像数据。 2. **视频输出** 使用 `Video Output` 接口驱动显示器或编码器。 3. **复杂媒体链路** 结合媒体控制器配置多设备管道(如:传感器 → ISP → 编码器)。 --- ### 六、与其他框架的关系 - **与 DRM 框架**:DRM 负责显示输出,V4L2 负责采集输入。 - **与 Media Controller**:用于管理多子设备拓扑结构。 --- ### 七、示例驱动结构 ```c static struct video_device my_vdev = { .name = "my_camera", .fops = &my_fops, .ioctl_ops = &my_ioctl_ops, }; static int __init my_driver_init(void) { v4l2_device_register(NULL, &my_v4l2_dev); video_register_device(&my_vdev, VFL_TYPE_VIDEO, -1); // 注册子设备与配置媒体链路 } ``` --- 通过上述分层设计,V4L2 实现了硬件无关性,驱动开发者只需关注硬件特有操作,用户空间则可跨设备调用统一 API。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值