v4l2,camera笔记
开始学习v4l2中camera的架构app调用v4l2框架,然后v4l2框架再调用具体的驱动如:在app:open----->v4l2:open------->driver:openv4l2提供的是一个通用的框架,然后驱动去实现具体的内容。问题:那么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 removedalready 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_deviceif (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补充:综合编程 , 其他综合 ,
上一个:http复习之telnet
下一个:控制母版页中的按钮是否显示