框架图
从上图不难看出,v4l2_device作为顶层管理者,一方面通过嵌入到一个video_device中,暴露video设备节点给用户空间进行控制;另一方面,video_device内部会创建一个media_entity作为在media controller中的抽象体,被加入到media_device中的entities链表中。此外,为了保持对所从属子设备的控制,内部还维护了一个挂载了所有v4l2_subdev子设备的subdevs链表。
而对于其中每一个子设备而言,统一采用了v4l2_subdev结构体来进行描述,一方面通过嵌入到video_device,暴露v4l2_subdev子设备节点给用户空间进行控制,另一方面其内部也维护着在media controller中的对应的一个media_entity抽象体,而该抽象体也会链入到media_device中的entities链表中。
通过加入entities链表的方式,media_device保持了对所有的设备信息的查询和控制的能力,而该能力会通过media controller框架在用户空间创建meida设备节点,将这种能力暴露给用户进行控制。
Linux-v4l2框架
struct video_device {} //创建用户层设备节点
struct media_device {} //media_device_init()media_device_cleanup()media_device_register()media_device_unregister()
struct v4l2_device {} //v4l2控制器 v4l2_device_register()v4l2_device_unregister()struct v4l2_subdev { //描述摄像头等子设备
#if defined(CONFIG_MEDIA_CONTROLLER)struct media_entity entity;
#endifstruct list_head list;struct module *owner;bool owner_v4l2_dev;u32 flags;struct v4l2_device *v4l2_dev;const struct v4l2_subdev_ops *ops;const struct v4l2_subdev_internal_ops *internal_ops;struct v4l2_ctrl_handler *ctrl_handler;char name[V4L2_SUBDEV_NAME_SIZE];u32 grp_id;void *dev_priv;void *host_priv;struct video_device *devnode;struct device *dev;struct fwnode_handle *fwnode;struct list_head async_list;struct v4l2_async_subdev *asd;struct v4l2_async_notifier *notifier;struct v4l2_async_notifier *subdev_notifier;struct v4l2_subdev_platform_data *pdata;
}; v4l2_i2c_subdev_init()v4l2_spi_subdev_init()
media controller
媒体实体(Media Entity)
媒体端口(Media Pad)
媒体连接(Media Link)struct media_device {}
media_device_init()
media_device_cleanup()
media_device_register()
media_device_unregister()struct media_entity {}
media_entity_pads_init() //初始化entity pad
media_device_register_entity() //注册entity
media_device_unregister_entity()//卸载entitystruct media_pad {}
//分为sink pad输入端口和source pad输出端口
//输入端口负责接收数据,输出端口负责发送数据。struct media_link {}
media_create_pad_link()
media_entity_remove_links()
media_create_intf_link()
media_remove_intf_links()