日期:2014-05-16  浏览次数:20936 次

我对linux理解之v4l2
我们先看具体sensor slave怎么注册到v4l2的:
static struct v4l2_int_ioctl_desc ov5642_ioctl_desc[] = {//ioctl与对应的序号联系在一起,在v4l2层将被转换成固定的名字
    {vidioc_int_dev_init_num, (v4l2_int_ioctl_func *)ioctl_dev_init},
    {vidioc_int_dev_exit_num, ioctl_dev_exit},
    {vidioc_int_s_power_num, (v4l2_int_ioctl_func *)ioctl_s_power},
    {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func *)ioctl_g_ifparm},
/*    {vidioc_int_g_needs_reset_num,
                (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
/*    {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
    {vidioc_int_init_num, (v4l2_int_ioctl_func *)ioctl_init},
/*    {vidioc_int_enum_fmt_cap_num,
                (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap}, */
/*    {vidioc_int_try_fmt_cap_num,
                (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
    {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func *)ioctl_g_fmt_cap},
/*    {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *)ioctl_s_fmt_cap}, */
    {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *)ioctl_g_parm},
    {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *)ioctl_s_parm},
/*    {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func *)ioctl_queryctrl}, */
    {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *)ioctl_g_ctrl},
    {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *)ioctl_s_ctrl},
};
static struct v4l2_int_slave ov5642_slave = {//slave
    .ioctls = ov5642_ioctl_desc,
    .num_ioctls = ARRAY_SIZE(ov5642_ioctl_desc),
};

static struct v4l2_int_device ov5642_int_device = {
    .module = THIS_MODULE,
    .name = "ov5642",
    .type = v4l2_int_type_slave,
    .u = {
        .slave = &ov5642_slave,
    },
};
v4l2_int_device_register(&ov5642_int_device);//注册v4l2_int_device:
int v4l2_int_device_register(struct v4l2_int_device *d)
{
    if (d->type == v4l2_int_type_slave)
        sort(d->u.slave->ioctls, d->u.slave->num_ioctls,//按照序号存储,加快访问速度
             sizeof(struct v4l2_int_ioctl_desc),
             &ioctl_sort_cmp, NULL);
    mutex_lock(&mutex);
    list_add(&d->head, &int_list);//无论是slave还是master都会添加到int_list中
    v4l2_int_device_try_attach_all();//都会做匹配动作
    mutex_unlock(&mutex);

    return 0;
}
我们看下v4l2匹配函数v4l2_int_device_try_attach_all():
void v4l2_int_device_try_attach_all(void)
{
    struct v4l2_int_device *m, *s;

    list_for_each_entry(m, &int_list, head) {//对int_list中每个master
        if (m->type != v4l2_int_type_master)
            continue;

        list_for_each_entry(s, &int_list, head) {//对int_list中的每个salve
            if (s->type != v4l2_int_type_slave)
                continue;

            /* Slave is connected? */
            if (s->u.slave->master)//slave中master已经被赋值说明已经连接起来
                continue;

            /