1、 video_device
在 v4l2 中用 struct video_device 代表一个视频设备,该结构说明如下:
[cpp]
struct video_device
{
/* 设备操作合集 */
const struct v4l2_file_operations *fops;
/* sysfs节点 */
struct device dev; /* v4l device */
struct cdev *cdev; /* 字符设备节点 */
/* Set either parent or v4l2_dev if your driver uses v4l2_device */
struct device *parent; /* 父设备 */
struct v4l2_device *v4l2_dev; /* v4l2_device parent */
/* 设备信息 */
char name[32];
int vfl_type;
/* 如果注册失败 minor 将被设置为 -1 */
int minor;
u16 num;
/* 需要用位操作 flags */
unsigned long flags;
/* attribute to differentiate multiple indices on one physical device */
int index;
int debug; /* Activates debug level*/
/* Video standard vars */
v4l2_std_id tvnorms; /* Supported tv norms */
v4l2_std_id current_norm; /* Current tvnorm */
/* 释放设备的回调函数 */
/* ioctl 回调函数 */
const struct v4l2_ioctl_ops *ioctl_ops;
};
其中
struct cdev {
struct kobject kobj; /* 内核对象 */
struct module *owner;
const struct file_operations *ops; /* 设备操作合集 */
struct list_head list;
dev_t dev;
unsigned int count;
};
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 *); /* 释放设备 */
};
视频设备在 linux 中作为字符设备出现,域 cdev 与 /dev/videox 节点关联,打开节点就相当于执行cdev 的 open 函数,cdev 的 ops 域即 file_operations 的一些接口在经过一定的参数过滤后最终都调用了video_device 的 fops 域即v4l2_file_operations的成员,所以在编写驱动程序的时候需要实现 v4l2_file_operations 的接口:其中 open 用于打开视频设备, read 接口用于读取视频数据,poll 接口用于视频流的同步,mmap 将视频设备的保存数据的内存空间的物理地址映射到用户空间,ioctl 用于向视频设备发送命令并查询相关信息(ioctl 一般设置为 v4l2 提供的 video_ioctl2 函数,并最终调用 video_device 的 ioctl_ops 域即 v4l2_ioctl_ops),通常需要实现的 ioctl 接口如下:
[cpp]
static const struct v4l2_ioctl_ops xxx_cam_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input