linux V4L2子系统——v4l2的结构体(1)之v4l2_device

备注:
  1. Kernel版本:5.4
  2. 使用工具:Source Insight 4.0

文章目录

  • linux V4L2子系统——v4l2的结构体(1)之v4l2_device
    • 简介
    • 定义
    • 注册
    • 释放
    • 示例

简介

V4L2主设备实例使用struct v4l2_device结构体表示,v4l2_device是V4L2子系统的入口,管理着V4L2子系统的主设备和从设备。简单设备可以仅分配这个结构体,但在大多数情况下,都会将这个结构体嵌入到一个更大的结构体中。需要与媒体框架整合的驱动必须手动设置dev->driver_data,指向包含v4l2_device结构体实例的驱动特定设备结构体。这可以在注册V4L2设备实例前通过dev_set_drvdata()函数完成。同时必须设置v4l2_device结构体的mdev域,指向适当的初始化并注册过的media_device实例。

对于视频设备,Camera控制器可以视为主设备,接在Camera控制器上的摄像头可以视为从设备。V4L2子系统使用v4l2_device结构体管理设备,设备的具体操作方法根据设备类型决定,若是视频设备,则需要注册video_device结构体,并提供相应的操作方法。

定义

//源码:include/media/4l2-device.hstruct v4l2_ctrl_handler;/*** struct v4l2_device - main struct to for V4L2 device drivers** @dev: pointer to struct device.* @mdev: pointer to struct media_device, may be NULL.* @subdevs: used to keep track of the registered subdevs* @lock: lock this struct; can be used by the driver as well* if this struct is embedded into a larger struct.* @name: unique device name, by default the driver name + bus ID* @notify: notify operation called by some sub-devices.* @ctrl_handler: The control handler. May be %NULL.* @prio: Device's priority state* @ref: Keep track of the references to this struct.* @release: Release function that is called when the ref count*   goes to 0.** Each instance of a V4L2 device should create the v4l2_device struct,* either stand-alone or embedded in a larger struct.** It allows easy access to sub-devices (see v4l2-subdev.h) and provides* basic V4L2 device-level support.** .. note::**    #) @dev->driver_data points to this struct.*    #) @dev might be %NULL if there is no parent device*/
struct v4l2_device {/* dev->driver_data points to this struct.Note: dev might be NULL if there is no parent deviceas is the case with e.g. ISA devices. */struct device *dev;            // 父设备struct media_device *mdev;    // 指向media设备/* used to keep track of the registered subdevs */// 注册的子设备的v4l2_subdev结构体都挂载此链表中struct list_head subdevs;  // subdev链表/* lock this struct; can be used by the driver as well if thisstruct is embedded into a larger struct. */// 同步用的自旋锁spinlock_t lock;/* unique device name, by default the driver name + bus ID */// 独一无二的设备名称,默认使用driver name + bus IDchar name[V4L2_DEVICE_NAME_SIZE];    //设备名/* notify callback called by some sub-devices. */// 被一些子设备回调的通知函数,但这个设置与子设备相关。子设备支持的任何通知必须在// include/media/subdevice.h 中定义一个消息头。void (*notify)(struct v4l2_subdev *sd,unsigned int notification, void *arg);//subdev回调函数/* The control handler. May be NULL. */// 提供子设备(主要是video和ISP设备)在用户空间的特效操作接口,// 比如改变输出图像的亮度、对比度、饱和度等等struct v4l2_ctrl_handler *ctrl_handler; //私有的控制接口/* Device's priority state */struct v4l2_prio_state prio;/* Keep track of the references to this struct. */// struct v4l2_device结构体的引用计数,等于0时才释放struct kref ref;/* Release function that is called when the ref count goes to 0. */// 引用计数ref为0时,调用release函数进行释放资源和清理工作void (*release)(struct v4l2_device *v4l2_dev);
};
  • 框架结构体(media_device)
    与驱动结构体非常类似,参考上面的解释,这里不再赘述。v4l2 框架也可以整合到 media framework 里面。如果驱动程序设置了 v4l2_device 的 mdev 成员,那么子设备与 video 节点都会被自动当作 media framework 里的 entitiy 抽象。

  • v4l2_device 结构体
    每一个设备实例都被抽象为一个 v4l2_device 结构体。一些简单的设备可以仅分配一个 v4l2_device 结构体即可,但是
    大多数情况下需要将该结构体嵌入到一个更大的结构体(custom_v4l2_dev)里面。必须用 v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); 来注册设备实例。该函数会初始化传入的 v4l2_device 结构体,如果 dev->driver_data 成员为空的话,该函数就会设置其指向传入的 v4l2_dev 参数。

  • 集成 media framework
    如果驱动想要集成 media framework 的话,就需要人为地设置 dev->driver_data 指向驱动适配的结构体(该结构体由
    驱动自定义- custom_v4l2_dev,里面嵌入 v4l2_device 结构体)。在注册 v4l2_device 之前就需要调用 dev_set_drvdata 来完成设置。并且必须设置 v4l2_decice 的 mdev 成员指向注册的 media_device 结构体实例。

  • 设备节点的命名
    如果 v4l2_device 的 name 成员为空的话,就按照 dev 成员的名称来命名,如果 dev 成员也为空的话,就必须在注册 v4l2_device 之前设置它的 name 成员。可以使用 v4l2_device_set_name 函数来设置 name 成员,该函数会基于驱动名以及驱动实例的索引号来生成 name 成员的名称,类似于 ivtv0、ivtv1 等等,如果驱动名的最后一个字母是整数的话,生成的名称就类似于cx18-0、cx18-1等等,该函数的返回值是驱动实例的索引号。

  • 回调函数与设备卸载
    还可以提供一个 notify() 回调函数给 v4l2_device 接收来自子设备的事件通知。当然,是否需要设置该回调函数取决于子设备是否有向主设备发送通知事件的需求。v4l2_device 的卸载需调用到 v4l2_device_unregister 函数。在该函数被调用之后,如果 dev->driver_data 指向 v4l2_device 的话,该指针将会被设置为NULL。该函数会将所有的子设备全部卸载掉。如果设备是热拔插属性的话,当 disconnect 发生的时候,父设备就会失效,同时 v4l2_device 指向父设备的指针也必须被清除,可以调用 v4l2_device_disconnect 函数来清除指针,该函数并不卸载子设备,子设备的卸载还是需要调用到 v4l2_device_unregister 来完成。如果不是热拔插设备的话,就不必关注这些。

