函数
V4L2 events 提供一种将event传递到用户空间的通用方式。
驱动需要调用下面的函数将event添加到队列中。并且只需要填充type、data,其它的由v4l2来填充。
v4l2_event_queue (vdev, ev)
通过下面的函数来订阅event,这个函数实际上是video_device-> ioctl_ops-> vidioc_subscribe_event的具体实现。需要注意的是在驱动中要先检查驱动是否能产生指定的事件。
v4l2_event_subscribe (fh, sub , elems, ops)
ops参数可以让驱动指定一个回调函数:add,del,replace,merge。一共有4个可选的回调函数,如果不需要也可以传入NULL参数。
通过下面的函数来取消event的订阅。实际上也是video_device-> ioctl_ops-> vidioc_unsubscribe_event的具体实现。
v4l2_event_unsubscribe (fh, sub)
通过下面的函数来查看是否有挂起的事件。函数返回事件的number。
v4l2_event_pending (fh)
应用
应用程序中ioctl使用和其它功能函数类似,它的的宏定义如下:
VIDIOC_SUBSCRIBE_EVENT-订阅事件
VIDIOC_UNSUBSCRIBE_EVENT-取消订阅事件
int ioctl(int fd, VIDIOC_SUBSCRIBE_EVENT, struct v4l2_event_subscription *argp)
int ioctl(int fd, VIDIOC_UNSUBSCRIBE_EVENT, struct v4l2_event_subscription *argp)
fd: 使用open()函数返回的文件描述符
argp: 指向struct v4l2_event_subscription的指针
驱动实例
/drivers/media/platform/omap3isp/ispccdc.c
static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
if (sub->type != V4L2_EVENT_FRAME_SYNC)
return -EINVAL;
/* line number is zero at frame start */
if (sub->id != 0)
return -EINVAL;
return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
}
static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
return v4l2_event_unsubscribe(fh, sub);
}
static const struct v4l2_subdev_core_ops ccdc_v4l2_core_ops = {
.ioctl = ccdc_ioctl,
.subscribe_event = ccdc_subscribe_event,
.unsubscribe_event = ccdc_unsubscribe_event,
};
/* V4L2 subdev operations */
static const struct v4l2_subdev_ops ccdc_v4l2_ops = {
.core = &ccdc_v4l2_core_ops,
.video = &ccdc_v4l2_video_ops,
.pad = &ccdc_v4l2_pad_ops,
};
相关内容阅读
链接: V4L2框架
链接: V4L2之设备注册
链接: V4L2之mmap()函数
链接: V4L2之events
链接: V4L2之buffer分配和映射