Linux驱动 2026年8月6日 6 分钟

V4L2子系统6-VB2_queue三个操作函数

上面这个操作结构体可以用来实现简单结构体到复杂结构体数据转换工作 完整的注册流程(参考drivers\media\usb…

上面这个操作结构体可以用来实现简单结构体到复杂结构体数据转换工作

完整的注册流程(参考drivers\media\usb\airspy\airspy.c):

static struct video_device airspy_template = {
.name = “AirSpy SDR”,
.release = video_device_release_empty,
.fops = &airspy_fops,
.ioctl_ops = &airspy_ioctl_ops,
};

/* 构造一个vb2_queue / / Init videobuf2 queue structure */
s->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
s->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
s->vb_queue.drv_priv = s;
s->vb_queue.buf_struct_size = sizeof(struct airspy_frame_buf);
s->vb_queue.ops = &airspy_vb2_ops; // vb2_ops, 硬件相关的操作函数
s->vb_queue.mem_ops = &vb2_vmalloc_memops; // vb2_mem_ops, 辅助结构体,用于mem ops(alloc、mmap)
s->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
ret = vb2_queue_init(&s->vb_queue);
q->buf_ops = &v4l2_buf_ops; // vb2_buf_ops, 用于APP和驱动传递参数

// 分配/设置video_device结构体
s->vdev = airspy_template;
s->vdev.queue = &s->vb_queue; // 指向前面构造的vb2_queue

// 初始化一个v4l2_device结构体(起辅助作用)
/* Register the v4l2_device structure */
s->v4l2_dev.release = airspy_video_release;
ret = v4l2_device_register(&intf->dev, &s->v4l2_dev);

// video_device和4l2_device建立联系
s->vdev.v4l2_dev = &s->v4l2_dev;

// 注册video_device结构体
ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1);
__video_register_device
// 根据次设备号把video_device结构体放入数组
video_device[vdev->minor] = vdev;

        // 注册字符设备驱动程序
        vdev->cdev->ops = &v4l2_fops;
        vdev->cdev->owner = owner;
        ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);

上一篇 V4L2子系统5-videobuff2相关概念介绍

内核如何对buff进行管理呢 队列里面两个关键链表 如队列流程

下一篇 V4L2子系统7-videobuff2情景分析