注册

//源码:drivers/media/v4l2-core/v4l2-device.cint v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
{if (v4l2_dev == NULL)return -EINVAL;INIT_LIST_HEAD(&v4l2_dev->subdevs); //初始化subdev链表spin_lock_init(&v4l2_dev->lock);v4l2_prio_init(&v4l2_dev->prio);kref_init(&v4l2_dev->ref);            //初始化v4l2_dev计数值为1get_device(dev);v4l2_dev->dev = dev;if (dev == NULL) {     // 条件检查/* If dev == NULL, then name must be filled in by the caller */if (WARN_ON(!v4l2_dev->name[0]))return -EINVAL;return 0;}/* Set name to driver name + device name if it is empty. */// 初始化v4l2_device设备名if (!v4l2_dev->name[0])snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",dev->driver->name, dev_name(dev));if (!dev_get_drvdata(dev))dev_set_drvdata(dev, v4l2_dev);return 0;
}

释放

//源码:drivers/media/v4l2-core/v4l2-device.c
static void v4l2_device_release(struct kref *ref)
{struct v4l2_device *v4l2_dev =container_of(ref, struct v4l2_device, ref);if (v4l2_dev->release)v4l2_dev->release(v4l2_dev);
}

示例

//源码:drivers/media/platform/sunxi/sun6i/sun6i_csi.c
static int sun6i_csi_v4l2_init(struct sun6i_csi *csi)
{int ret;csi->media_dev.dev = csi->dev;strscpy(csi->media_dev.model, "Allwinner Video Capture Device",sizeof(csi->media_dev.model));csi->media_dev.hw_revision = 0;media_device_init(&csi->media_dev);v4l2_async_notifier_init(&csi->notifier);ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 0);if (ret) {dev_err(csi->dev, "V4L2 controls handler init failed (%d)\n",ret);goto clean_media;}csi->v4l2_dev.mdev = &csi->media_dev;csi->v4l2_dev.ctrl_handler = &csi->ctrl_handler;ret = v4l2_device_register(csi->dev, &csi->v4l2_dev);if (ret) {dev_err(csi->dev, "V4L2 device registration failed (%d)\n",ret);goto free_ctrl;}......csi->notifier.ops = &sun6i_csi_async_ops;ret = v4l2_async_notifier_register(&csi->v4l2_dev, &csi->notifier);if (ret) {dev_err(csi->dev, "notifier registration failed\n");goto clean_video;}return 0;......return ret;
}

