- 概述
- MTK
camera主要的内容在hal层,现在有hal1/hal3,当下主流的使用的是hal3,驱动主要负责sensor,电源的控制以及sensor相关寄存器的操作,MTK采用设备和驱动分离的思想,抽象出imgsensor.c来控制sensor的上下电以及sensor具体的操作,结构图如下:
- sensorDriver介绍
-
对上相应需求,对下控制sensor硬件行为,处理器通过I2C接口来控制sensor的大部分行为,sensor输出的数据传输到TG、ISP等模块处理后,ISP将数据保存到内存中之后,才可以dump出sensor的数据,才能看到sensor的第一帧画面。
sensorDriver函数结构体
mgsensor_mode_struct
不同模式特征的结构体,这个结构体描叙了各个模式下的pclk/linelength/framelength 等:
pclk ≈ linelength * frame_length * framerate:
-
sensor的linelength是固定的,每个模式的pclk也是不可调的,所以要调整帧率framerate,只能调整frame_length。set_dummy使得当前帧率立刻变化为设置的帧率,如果pclk或者linelength与对应sensor
setting的实际值不一致,设置的帧率和响应的帧率会有一个偏差,画面可能出现水波纹 -
struct imgsensor_info_struct描叙sensor info常量的结构体:
struct imgsensor_struct记录sensor info变量的结构体,用于动态的保存sensor的关键信息:
驱动入口xxxx_MIPI_RAW_SensorInit:
SensorInit以函数指针的形式传入到kdSensorList结构体中:
open 函数介绍及其所完成的任务:
-
此函数在每次打开camera都会调用;
-
读取sensorid,确保I2C通讯正常;
-
调用sensor_init初始化sensor芯片;
-
初始化imgsensor结构体中的变量;
-
读取otp中信息;
feature_control接口:
-
获取linelength和pclk:
-
获取各个mode的sensor pclk(pixel/s),PCLK指pixel采样的时钟,linelength, 结合pclk来计算linetime, 用来换算ae plinetable的exposure time对应的shutter (unit: line,条数)。
**set_shutter设置曝光行:**
-
设置曝光行,曝光行物理上小于frame_length,所以曝光行大于当前frame_length时,frame_length会自动撑长,
-
帧率降低所以亮度较低时,帧率会下降,因为这时候shutter比较大。每个AE周期会根据AE算法找到的对应pline
-
table中相应index的exp转换为shutter下给driver。
-
streaming_control控制sensor输出数据:
在打开sensor输出数据前,需要先设置shutter。 -
control 模式切换函数:
以preview为例说明流程:
imgsensor作用
-
imgsensor起到承上启下的作用,系统起来时会创建整个camera驱动运行的环境,先设备挂载时会调用注册platform设备platform_driver_register,在匹配成功后调用probe函数进行初始化相关的设备。主要有以下文件:
camera的三路电压的上电方式可以通过gpio来控制,也可以通过pmic(REGULATOR)方式来进行控制,在imgsensor_hw中通过不同的pdev信息,调用不同的set函数。
-
上电相关的结构体之间的联系
IMGSENSOR_HW结构体
-
IMGSENSOR_HW结构体包含了pdev(gpio/regulator)的设备结构体和上电时序相关的结构体:
上电时序控制相关:
上电方式控制:GPIO?REGULATOR?
上电时序控制结构体:
-
系统初始化
设备加载
imgsensor和其他的驱动模块相同,也是通过module_init来初始化模块,在init中注册platform总线驱动,从而需要对应的platform_driver结构体信息
当gimgsensor_of_device_id的信息在dts上匹配成功后会回到probe函数,probe函数中主要注册了snesordrv的字符设备和初始化imgsensor的硬件信息(时钟及上电)
imgsensor_driver_register创建字符设备
imgsensor_clk_init时钟初始化:
imgsensor_hw_init电压初始化:
依次调用GPIO/REGULATOR/MCLK的init接口;
解析出imgsensor_custom_config,获取到对应sensor的对应管脚(DVDD/AVDD…)的上电方式(GPIO/REGULATOR);
imgsensor_i2c_create I2C设备初始化:、
具体类型的上电介绍(以pmic控制的regulator方式为例)
前面imgsensor_hw_init中有去调用imgsensor_hw_regulator_open和regulator_init:
传入对应的设备的device结构体:
调用对应的init进行初始化: -
因为MTK
平台的PMIC上电是通过统一的REGULATOR进行统一管理的,每一种上电方式需要申请对应type的regulator控制的结构体,才可以来进行设置:
3.Camera框架介绍
Camera框架分为Kernel部分和hal部分,其中Kernel部分主要有
-
image sensordriver
负责具体型号的sensor的id检测,上电,以及在preview、capture、初始化、3A等功能设定时的寄存器配置 -
isp driver 通过DMA将sensor数据流上传
Hal层主要分3部分
-
imageio,主要负责数据buffer上传的pipe
-
drv,包含imgsensor和isp的hal层控制
-
feature io,包含各种3A等性能配置
-
Camera启动流程
CameraService是在开机时启动的,启动后进行searchSensor的操作,会search操作,只进行camera支持数量的遍历,以及sensorID读取操作
-
searchSensor
1、在CameraDeviceManagerBase中定义enumerateDevicesLocked()方法,在CameraDeviceManagerImpl实现了它的onEnumerateDevicesLocked方法
2、CameraDeviceManagerImpl.cpp文件中函数pHalDeviceList->searchDevices()将调用HalLogicalDeviceList.cpp文件中HalLogicalDeviceList::searchDevices()函数,该函数再调用的HalLogicalDeviceList::createDeviceMap函数。在createDeviceMap里面有serachSensors的操作
3、在HalLogicalDeviceList.cpp类中创建sensor对象,searchSensors()主要时查找匹配的硬件sensor,把找到的Device放入集合中。
4、函数 pHalSensorList->searchSensors()将调用HalSensorList:: enumerateSensor_Locked()函数,该函数再调用ImgSensor_drv.cpp文件中的 pSensorDrv->searchSensor函数。
5、在HalSensorList::enumerateSensor_Locked()方法中循环遍历查找sensorinfo信息,然后fill in metadata
在imgsensor_drv.cpp中GetSensorInitFuncList()获得Hal层的sensor列表,featureControl(sensorIdx, SENSOR_FEATURE_SET_DRIVER, (MUINT8 *)&idx, &featureParaLen); //-- (2)调用kernel层的kdSetDriver函数
6、 if (ioctl(m_fdSensor, KDIMGSENSORIOC_X_FEATURECONCTROL , &featureCtrl) < 0) { //这块会调用imgsensor.c中的adopt_CAMERA_HW_FeatureControl,调用imgsensor_sensor_open(psensor),会在获取get_sensor_id之前把sensor给open起来
7、调用kernel层的kdSetDriver函数 ,在这里面做一些设置,imgsensor_set_driver()方法中设置 sensor的name、status、i2c_dev等,然后通过mgsensor_check_is_alive上下电camera并读取sensor的ID,如果匹配则成功
8、 接下来就是Sensor 上电, imgsensor_hw_power(&pgimgsensor->hw,psensor,psensor_inst->psensor_name,IMGSENSOR_HW_POWER_STATUS_ON);这里是给三路电压上电(AVDD、DVDD、DOVDD)然后获取sensor id,传入SENSOR_FEATURE_CHECK_SENSOR_ID,然后再把前面传下来的SENSOR_FEATURE_CHECK_SENSOR_ID进行匹配,最后get_imgsensor_id
10、search sensor的过程中,找到一个sensor,获取这个sensor的信息,然后fill in metadata。最后更新一些数据(效果参数、闪光灯、StaticInfo)。
11、为什么要locked()保证只允许一个进程操作。