3.3 应用程序中函数调用的底层执行流程

3.1节分析的probe函数中,它的核心函数video_register_devicepart3中(v4l2-core/v4l2-dev.c文件),通过vdev->cdev->ops= &v4l2_fops;将字符设备的结构体cdevfile_operations函数集指向了v4l2_fops,如下所示:

[cpp]  view plain  copy
  1. static const struct file_operations v4l2_fops = {   
  2.     .owner = THIS_MODULE,   
  3.     .read = v4l2_read,   
  4.     .write = v4l2_write,   
  5.     .open = v4l2_open,   
  6.     .get_unmapped_area = v4l2_get_unmapped_area,   
  7.     .mmap = v4l2_mmap,   
  8.     .unlocked_ioctl = v4l2_ioctl,   
  9. #ifdef CONFIG_COMPAT   
  10.     .compat_ioctl = v4l2_compat_ioctl32,   
  11. #endif   
  12.     .release = v4l2_release,   
  13.     .poll = v4l2_poll,   
  14.     .llseek = no_llseek,   
  15. };  

open函数和ioctl函数为例来分析这个底层的调用过程:

当应用程序调用open函数的时候,就会调用这个v4l2_open函数,如下所示:

[cpp]  view plain  copy
  1. static int v4l2_open(struct inode *inode, struct file *filp)   
  2. {   
  3.     struct video_device *vdev;   
  4.     int ret = 0;   
  5.   
  6.     /* Check if the video device is available */   
  7.     mutex_lock(&videodev_lock);   
  8.     vdev = video_devdata(filp);   
  9.     /* return ENODEV if the video device has already been removed. */   
  10.     if (vdev == NULL || !video_is_registered(vdev)) {   
  11.         mutex_unlock(&videodev_lock);   
  12.         return -ENODEV;   
  13.     }   
  14.     /* and increase the device refcount */   
  15.     video_get(vdev);   
  16.     mutex_unlock(&videodev_lock);   
  17.     if (vdev->fops->open) {   
  18.         if (video_is_registered(vdev))   
  19.             ret = vdev->fops->open(filp);   
  20.         else   
  21.             ret = -ENODEV;   
  22.     }   
  23.   
  24.     if (vdev->debug)   
  25.         printk(KERN_DEBUG "%s: open (%d)\n",   
  26.             video_device_node_name(vdev), ret);   
  27.     /* decrease the refcount in case of an error */   
  28.     if (ret)   
  29.         video_put(vdev);   
  30.     return ret;   
  31. }  

看这个函数,它经过一系列的判断和操作,最终通过我标红那一句,调用到video_device结构体里面fops函数集的open函数。(以上这些分析是v4l2-dev.c中的)

体现在mxc_v4l2_capture.c中就是:在init_camera_struct函数中,通过*(cam->video_dev)= mxc_v4l_template;这一句话,将video_device指向了mxc_v4l_template,所以应用程序调用open函数,最终就会依次调用mxc_v4l_template->fops->open,即

mxc_v4l_template--->mxc_v4l_fops--->mxc_v4l_open

上面分析的是应用程序如果调用open函数的话,底层函数的执行流程,最终就会执行到我们mxc_v4l2_capture.c中的mxc_v4l_open函数。


同样对于ioctl函数来说,比如应用程序调用了一个ioctl函数,作为一个字符设备,肯定会调用到v4l2_fops结构体中的v4l2_ioctl函数,ret= vdev->fops->ioctl(filp, cmd, arg);

最终在mxc_v4l2_capture.c中会依次调用mxc_v4l_template--->mxc_v4l_fops--->mxc_v4l_ioctl


mxc_v4l_ioctl函数如下所示

[cpp]  view plain  copy
  1. static long mxc_v4l_ioctl(struct file *file, unsigned int cmd,   
  2.              unsigned long arg)   
  3. {   
  4.     pr_debug("In MVC:mxc_v4l_ioctl\n");   
  5.     return video_usercopy(file, cmd, arg, mxc_v4l_do_ioctl);   
  6. }   

它通过video_usercopy函数,这个video_usercopy函数会进行一些检查及错误分析,最终会调用到mxc_v4l_do_ioctl函数,在mxc_v4l_do_ioctl函数中会根据不同的宏,通过一个switch语句来分别执行不同的过程。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值