zoukankan      html  css  js  c++  java
  • Embeded linux之soc camera

    soc camera 子系统为分为soc camera device 和 soc camera host,并且定义了标准的接口或者回调函数.

    流程:

      1.获取传来信息,填充soc_camera_link

      2.初始化soc_camera_device(iface、device、设备号、总线类型)、加入链表

      3.

    一、/linux-3.0.35/drivers/media/video/soc_camera.c主要是用来管理接口或者回调函数.

    module_init(soc_camera_init);

    static int __init soc_camera_init(void)
    {
      int ret = bus_register(&soc_camera_bus_type);//注册单没有关联
      ...
      ret = driver_register(&ic_drv);

      ...

      ret = platform_driver_probe(&soc_camera_pdrv, soc_camera_pdrv_probe);

      ...
    }

    static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
    {

      //通过传入的参数pdev获取platform_data,即struct soc_camera_link
      struct soc_camera_link *icl = pdev->dev.platform_data;

      struct soc_camera_device *icd;

      /*

       * 分配设备结构及初始化

       */

      icd = kzalloc(sizeof(*icd), GFP_KERNEL);

      icd->iface = icl->bus_id;  //iface被初始化为bus_id
      icd->pdev = &pdev->dev;
      platform_set_drvdata(pdev, icd);

      ret = soc_camera_device_register(icd);//soc_camera_device加到全局camera device链表@devices上,并且为它分配设备号,做一些必要的初始化

      soc_camera_device_init(&icd->dev, icl);//设置soc_came_device对应device的bus为soc_camera_bus_type,这样当我们注册设备时,就会调用soc_camera_probe

      icd->user_width  = DEFAULT_WIDTH;
      icd->user_height = DEFAULT_HEIGHT;
    }

    struct soc_camera_link {
      int bus_id;                //匹配soc camera host的序号
      unsigned long flags;
      int i2c_adapter_id;            //I2C 适配器号
      struct i2c_board_info *board_info;
      const char *module_name;
      void *priv;
      struct regulator_bulk_data *regulators;  //用于电源的管理
      int num_regulators;

      /*

      *针对那些非I2C的平台的函数,用于管理sensor设备的添加或者删除

      */
      int (*add_device)(struct soc_camera_link *, struct device *);
      void (*del_device)(struct soc_camera_link *);
      int (*power)(struct device *, int);
      int (*reset)(struct device *);
      int (*set_bus_param)(struct soc_camera_link *, unsigned long flags);
      unsigned long (*query_bus_param)(struct soc_camera_link *);
      void (*free_bus)(struct soc_camera_link *);
    };

    struct soc_camera_device {
      struct list_head list;
      struct device dev;
      struct device *pdev;  
      s32 user_width;           //图像的宽度,以像素为单位
      s32 user_height;          //图像的高度,以像素为单位
      u32 bytesperline;  
      u32 sizeimage;            //一画图像的大小,也是存储图像缓冲区的大小
      enum v4l2_colorspace colorspace;  //色域,指描述色彩时所使用的坐标系
      unsigned char iface;         //于camera link中的bus_id相对应
      unsigned char devnum;  
      struct soc_camera_sense *sense; 
      struct soc_camera_ops *ops;
      struct video_device *vdev;
      const struct soc_camera_format_xlate *current_fmt;  //驱动中当前使用的视频格式
      struct soc_camera_format_xlate *user_formats;     //全部支持的视频格式
      int num_user_formats;
      enum v4l2_field field;        //决定图像源数据交错的方式
      void *host_priv;  
      int use_count;
      struct mutex video_lock; 
      struct file *streamer;  

      /*

       * 管理帧缓冲区

       */
      union {
        struct videobuf_queue vb_vidq;
        struct vb2_queue vb2_vidq;
      };
    };

    static int soc_camera_device_register(struct soc_camera_device *icd)
    {
      struct soc_camera_device *ix;
      int num = -1, i;

      for (i = 0; i < 256 && num < 0; i++) {  //判断挂接的设备是否256个设备号都占用
        num = i;
        list_for_each_entry(ix, &devices, list) {
        if (ix->iface == icd->iface && ix->devnum == i) {
          num = -1;
          break;
          }
        }
       }

      icd->devnum  = num;          //找到空闲的设备号
      icd->use_count  = 0;
      icd->host_priv  = NULL;
      mutex_init(&icd->video_lock);

      list_add_tail(&icd->list, &devices);    //将空闲的设备结构放入链表

    }

    static void soc_camera_device_init(struct device *dev, void *pdata)
    {
      dev->platform_data = pdata;
      dev->bus  = &soc_camera_bus_type;  //设置总线类型
      dev->release  = dummy_release;
    }

    struct bus_type soc_camera_bus_type = {
     .name  = "soc-camera",
     .probe  = soc_camera_probe,
     .remove  = soc_camera_remove,
     .suspend = soc_camera_suspend,
     .resume  = soc_camera_resume,
    };

    static int soc_camera_probe(struct device *dev)
    {

      ...
     ret = video_dev_create(icd);

      ...

    } 

    static int video_dev_create(struct soc_camera_device *icd)
    {
     struct video_device *vdev = video_device_alloc();

     strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));

     vdev->parent  = &icd->dev;
     vdev->current_norm = V4L2_STD_UNKNOWN;
     vdev->fops  = &soc_camera_fops;
     vdev->ioctl_ops  = &soc_camera_ioctl_ops;
     vdev->release  = video_device_release;
     vdev->tvnorms  = V4L2_STD_UNKNOWN;

     icd->vdev = vdev;

     return 0;
    }

    static struct v4l2_file_operations soc_camera_fops = {
     .owner  = THIS_MODULE,
     .open  = soc_camera_open,
     .release = soc_camera_close,
     .unlocked_ioctl = video_ioctl2,
     .read  = soc_camera_read,
     .mmap  = soc_camera_mmap,
     .poll  = soc_camera_poll,
    };

    static int soc_camera_open(struct file *file)
    {
     struct video_device *vdev = video_devdata(file);//获取video_driver信息

      ...

    /linux-3.0.35/drivers/media/video/v4l2-ioctl.c

    long video_ioctl2(struct file *file,
            unsigned int cmd, unsigned long arg)
    {
      return video_usercopy(file, cmd, arg, __video_do_ioctl);
    }

    static long __video_do_ioctl(struct file *file,
      unsigned int cmd, void *arg)
    {
      struct video_device *vfd = video_devdata(file);
      const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
      void *fh = file->private_data;

      ...

      case VIDIOC_S_CROP:
      {
        struct v4l2_crop *p = arg;

        ret = ops->vidioc_s_crop(file, fh, p);
        break;
      }

      ...

    }

    未完待续...

  • 相关阅读:
    游戏程序设计DirectX 9
    面试题1
    [python爬虫] Selenium定向爬取PubMed生物医学摘要信息
    Python简单实现基于VSM的余弦相似度计算
    [python爬虫] Selenium常见元素定位方法和操作的学习介绍
    [python爬虫] 爬取图片无法打开或已损坏的简单探讨
    [python] 安装numpy+scipy+matlotlib+scikitlearn及问题解决
    [python] 使用Jieba工具中文分词及文本聚类概念
    javascript在firefox中对Dom的处理的一个问题
    XML和DOM节点的NodeType
  • 原文地址:https://www.cnblogs.com/pokerface/p/6518154.html
Copyright © 2011-2022 走看看