当前位置:编程学习 > 网站相关 >>

v4l2,camera笔记

     开始学习v4l2中camera的架构
 
    app调用v4l2框架,然后v4l2框架再调用具体的驱动
 
     如:在app:open----->v4l2:open------->driver:open
\
 
   v4l2提供的是一个通用的框架,然后驱动去实现具体的内容。
 
   问题:那么v4l2是怎么调用driver的呢?
 
           这个我们看看相关代码就很清楚了。
 
//drivers/media/video/v4l2-dev.c
 
[html]  
static int v4l2_open(struct inode *inode, struct file *filp)  
{  
    printk("<6>\nsong:**************v4l2_open************\n");  
    struct video_device *vdev;  
    int ret = 0;  
  
    /* Check if the video device is available */  
    mutex_lock(&videodev_lock);  
       <span style="color:#FF0000;"> //这里就是从我们的在驱动中注册的video_device->cdev得到video_device.  
    vdev = video_devdata(filp);</span>  
    /* return ENODEV if the video device has been removed  
       already or if it is not registered anymore. */  
    if (vdev == NULL || !video_is_registered(vdev)) {  
        mutex_unlock(&videodev_lock);  
        return -ENODEV;  
    }  
    /* and increase the device refcount */  
    video_get(vdev);  
    mutex_unlock(&videodev_lock);  
        <span style="color:#FF0000;">//调用在驱动注册的open方法  
    if (vdev->fops->open)  
        ret = vdev->fops->open(filp);</span>  
  
    /* decrease the refcount in case of an error */  
    if (ret)  
        video_put(vdev);  
    return ret;  
}  
 
 
  其它操作和open操作是一样的。
 
下面来看具体的驱动代码:
 
1.首先dcam_init()
 
在初始化的时候要注册一个platform driver:
 
platform_driver_register(&dcam_driver) 
 
然后进行相关初始化:create_instance(i)
 
相关代码:
 
[cpp]  
int __init dcam_v4l2_init(void)  
{  
    int ret = 0, i;  
      
    if(platform_driver_register(&dcam_driver) != 0) {  
        printk("platform device register Failed \n");  
        return -1;  
    }  
       // 省略  
          
        ret = create_instance(i);      
         
  
        // 省略  
  
return ret;}  
  
static struct platform_driver dcam_driver = {  
    .probe    = dcam_probe,  
    .remove   = dcam_remove,  
    .driver   = {  
        .owner = THIS_MODULE,  
        .name = "XXXXX_dcam",  
    },  
};  
  
static int __init create_instance(int inst)  
{  
    struct dcam_dev *dev;  
    struct video_device *vfd;  
    int ret, i;  
  
    dev = kzalloc(sizeof(*dev), GFP_KERNEL);  
    if (!dev)  
        return -ENOMEM;  
  
    snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),  
            "%s-%03d", DCAM_MODULE_NAME, inst);  
    ret = v4l2_device_register(NULL, &dev->v4l2_dev);  
//初始化v4l2_device  
    if (ret)  
        goto free_dev;  
  
    /* init video dma queues */  
    INIT_LIST_HEAD(&dev->vidq.active);  
    init_waitqueue_head(&dev->vidq.wq);  
  
    /* initialize locks */  
    spin_lock_init(&dev->slock);  
    mutex_init(&dev->mutex);  
  
    ret = -ENOMEM;  
//为video_device分配内存  
    vfd = video_device_alloc();  
    if (!vfd)  
        goto unreg_dev;  
//为vfd赋值  
    *vfd = dcam_template;  
    vfd->debug = debug;  
//注册video_device,主要作用是注册cdev,具体看实现,这个函数很重要  
    ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);  
    if (ret < 0)  
        goto rel_vdev;  
  
    video_set_drvdata(vfd, dev);  
  
    /* Set all controls to their default value. */  
    for (i = 0; i < ARRAY_SIZE(dcam_qctrl); i++)  
        dev->qctl_regs[i] = dcam_qctrl[i].default_value;  
  
    /* Now that everything is fine, let's add it to device list */  
    list_add_tail(&dev->dcam_devlist, &dcam_devlist);  
  
    snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",  
            dcam_template.name, vfd->num);  
  
    if (video_nr >= 0)  
        video_nr++;  
  
    dev->vfd = vfd;  
    v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n",  
            vfd->num);  
    return 0;  
  
rel_vdev:  
    video_device_release(vfd);  
unreg_dev:  
    v4l2_device_unregister(&dev->v4l2_dev);  
free_dev:  
    kfree(dev);  
    return ret;  
} &n
补充:综合编程 , 其他综合 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,