V4L2框架分析学习二

本文深入剖析了V4L2框架中的v4l2_device结构,介绍了其作为子设备管理者的角色,以及v4l2_subdev如何代表和操作子设备。详细讲解了v4l2_subdev的注册与注销,video_device在生成设备节点文件中的作用,以及v4l2_fh和v4l2_ctrl_handler在保存设备特有操作和控制方法上的功能。此外,还探讨了V4L2设备的ioctl框架和IO访问方式,特别是内存映射缓冲区的使用,以及用户空间如何通过内核映射访问视频设备的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

v4l2_device

v4l2_device在v4l2框架中充当所有v4l2_subdev的父设备,管理着注册在其下的子设备。以下是v4l2_device结构体原型(去掉了无关的成员):
复制代码

struct v4l2_device {

     structlist_head subdevs;    //用链表管理注册的subdev

     charname[V4L2_DEVICE_NAME_SIZE];    //device 名字

     structkref ref;      //引用计数

     ……

}

复制代码

可以看出v4l2_device的主要作用是管理注册在其下的子设备,方便系统查找引用到。

V4l2_device的注册和注销:

int v4l2_device_register(struct device*dev, struct v4l2_device *v4l2_dev)

static void v4l2_device_release(struct kref *ref)

V4l2_subdev

V4l2_subdev代表子设备,包含了子设备的相关属性和操作。先来看下结构体原型:
复制代码

struct v4l2_subdev {

     struct v4l2_device *v4l2_dev;  //指向父设备

     //提供一些控制v4l2设备的接口

     const struct v4l2_subdev_ops *ops;

     //向V4L2框架提供的接口函数

     const struct v4l2_subdev_internal_ops *internal_ops;

     //subdev控制接口

     struct v4l2_ctrl_handler *ctrl_handler;

     /* name must be unique */

     charname[V4L2_SUBDEV_NAME_SIZE];

     /*subdev device node */

     struct video_device *devnode;  

};

复制代码

每个子设备驱动都需要实现一个v4l2_subdev结构体,v4l2_subdev可以内嵌到其它结构体中,也可以独立使用。结构体中包含了对子设备操作的成员v4l2_subdev_ops和v4l2_subdev_internal_ops。

v4l2_subdev_ops结构体原型如下:
复制代码

struct v4l2_subdev_ops {

//视频设备通用的操作:初始化、加载FW、上电和RESET等

     const struct v4l2_subdev_core_ops        *core;    //tuner特有的操作

     const struct v4l2_subdev_tuner_ops      *tuner;    //audio特有的操作

     const struct v4l2_subdev_audio_ops      *audio;    //视频设备的特有操作:设置帧率、裁剪图像、开关视频流等

     const struct v4l2_subdev_video_ops      *video;

……

};

复制代码

视频设备通常需要实现core和video成员,这两个OPS中的操作都是可选的,但是对于视频流设备video->s_stream(开启或关闭流IO)必须要实现。

v4l2_subdev_internal_ops结构体原型如下:
复制代码

struct v4l2_subdev_internal_ops {

//当subdev注册时被调用,读取IC的ID来进行识别

     int(*registered)(struct v4l2_subdev *sd);

     void(*unregistered)(struct v4l2_subdev *sd);

//当设备节点被打开时调用,通常会给设备上电和设置视频捕捉FMT

     int(*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);

     int(*close)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);

};

复制代码

v4l2_subdev_internal_ops是向V4L2框架提供的接口,只能被V4L2框架层调用。在注册或打开子设备时,进行一些辅助性操作。

Subdev的注册和注销

当我们把v4l2_subdev需要实现的成员都已经实现,就可以调用以下函数把子设备注册到V4L2核心层:

int v4l2_device_register_subdev(struct v4l2_device*v4l2_dev, struct v4l2_subdev *sd)

当卸载子设备时,可以调用以下函数进行注销:

void v4l2_device_unregister_subdev(struct v4l2_subdev*sd)

video_device

video_device结构体用于在/dev目录下生成设备节点文件,把操作设备的接口暴露给用户空间。
复制代码

struct video_device

{

     const struct v4l2_file_operations *fops;  //V4L2设备操作集合

     /*sysfs */

     struct device dev;             /* v4l device */

     struct cdev *cdev;            //字符设备

     /* Seteither parent or v4l2_dev if your driver uses v4l2_device */

     struct device *parent;              /* deviceparent */

     struct 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值