linux V4L2子系统——v4l2的结构体(1)之v4l2_device相关推荐

  1. linux V4L2子系统——v4l2架构(3)之video_device

    linux V4L2子系统--v4l2架构(3)之video_device 备注:   1. Kernel版本:5.4   2. 使用工具:Source Insight 4.0   3. 参考博客: ...

  2. Linux中表示“时间”的结构体和相关函数

    转载于:http://blog.chinaunix.net/uid-25909722-id-2827364.html Linux中表示"时间"的结构体和相关函数 2011-09-1 ...

  3. Linux学习-文件IOA1——用结构体和文件操作函数实现文件的拷贝

    Linux学习-文件IOA1--用结构体和文件操作函数实现文件的拷贝 其实我们不必选用结构体去实现模仿拷贝功能的,但是为了锻炼我们的思维以及对结构体.文件操作函数的使用,所以我们就这样来折腾自己. 学 ...

  4. Linux进程描述符task_struct结构体简析

    进程是处于执行期的程序以及它所管理的资源(如打开的文件.挂起的信号.进程状态.地址空间等等)的总称 Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个 ...

  5. Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)

    转自:http://blog.csdn.net/gatieme/article/details/51383272 日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux- ...

  6. linux驱动 cdev,inode结构体

    前面我们学习了字符设备结构体cdev  Linux 字符设备驱动开发 (一)-- 字符设备驱动结构(上)  下面继续学习字符设备另外几个重要的 数据结构. 先看下面这张图,这是Linux 中虚拟文件系 ...

  7. Linux串口通信之termios结构体说明

    termios结构体中,该结构体一般包括如下的成员: tcflag_t c_iflag; tcflag_t c_oflag; tcflag_t c_cflag; tcflag_t c_lflag; c ...

  8. Linux串口通信之termios结构体

    转 termios结构体的详细设置 2012年08月20日 23:42:47 阅读数:5210 termios结构体内容: 查看全文 http://www.taodudu.cc/news/show-4 ...

  9. Linux进程描述符task_struct结构体

    进程是处于执行期的程序以及它所管理的资源(如打开的文件.挂起的信号.进程状态.地址空间等等)的总称.进程的两个基本元素是程序和代码相关的数据集,进程是一种动态描述,但是并不代表所有的进程都在运行.每个 ...

  10. 深入理解Linux进程描述符task_struct结构体

    进程是处于执行期的程序以及它所管理的资源(如打开的文件.挂起的信号.进程状态.地址空间等等)的总称.注意,程序并不是进程,实际上两个或多个进程不仅有可能执行同一程序,而且还有可能共享地址空间等资源. ...

最新文章

  1. Case When 解决简单的是与否
  2. android 保存 用户名和密码 设置等应用信息优化
  3. 被前公司辞退后,前领导打电话命令你给前同事解释代码,该怎么办?
  4. Java 接口实现计算器加减乘除(字符交互界面)
  5. 微信 商城 php,PHP微信商城
  6. 透露抖音、腾讯、阿里、美团招开发岗位硬核面试题,轻轻松松收到offer
  7. zabbix mysql 8g优化_zabbix mysql调优
  8. tensoflow_yolov3 计算平均识别个数(平均识别数)
  9. 2007年处女星座全年运势预测
  10. 《Java并发编程的艺术》一一第2章Java并发机制的底层实现原理
  11. Android中文图混排时文图的居中对齐 FontMetrics以及自定义ImageSpan实现
  12. 多核对mysql好处_多核和MySQL性能
  13. [obc学习日记]3.10
  14. 运动目标跟踪(四)--搜索算法优化搜索方向之Camshift
  15. 使用树莓派 Raspberry Pi 播放豆瓣 FM
  16. 简易cad导出pdf程序源码
  17. 台式计算机如何连接投影仪,电脑如何链接投影仪_台式电脑主机怎么连接投影仪-win7之家...
  18. ASP.NET MVC4 微信公众平台开发测试一: 验证
  19. 计算机是指能根据给定程序自动,001第1章 计算机基础.ppt
  20. 人渣!鄂尔多斯一男子发布前女友裸照,被警方拘留!

热门文章

  1. latex中标题的使用
  2. 为孩子进行启蒙教育的6种基本思维导图类型分析
  3. Java虚拟机之堆空间
  4. 一套绝佳的自定义3dmax快捷键!
  5. FeedSky更新出现很大延时
  6. 全国软件工程专业大学排名!你报考的大学排第几?
  7. laravel Excel 3.1 列宽设置不起作用
  8. 测试技术总监需要具备哪些能力
  9. java jar apktool,apktool下载
  10. 全国哀悼日,网站变成黑白色