主要分析来自下面一篇文章。
http://www.chinaaet.com/article/3000015768 


/*
由mach-smdk6410.c文件可知,内核启动时将所有platform_device
包括 s3c_device_fimc0 s3c_device_fimc1
挂载到platform总线。
*//*
dev-fimc0.c
*/
struct platform_device s3c_device_fimc0 = {.name          = "s3c-fimc",.id          = 0,.num_resources      = ARRAY_SIZE(s3c_fimc0_resource),.resource      = s3c_fimc0_resource,
};
/*
dev-fimc1.c
*/
struct platform_device s3c_device_fimc1 = {.name          = "s3c-fimc",.id          = 1,.num_resources      = ARRAY_SIZE(s3c_fimc1_resource),.resource      = s3c_fimc1_resource,
};
/*
mach-smdk6410.c
*/
static struct platform_device *smdk6410_devices[] __initdata =
{&s3c_device_hsmmc0,&s3c_device_hsmmc1,&s3c_device_i2c0,&s3c_device_fb,&s3c_device_ohci,&s3c_device_usb_hsotg,&samsung_asoc_dma,&samsung_device_keypad,&gpio_button_device,&s3c_device_nand,
#ifdef CONFIG_DM9000&s3c_device_dm9000,
#endif&s3c64xx_device_ac97,&s3c_device_rtc,&s3c_device_ts,&s3c_device_fimc0,//FIMC 设备&s3c_device_fimc1,&s3c_device_wdt, &s3c_device_vpp,&s3c_device_mfc,&s3c_device_tvenc,&s3c_device_tvscaler,&s3c_device_rotator,&s3c_device_jpeg,&s3c_device_g2d,&s3c_device_g3d,&s3c64xx_device_spi0,&s3c64xx_device_spi1,
};
platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
/*
platform总线的match函数将device和driver匹配之后,
会自动调用s3c_fimc_driver中指定的probe函数探测设备、
申请内存资源、申请中断等,
并将最终形成的platform_device类型数据保存到内核中,
供后续使用。
*/
/*
s3c_fimc_core.c
*/
static int s3c_fimc_probe(struct platform_device *pdev)
{struct s3c_platform_fimc *pdata;struct s3c_fimc_control *ctrl;struct clk *srclk;int ret;ctrl = s3c_fimc_register_controller(pdev);if (!ctrl) {err("cannot register fimc controller\n");goto err_fimc;}pdata = to_fimc_plat(&pdev->dev);if (pdata->cfg_gpio)pdata->cfg_gpio(pdev);/* fimc source clock */srclk = clk_get(&pdev->dev, pdata->srclk_name);if (IS_ERR(srclk)) {err("failed to get source clock of fimc\n");goto err_clk_io;}/* fimc clock */ctrl->clock = clk_get(&pdev->dev, pdata->clk_name);if (IS_ERR(ctrl->clock)) {err("failed to get fimc clock source\n");goto err_clk_io;}/* set parent clock */clk_enable(ctrl->clock);/* things to initialize once */if (ctrl->id == 0) {ret = s3c_fimc_init_global(pdev);if (ret)goto err_global;}/*注册 video4linux devices*/ret = video_register_device(ctrl->vd, VFL_TYPE_GRABBER, ctrl->id);if (ret) {err("cannot register video driver\n");goto err_video;}info("controller %d registered successfully\n", ctrl->id);return 0;
err_video:clk_put(s3c_fimc.cam_clock);
err_global:clk_disable(ctrl->clock);clk_put(ctrl->clock);
err_clk_io:s3c_fimc_unregister_controller(pdev);
err_fimc:return -EINVAL;}
static struct platform_driver s3c_fimc_driver = {.probe        = s3c_fimc_probe,.remove        = s3c_fimc_remove,.suspend    = s3c_fimc_suspend,.resume        = s3c_fimc_resume,.driver        = {.name    = "s3c-fimc",.owner    = THIS_MODULE,},
};/*video_device结构体包括fops、ioctl_ops、release、name、vf_type几个成员变量,
其中,最重要的是file_operations类型的[fops]  和  v4l2_ioctl_ops类型的[ioctl_ops],
分别实现文件操作接口和V4L2接口。
*/
struct video_device s3c_fimc_video_device[S3C_FIMC_MAX_CTRLS] = {[0] = {.vfl_type = VID_TYPE_OVERLAY | VID_TYPE_CAPTURE | VID_TYPE_CLIPPING | VID_TYPE_SCALES,.fops = &s3c_fimc_fops,.ioctl_ops = &s3c_fimc_v4l2_ops,.release  = s3c_fimc_vdev_release,.name = "sc3_video0",},[1] = {.vfl_type = VID_TYPE_OVERLAY | VID_TYPE_CAPTURE | VID_TYPE_CLIPPING | VID_TYPE_SCALES,.fops = &s3c_fimc_fops,.ioctl_ops = &s3c_fimc_v4l2_ops,.release  = s3c_fimc_vdev_release,.name = "sc3_video1",},[2] = {.vfl_type = VID_TYPE_OVERLAY | VID_TYPE_CAPTURE | VID_TYPE_CLIPPING | VID_TYPE_SCALES,.fops = &s3c_fimc_fops,.ioctl_ops = &s3c_fimc_v4l2_ops,.release  = s3c_fimc_vdev_release,.name = "sc3_video2",},
};struct video_device
{/* device ops */const struct v4l2_file_operations *fops;/* sysfs */struct device dev;        /* v4l device */struct cdev *cdev;        /* character device *//* Set either parent or v4l2_dev if your driver uses v4l2_device */struct device *parent;        /* device parent */struct v4l2_device *v4l2_dev;    /* v4l2_device parent *//* Control handler associated with this device node. May be NULL. */struct v4l2_ctrl_handler *ctrl_handler;/* device info */char name[32];int vfl_type;/* 'minor' is set to -1 if the registration failed */int minor;u16 num;/* added for TV */int type2;int users;/* use bitops to set/clear/test flags */unsigned long flags;/* attribute to differentiate multiple indices on one physical device */int index;/* V4L2 file handles */spinlock_t        fh_lock; /* Lock for all v4l2_fhs */struct list_head    fh_list; /* List of struct v4l2_fh */int debug;            /* Activates debug level*//* Video standard vars */v4l2_std_id tvnorms;        /* Supported tv norms */v4l2_std_id current_norm;    /* Current tvnorm *//* callbacks */void (*release)(struct video_device *vdev);/* ioctl callbacks */const struct v4l2_ioctl_ops *ioctl_ops;
};
/*
s3c_fimc_core.c
FIMC驱动遵循V4L2接口标准,其file_operations接口定义如下:
当应用程序通过系统调用open()打开摄像头设备时,内核会最终找到s3c_fimc_open()
函数来打开摄像头。
应用程序通过read()获取图像数据,该函数通过copy_to_user()
将内核空间所申请缓冲区中图像数据拷贝到用户空间中开辟的图像数据区。
该函数没有充分利用FIMC接口提供的ping-pong缓冲区,按字进行拷贝(memcpy),
十分耗时。
mmap函数将内核空间中申请到的图像缓冲区映射到应用程序所在的用户空间,
这样,应用程序申请到的buffer将指向内核空间的图像缓冲区,应用程序可以
(不拷贝)直接对图像进行操作。该函数配合V4L2标准中的环形缓冲区队列,
节省了应用程序读取图像数据所消耗的时间。
*/
static const struct v4l2_file_operations s3c_fimc_fops = {
//static const struct file_operations s3c_fimc_fops = {.owner = THIS_MODULE,.open = s3c_fimc_open,.release = s3c_fimc_release,.unlocked_ioctl = video_ioctl2,.read = s3c_fimc_read,.write = s3c_fimc_write,.mmap = s3c_fimc_mmap,.poll = s3c_fimc_poll,
};
/*
s3c_fimc_v4l2.c
*//*************************应用程序通过ioctl接口使用这些函数,比如ioctl(fd,VIDIOC_S_FMT,&fmt)
用来设置图像格式,此时V4L2会将VIDIOC_S_FMT命令映射为s3c_fimc_v4l2_s_fmt_vid_cap()函数,
并将fmt指定的格式告知FIMC接口,FIMC会将OV9650传递过来的原始图像数据经过类型转换传递回应用程序。
s3c_fimc_v4l2_reqbufs()用于申请图像缓冲区,
该函数为应用程序在内核空间开辟ping-pong缓冲区。s3c_fimc_v4l2_qbuf()
函数将缓冲区组成环形缓冲队列,当应用程序需要调用图像数据时,使用s3c_fimc_v4l2_dqbuf()
使指定的缓冲区出队,缓冲区在出队期间,不会被新来的图像数据覆盖,
新到的图像数据会被传送到环形队列中指定缓冲区的下一个缓冲区。
由于FIMC控制器为P通道和C通道分别开辟了4个缓冲区,在内核初始化时已经申请到,
因此FIMC驱动中并不需要再重新申请。*************************/
const struct v4l2_ioctl_ops s3c_fimc_v4l2_ops = {.vidioc_querycap        = s3c_fimc_v4l2_querycap,.vidioc_g_fbuf            = s3c_fimc_v4l2_g_fbuf,.vidioc_s_fbuf            = s3c_fimc_v4l2_s_fbuf,.vidioc_enum_fmt_vid_cap    = s3c_fimc_v4l2_enum_fmt_vid_cap,.vidioc_g_fmt_vid_cap        = s3c_fimc_v4l2_g_fmt_vid_cap,.vidioc_s_fmt_vid_cap        = s3c_fimc_v4l2_s_fmt_vid_cap,.vidioc_try_fmt_vid_cap        = s3c_fimc_v4l2_try_fmt_vid_cap,.vidioc_try_fmt_vid_overlay    = s3c_fimc_v4l2_try_fmt_overlay,.vidioc_overlay            = s3c_fimc_v4l2_overlay,.vidioc_g_ctrl            = s3c_fimc_v4l2_g_ctrl,.vidioc_s_ctrl            = s3c_fimc_v4l2_s_ctrl,.vidioc_streamon        = s3c_fimc_v4l2_streamon,.vidioc_streamoff        = s3c_fimc_v4l2_streamoff,.vidioc_g_input            = s3c_fimc_v4l2_g_input,.vidioc_s_input            = s3c_fimc_v4l2_s_input,.vidioc_g_output        = s3c_fimc_v4l2_g_output,.vidioc_s_output        = s3c_fimc_v4l2_s_output,.vidioc_enum_input        = s3c_fimc_v4l2_enum_input,.vidioc_enum_output        = s3c_fimc_v4l2_enum_output,.vidioc_reqbufs            = s3c_fimc_v4l2_reqbufs,.vidioc_querybuf        = s3c_fimc_v4l2_querybuf,.vidioc_qbuf            = s3c_fimc_v4l2_qbuf,.vidioc_dqbuf            = s3c_fimc_v4l2_dqbuf,.vidioc_cropcap            = s3c_fimc_v4l2_cropcap,.vidioc_g_crop            = s3c_fimc_v4l2_g_crop,.vidioc_s_crop            = s3c_fimc_v4l2_s_crop,.vidioc_s_parm            = s3c_fimc_v4l2_s_parm,
};

在内核中加入打印。追踪ok6410 官方camera 测试程序运行过程。

--s3c_fimc_probe
---[CAM]s3c_fimc_register_controller.id=0
--[CAM]s3c_fimc_set_active_camera,id=0
s3c_fimc_init_global s3c_fimc.cam_clock=-1065304896
--video_register_device
device: 'video0': device_add
s3c-fimc: controller 0 registered successfully
driver: 's3c-fimc.0': driver_bound: bound to device 's3c-fimc'
bus: 'platform': really_probe: bound device s3c-fimc.0 to driver s3c-fimc
bus: 'platform': driver_probe_device: matched device s3c-fimc.1 with driver s3c-fimc
bus: 'platform': really_probe: probing driver s3c-fimc with device s3c-fimc.1
--s3c_fimc_probe
---[CAM]s3c_fimc_register_controller.id=1
--[CAM]s3c_fimc_set_active_camera,id=0
--video_register_device
device: 'video1': device_add
s3c-fimc: controller 1 registered successfully
driver: 's3c-fimc.1': driver_bound: bound to device 's3c-fimc'
bus: 'platform': really_probe: bound device s3c-fimc.1 to driver s3c-fimc
s3c-fimc: 

--info ov965x_init
bus: 'i2c': add driver ov965x
bus: 'i2c': driver_probe_device: matched device 0-0030 with driver ov965x
bus: 'i2c': really_probe: probing driver ov965x with device 0-0030
s3c-fimc: 

--ov965x_probe
[CAM]s3c_fimc_register_camera,cam->id=0
s3c_fimc.cam_clock = c080bcc0
parent clock for camera: 266.000 MHz, divisor: 11
[CAM]RESET CAM.[CAM]Reset and init reg!1cam->client=cc460c00
[CAM]Reset and init reg!1
[CAM]Reset and init reg!2
--[CAM]s3c_fimc_init_camera
[CAM]I2C_CAM_INIT.
--[CAM]s3c_fimc_init_camera
--[CAM]s3c_fimc_init_camera
[CAM]Reset and init reg!3
s3c-fimc: //OV9650 寄存器设置

--reg 12  80
--reg ff  0a
--reg 6a  3e
--reg 3b  09
--reg 13  8f
--reg 01  80
--reg 02  80
--reg 00  00
--reg 10  00
--reg 35  91
--reg 0e  a0
--reg 1e  34
--reg a8  80
--reg 04  00
--reg 0c  04
--reg 0d  80
--reg 11  81
--reg 12  40
--reg 37  91
--reg 38  12
--reg 39  43
--reg 18  c6
--reg 17  26
--reg 32  ad
--reg 03  00
--reg 1a  3d
--reg 19  01
--reg 3f  a6
--reg 14  2e
--reg 15  10
--reg 41  02
--reg 42  08
--reg 1b  00
--reg 16  06
--reg 33  e2
--reg 34  bf
--reg 96  04
-reg 3a  00
--reg 8e  00
--reg 3c  77
--reg 8b  06
--reg 94  88
--reg 95  88
--reg 40  c1
--reg 29  3f
--reg 0f  42
--reg 3d  92
--reg 69  40
--reg 5c  b9
--reg 5d  96
--reg 5e  10
--reg 59  c0
--reg 5a  af
--reg 5b  55
-reg 43  f0
--reg 44  10
--reg 45  68
--reg 46  96
--reg 47  60
--reg 48  80
--reg 5f  e0
--reg 60  8c
--reg 61  20
--reg a5  d9
--reg a4  74
--reg 8d  02
--reg 4f  3a
--reg 50  3d
--reg 51  03
--reg 52  12
--reg 53  26
--reg 54  36
--reg 55  45
--reg 56  40
--reg 57  40
--reg 58  0d
--reg 8c  23
--reg 3e  02
--reg a9  b8
--reg aa  92
--reg ab  0a

--reg 8f  df
--reg 90  00
--reg 91  00
--reg 9f  00
--reg a0  00
--reg 3a  01
--reg 24  70
--reg 25  64
--reg 26  c3
--reg 2a  00
--reg 2b  00
--reg 6c  40
--reg 6d  30
--reg 6e  4b
--reg 6f  60
--reg 70  70
--reg 71  70
--reg 72  70
--reg 73  70
--reg 74  60
--reg 75  60
--reg 76  50
--reg 77  48
--reg 78  3a
--reg 79  2e
--reg 7a  28
--reg 7b  22
--reg 7c  04
--reg 7d  07
-reg 7e  10
--reg 7f  28
-reg 80  36
--reg 81  44
-reg 82  52
--reg 83  60
 
--reg 84  6c
--reg 85  78
--reg 86  8c
--reg 87  9e
--reg 88  bb
--reg 89  d2
--reg 8a  e6
driver: '0-0030': driver_bound: bound to device 'ov965x'
bus: 'i2c': really_probe: bound device 0-0030 to driver ov965x

Please press Enter to activate this console. device: 'vcs2': device_add
device: 'vcsa2': device_add
device: 'vcs4': device_add
device: 'vcsa4': device_add
device: 'vcs3': device_add
device: 'vcsa3': device_add
touch...

[root@FORLINX6410]# 
[root@FORLINX6410]# ls
adctest             keytest             sbin
at24c08test         ledtest             sdcard
bin                 lib                 spitest
camera              linuxrc             sys
dev                 mnt                 tmp
duhuitest           mpu6050             uarttest
etc                 nfs.txt             udisk
fork                opt                 udp
gpio                ov9650              usr
iictest             proc                var
key_workqueue_test  root                w25q128
[root@FORLINX6410]# cd camera
[root@FORLINX6410]# ls
422jpeg.h    Makefile     testcamera   v4l2.c       videodev.h   videodev2.h


[root@FORLINX6410]# ./testcamera

//运行testcamera,开始显示图片
Start Main ---v4l2_open  id=0
--v4l2 get
--[CAM]s3c_fimc_open.id=0
--[CAM]ctrl->in_cam->width=640
s3c_fimc_v4l2_s_fmt_vid_cap filp=cbcd4f00,fh=c08bbed0,f=cbccf000
s3c_fimc_alloc_output_memory width 140  height f0 format 0 buf_size = 26000
s3c_fimc_v4l2_streamon is called
--[CAM]s3c_fimc_init_camera
--v4l2 read
---s3c_fimc_read

already open the devicise codec 
Before openning FB 
VIDIOC_S_FMT is c0cc5605
VIDIOC_STREAMON is 40045612
start to get pic 0
display 153600
--v4l2 read
---s3c_fimc_read
display 153600
--v4l2 read
---s3c_fimc_read
display 153600

OK6410 V4L2 分析相关推荐

  1. 基于全志A64平台v4l2驱动分析

    纪念再一次使用这里,刚好开通好博客,写下近年来的第一篇. 最近要做一个全志A64平台的vfe驱动培训,组织了下v4l2与vfe驱动分析.这里记录下. 全志A64芯片csi部份不自带isp(其实是有带一 ...

  2. DM6446开发攻略:V4L2视频驱动和应用分析

    针对DAVINCI DM6446平台,网络上也有很多网友写了V4L2的驱动,但只是解析Montavistalinux-2.6.10 V4L2的原理.结构和函数,深度不够.本文决定把Montavista ...

  3. v4l2驱动框架_【干货分享】Xilinx Linux V4L2视频管道(Video Pipeline)驱动程序分析...

    作者:付汉杰,hankf@xilinx.com, 文章转载自:赛灵思中文社区论坛 概述 Xilinx提供了完整的V4L2的驱动程序,Xilinx V4L2 driver.处于最顶层的驱动程序是V4L2 ...

  4. 基于OK6410开发板Uboot源码简单分析

    2018-04-07 OK6410开发板是基于三星S3C6410芯片设计的一款开发板,资源比较丰富,可是想要使用这些资源就需要编写相应的启动引导程序,即BootLoader.当然,想要自己凭空写出Bo ...

  5. V4L2 驱动层分析

    一.Camera V4L2 驱动层分析 Linux系统中视频输入设备主要包括以下四个部分: 1.字符设备驱动:V4L2本身就是一个字符设备,具有字符设备所有的特性,暴露接口给用户空间: 2.V4L2驱 ...

  6. linux v4l2架构分析之v4l2_ctrl_handler初始化及添加v4l2_ctrl的过程分析

    本文根据原代码分析v4l2的handler初始化以及添加ctrl的过程,会涉及v4l2_ctrl_handler.v4l2_ctrl.v4l2_ctrl_ref结构体的分析,以及介绍v4l2_ctrl ...

  7. v4l2架构专题模块handler分析 -- handler ctrl的注册2

    Linux v4l2架构学习总链接 上一篇文章中忽略了ctrl class,这里补上 static int handler_new_ref(struct v4l2_ctrl_handler *hdl, ...

  8. v4l2架构专题模块handler分析 --- handler的初始化及handler ctrl注册

    Linux v4l2架构学习总链接 handler初始化代码调用如下: v4l2_ctrl_handler_init(handler, 9); 对应源码: #define v4l2_ctrl_hand ...

  9. 基于Ti Omap3x 分析v4l2架构

    1 概述 本文将基于Ti Omap3x这个典型的实例来分析v4l2在具体media场景中的应用.通过分析app层的行为以及driver层的实现来对整个多媒体框架有一个大概的认识.内容主要包括主要包括v ...

最新文章

  1. ORACLE选择hint,ORACLE中的的HINT详解
  2. MaterialImageView
  3. 事务管理最佳实践全面解析
  4. 一步一图一代码之排序二叉树
  5. 033_NavMenu导航菜单
  6. android 跑分软件,跑分软件安兔兔公布了6月份Android手机性能榜TOP10
  7. Python自动化开发 - RESTful API
  8. overfitting(过度拟合)的概念
  9. Mac OS X终端的常用操作命令(UNIX指令)
  10. 【Linux系统编程学习】C库IO函数与系统IO函数的关系
  11. [Ext JS6] Grid 某些行不允许删除和选择的实现
  12. tensorflow Image 解码函数
  13. C - The Smallest String Concatenation CodeForces - 632C(按字典序列排列 )string或者数组
  14. 用nunit时,老是搞忘英文,在这里记录一下,方便到处查阅
  15. Mysql中间件代理 Atlas
  16. uniapp封装request
  17. 智慧监狱(所)设计方案
  18. 微信小程序头像怎么改变形状_微信小程序 open-data更改样式 open-data 显示头像 圆形...
  19. 拍照解数独之识别数独图片
  20. 76位健康专家共荐防病36计

热门文章

  1. 计算机通信中应用的调制解调与无线电通信,计算机通讯中的一对搭档——调制解调器和通讯软件...
  2. 办公室装修的五要四不要
  3. 深入详解python高级特性——函数柯里化(Currying)与反柯里化
  4. 太上玄门日诵晚课仙经
  5. RF信号下采样/矩阵下采样(附python实现代码)
  6. nn.Linear()函数详解及代码使用
  7. Swin-Unet跑自己的数据集(Transformer用于语义分割)
  8. 中科院大学计算机科学与技术王伟强,王伟强 - 中国科学院大学 - 计算机科学与技术学院...
  9. 努比亚android最高版本,努比亚Z11安卓7.1固件开发版下载地址:新增压力按键等功能...
  10. 计算机系统文件夹打不开,电脑系统的文件夹打不开可以试下这两个办法