深入理解l内核v4l2框架之video for linux 2(二)

续。。。

3video_device

struct video_device{

#if defined(CONFIG_MEDIA_CONTROLLER)

struct media_entity entity;

#endif

const struct v4l2_file_operations*fops;

struct device dev; /* v4l device */

struct cdev *cdev; /* characterdevice */

struct device *parent; /* deviceparent */

struct v4l2_device *v4l2_dev; /*v4l2_device parent */

struct v4l2_ctrl_handler*ctrl_handler;

struct v4l2_prio_state *prio;

char name[32];

int vfl_type;

int minor;

u16 num;

unsigned long flags;

int index;

spinlock_t fh_lock; /* Lock forall v4l2_fhs */

struct list_head fh_list; /* List ofstruct v4l2_fh */

int debug; /* Activates debuglevel*/

v4l2_std_id tvnorms; /* Supported tvnorms */

v4l2_std_id current_norm; /* Currenttvnorm */

void (*release)(struct video_device*vdev);

const struct v4l2_ioctl_ops*ioctl_ops;

struct mutex *lock;

};

/dev中实际的设备节点使用video_deice结构创建。该结构既可以被动态创建,也可以被嵌入到更大的结构当中:

动态创建:

struct video_device *vdev =video_device_alloc();

vdec->release =video_device_release;

嵌入到更大的结构当中:

Struct video_device *vdev =&my_vdev->vdev;

vdev->relase = my_vdev_release;

要完成这个结构的初始化,还需要设置以下的域:

.v4l2_dev 设置v4l2_device父设备

.name      设置唯一的描述名

.fops        设置v4l2_file_operations结构

.ioctl_ops 使用v4l2_ioctl_ops来简化ioctl的维护

.lock         如果想在驱动中进行全局锁定的话设置为NULL,否则初始化为一个 mutex_lock,这样就可以在unlocked_ioctl的操作之前和之后对操作内容进行保护

.prio          跟踪属性。用来实现VIDIOC_G/S_PRIORITY,如果设置为NULL,将使用v4l2_device中的v4l2_prio_state

.parent     NULL . 如果硬件中有多个PCI设备共享v4l2_device核心,那么就要设置父设备。

.flags        可选,设置V4L2_FL_USE_FH_PRIO,如果想让framework来处理VIDIOC_G/S_PRIORITYioctls的话。

             如果要使用v4l2_ioctl_ops,那么就需要将.unlocked_ioctl设置为video_ioctl2,这样的话,就可以打通上层应用在使用ioctl操作/dev/videoX的时候和v4l2设备之间的信                息交换通道。

在某些应用场景下,还需要mask掉在v4l2_ioctl_ops中指定的功能,那么需要调用

            void v4l2_disable_ioctl(structvideo_device *vdev, unsigned int cmd)来屏蔽对该cmd的调用。

v4l2_file_operations结构是一个file_operations的子集,主要的区别是inode参数不再使用了,因为从来没有用到过。

Ioctlslocking域:

V4L2核心提供了可选的锁定服务,主要体现在video_device结构当中的lock域,指向一个mutex,如果你初始化了这个域,那么它将被用在unlocked_ioctl中用来序列化所有的ioctl操作。

如果使用videobuf2框架来管理视频缓冲,那么还得在初始化一个video_device->queue->lock,并且这个锁会替代video_device->lock来序列化所有队列ioctl的操作。

队列ioctl的操作使用不同的锁有个优点,就是某些设备的操作需要很长的时间,而在此期间的其他非队列ioctl操作也可以进行。举个例子,有个场景就是既要设置camera的闪光灯亮,也要从videobuf当中读取数据的时候,我们就需要分开来锁定两个ioctl,以便两者能够基本上保持同步。

videobuf2当中,需要实现wait_preparewait_finish回调函数来lock/unlock,如果想要使用queue->lock,最好是使用vb2_ops_wait_prepare/finish

video_device 的注册:

接下来,通过video_device_alloc()分配好一个video_device之后,就要把它注册到系统当中,这将会为你创建一个字符设备。

err = video_register_device(vdev,VFL_TYPE_GRABBER, -1);

if (err) {

video_device_release(vdev);

return err;

}

如果v4l2_device有一个非空的mdev,那么video_device实体也会自动注册媒体设备。

具体注册成什么类型的V4l2设备,要看type指定为什么:

VFL_TYPE_GRABBER video的输入输出设备,体现为/dev/videoX

VFL_TYPE_VBI vertical blank data体现为/dev/vbiX

VFL_TYPE_RADIO radio tuners设备/dev/radioX

第三个参数是指定设备号,如果传入-1的话,就是让v4l2框架自动选择一个可用的node号,如果指定了非-1的参数,并且这个参数代表的设备已经被注册了,那么系统也会自动选择下一个可用的设备号,但是会给出警告。

一旦一个video_device被创建,那么框架也会同时为你创建一些设备属性节点,在/sys/class/video4linux/videoX/下你会看到诸如name,index等的属性节点。

如果注册失败了,那么就要调用video_device_release()来释放所有申请的资源。


video_device的清理工作:

当要移除视频设备节点的时候,就要调用video_unregister_device(vdev)将之前注册到系统中的信息销毁掉。


一些videodevice的帮助函数

file/video_deviceprivate_data,我们可以通过以下这些函数来设置和获取驱动的private_data:

void * video_get_drvdata(structvideo_device *vdev)

void video_set_drvdata(structvideo_device *vdev, void * data)

struct video_device*video_devdata(struct file *file)会返回一个属于filevideo_device结构体指针。

Void * video_drvdata(struct file*file)首先使用video_devdata获取video_device,然后通过video_get_drvdata获取private_data.


设备节点名:

video_device_node_name(structvideo_device *vdev)返回一个字符串。

到这儿,就基本上了解了v4l2的控制框架。接下来的博文中,会介绍videobuf及videobuf2的相关知识。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值