array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 soc camera子系统 - 爱码网
pokerface

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;
  }

  ...

}

未完待续...

分类:

技术点:

相关文章: