- Camera成像原理
-
景物通过镜头生成的光学图像投射到图像传感器上,然后转为模拟的电信号,经过A/D模数转换器后转换成数字信号,再把数字信号传输到DSP数字信号处理芯片加工处理,再通过IO接口传输到CPU中处理,再通过LCSD就可以看到图像了。
**图像传感器(sensor)**是一种半导体芯片,其表面包含有几十万到几百万的光电二极管。光电二极管受到光照射时,就会产生电荷。目前的sensor有两种
-
CCD(Charge Couple Device)电荷耦合器件,它是目前高像素类 sensor
中比较成熟的成像器件,是以一行为单位的电流信号。 -
CMOS(Complementary Metal Oxide
Semiconductor),互补金属氧化物半导体。CMOS的信号是以点为单位的电荷信号,更为敏感,速度也更快,更为省电。 -
ISP 的性能是决定影像流畅的关键,JPEG encoder 的性能也是关键指标之一。而 JPEG encoder 又分为硬件 JPEG
压缩方式,和软件 RGB 压缩方式。 -
DSP 控制芯片的作用是:将感光芯片获取的数据及时快速地传到 baseband
中并刷新感光芯片,因此控制芯片的好坏,直接决定画面品质(比如色彩饱和度、清晰度)与流畅度。
Camera 常见的数据输出格式
常见的数据输出格式有:Rawdata 格式、YUV 格式、RGB 格式。
-
RGB 格式:采用这种编码方法,每种颜色都可用三个变量来表示红色、绿色以及蓝色的强度。每一个像素有三原色 R 红色、G 绿色、B
蓝色组成。 -
YUV 格式:其中“Y”表示明亮度(Luminance 或 Luma),就是灰阶值;而“U”和“V”表示色度(Chrominance 或
Chroma),是描述影像色彩及饱和度,用于指定像素的颜色。 -
RAW DATA 格式:是 CCD 或 CMOS
在将光信号转换为电信号时的电平高低的原始记录,单纯地将没有进行任何处理的图像数据,即摄像元件直接得到的电信号进行数字化处理而得到的。
camera开机流程
- poweron上电开机,然后通过i2c地址匹配i2c通讯,rest和powerdown上电(上电代码在kd_camera_hw.c中的kdCISModulePowerOn,主要有VCAM:主要给ISP供电,VCAM_IO:数字IO电源,主要给I2C供电,VCAMA:模拟供电,主要给感光区和ADC部分供电,VCAMAF:主要给对焦马达供电;具体根据datasheet添加,有时会影响cts)
,读取sensor的ID(具体ic驱动里面的open和get_imgsensor_id都有读取id的操作,sensor
id只要大于0、小于0xffffffff都是合法的。),然后软复位,下载preview参数为预览做准备,下载capture为拍照做准备,然后执行下电操作。
总结
-
HAL层运行Search sensor这个线程
-
HAL层遍历sensorlist列表并挂载HAL层性能3A等一些参数获取的接口
-
HAL层下达setDriver的cmd,并下传正在遍历的sensorlist列表中的ID
-
Driver层根据这个ID,挂载Driver层sensorlist中对应的Sensorlist中对应的Sensor和具体Sensor底层操作接口(例如Sub_GC2355_MIPI_RAW_SensorInit)
-
HAL层对正确遍历的sensor下达check ID的指令
-
Driver层为对应sensor上电,通过I2C读取预存在寄存器中的sensor id
-
比较读取ID结果(配置的和读到的ID),不匹配,return error,继续遍历
匹配,HAL层下达其他指令收集sensor信息 -
最后sensor下电
-MT6580 平台 Camera 驱动整体框架
- 整个框架分为三个部分:hal部分逻辑调用,kernel层的通用驱动sensorlist.c 和具体IC的驱动
xxxx_mipi_raw.c,kernel起来后不会直接去访问硬件sensor,而是会注册相关的驱动,之后Android系统起来后会启动相关的服务如:camera_service,在camera服务中会直接去访问hal,kernel驱动,进而操作camera。
Camera 驱动的具体实现
-
camera驱动先注册platform平台驱动,再注册i2c驱动,然后又为前后摄注册字符设备,封装底层方法CAMERA_HW_loctl,上层访问底层驱动时候先使用setdrivder讲具体IC的驱动入口获取,然后使用checkisalive对sensorlist中的IC进行上电,上电完成通过i2c读取设备ID,到这里,上层应用与底层驱动挂接完成,紧接着是预览拍照
-
开机时,camera完成了sensor框架的初始化,id检测,以及上下电操作。
-
Hal层在开机初始化调用文件vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6580/hal/sensor/imgsensor_drv.cpp中的impSearchSensor(pfExIdChk
pExIdChkCbf) 函数,这个函数执行4个功能: -
用GetSensorInitFuncList(&m_pstSensorInitFunc)函数获取目前所有的camera
sensor(需加log打印确认一下是获取全部sensor还是ProjectConfig.mk中配置的sensor)列表,这些 前后
camera 都在 projectconfig. mk已经设置。 -
用KDIMGSENSORIOC_X_SET_DRIVER向Kd_sensorlist.c(kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt6580) 中的CAMERA_HW_Ioctl传值,通过case分支最终调用kdSetDriver函数,根据在projectconfig.mk文件里面的main sub
camera的配置,找到相应的前后camera具体的驱动文件,即对于正在遍历的这颗sensor,挂接上具体的底层驱动接口Init函数。 -
用KDIMGSENSORIOC_T_CHECK_IS_ALIVE向Kd_sensorlist.c
中的CAMERA_HW_Ioctl(即前面讲到的上层操作底层的接口)传值,通过case分支最终调用adopt_CAMERA_HW_CheckIsAlive函数,在这个函数里开始给前面找到的所有camera上电,并通过向具体驱动里面的ioctrl函数传递SENSOR_FEATURE_CHECK_SENSOR_ID参数,最终通过case分支调用对应的函数通过I2C读取并核对是否为该sensor的
id,去识别具体的camera sensor id。 -
分别对前后已经配对了sensor id的camera执行m_pSubSensorInfo
=m_pstSensorInitFunc.pSensorInfo;通过这个函数会调用具体驱动(这里以GC2145M 的前摄像头为例) UINT32GC2145mipiGetInfo()函数,这个函数是获取sensor IC preview capture
video时的帧率 丢帧 打开时候的默认窗口,数据传输的type等基本信息 -
开应用时,camera会有上电,完成寄存器的初始配置,向上层传送基本参数及配置信息,以及preview和capture模式循环,客户端在点击对应camera图标开始进入previewcaputure
video 应用操作时候,上层应用会启动上层的服务程序去调用Imgsensor_drv.cpp文件里面的ImgSensorDrv:open(MINT32 sensorIdx)函数,通过函数KDIMGSENSORIOC_T_OPEN()最终调用具体驱动UINT32 GC2145MIPIOpen(void)这个open函数。这个函数主要目的:通过调用GC2145MIPI_Sensor_Init函数,对相关capturepreview
Video动作的3A寄存器进行初始化,从而启动相应的操作。