深入浅出OTP

Camera Module一般会采取两种方式来记录该Sensor的一些信息

  • OTP:One Time Programmable。

    在嵌入式系统中,所有代码和系统数据都被存储在FLASH芯片内部。FLASH芯片可多次擦写,且掉电数据不丢失。为了保护FLASH中的数据,厂商提供OTP寄存器,OTP这个寄存器只可以编写一次,之后不能修改。

  • EEPROM:全称“电可擦除可编程只读存储器”( Electrically Erasable Programmable Read – Only Memory),手机中camera模块的EEPROM主要用来存储OTP数据,用来进行校准,来保持模组一致性。

加入知识星球与更多Camera同学交流

  • 星球名称:深入浅出Android Camera
  • 星球ID: 17296815

OTP介绍

OTP数据包括

  • Module Info:物料ID、日期、镜头、VCM等基本信息

  • LSC:lens shading calibration data

  • AWB:R、Gr、Gb、B的通道值或比值

  • AF:远、近焦的position对应DAC值

  • PDAF:SPC和DCC的data

Platform OTP

Sensor没有OTP自校准功能,需要我们BB端进行校正。从存储空间(外挂eeprom或者sensor内部存储空间)中读出数据,然后将数据送到BB端进行校正

Sensor OTP

Sensor有OTP自校准功能, 从存储空间(外挂eeprom或者sensor内部存储空间)中读出数据,然后写回sensor寄存器,送到BB端的Raw Data是已经校准过的数据

OTP存储方式

  • Sensor:在sensor芯片中ROM,和sensor公用I2C bus和read/write id

    OTP数据烧录在sensor的寄存器中。 这种方案省钱,不需要额外的存储器件,但是存储空间小,如果需要烧录的数据量过大,就不适用。

  • Sensor:sensor外挂的EEPROM,和sensor公用I2C bus,但具有不同的read/write id

    该方案优势是存储空间大,如果数据量过多,就需要这种方案,缺点是多一个独立的EEPROM存储器件。

OTP作用

OTP是用来给camera sensor做calibration(校准)用的。 因为模组生产出来会有很大的差异性,为了保证效果一致性, 模组厂会挑选一部分模组作为golden,然后将其他模组的相应参数校准到和这些golden一样, (golden不是最好的模组,也不是最差的模组,而是各方面最平均的模组)

代码实现

MTKOTP代码

Platform OTP

如果是MTK平台,首先需要读文档:MT6779_OTP_Porting_Guide.pdf

Using eeprom_drive.c, cam_cal_list.c as OTP adapter

Kernel modification

/Kernel-4.9/arch/arm64/boot/dts/mediatek/cust_tb8768_camera.dtsi

/kernel-4.9/drivers/misc/mediate/dws/mediatek/mt6765/tp8768tp1_64_bsp.dws

/Kernel-4.9/arch/arm64/configs/achilles6_prc_wifi_defconfig

/Kernel-4.9/arch/arm64/configs/ achilles6_prc_wifi_debug_defconfig

/kernel-4.9/drivers/misc/mediatek/cam_cal/src/common/v1/eeprom_drive.c

/kernel-4.9/drivers/misc/mediatek/cam_cal/src/mk6765/cam_cal_list.c

Hal modification

/vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/camera_calibration_cam_cal.cpp

Platform OTP 框架

Platform OTP 框架

Step1check dtsi and defconfig

/kernel-4.9/drivers/misc/mediate/dws/mediatek/mt6765/tp8768tp1_64_bsp.dws

配置main/sub eeprom地址,不能配置一样就行避免冲突(但实际上这块配置在不同CHANNEL,不会有冲突)。这块有工具配置(dws 工具路径:

./vendor/mediatek/proprietary/scripts/dct/DrvGen.exe

Platform OTP 框架

Platform OTP 框架

通过上述截图可以发现,CAMERA_MAIN_EEPROM、CAMERA_SUB_EEPROM的通讯地址分别是0x50、0x52。对应生成cust.dtsi文件

cust.dtsi在对camera的配置

文件路径:

/out/target/product/tb8768tp1_64_bsp/obj/KERNEL_OBJ/arch/arm/boot/dts/ tb8768tp1_64_bsp /cust.dtsi

Platform OTP 框架

代码中想要成功调用到对应的 eeprom_hw_i2c_probe() 和eeprom_hw_i2c_probe2() 函数需要分别匹配上 cust.dtsi 文件中的 compatible 节点 “mediatek,camera_main_eeprom” 和 "mediatek,camerasub eeprom "

Platform OTP 框架

Platform OTP 框架

配置defconfig 文件

/Kernel-4.9/arch/arm64/configs/achilles6_prc_wifi_defconfig

/Kernel-4.9/arch/arm64/configs/ achilles6_prc_wifi_debug_defconfig

Platform OTP 框架

Step2OTP Adapter

/kernel-4.9/drivers/misc/mediatek/cam_cal/src/mk6765/cam_cal_list.c

Platform OTP 框架

Step3:OTP Hal

NULL表示不支持OTP,否则表示支持

/vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/sensor_list.cpp

Platform OTP 框架

/vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/camera_calibration_cam_cal.cpp 默认sensor流程

/vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/camera_calibration_cam_cal_ov13b10.cpp 特定sensor

Platform OTP 框架

DoCamCal2Again()其他的函数和DoCamCalSingleLsc()实现很相似

Platform OTP 框架

配置像素ID:如果要进行Isc校准,需要在camera_isp_isc_xxxmipirow .h中配置像素id与模块厂商确定烧成OTP的第一个像素,然后修改vendor/mediatek/proprietary /custom / mt6765/hal/ imgsensor / xxx_mipi_raw/ camera_isp_Isc_xxxmipiraw.h

SensorGoldenCalTable{ //SensorGoldenCalTable

pixId: 3, //0,1,2,3: B, Gb, Gr,R

SlimLscType: 0

Width:0

}

OTP Read Flow

Platform OTP 框架

Platform OTP 框架

Sensor OTP

Sensor OTP代码和Platform OTP代码类似,在custom_camera_msdk.cpp中GetCameraCalData()函数来区分走默认函数CAM_CALGetCalData(),就是sensor OTP。Sensor

Platform OTP 框架

1、这块可以修改rg bg的值,刷版本看预览是否偏色,来看OTP是否正常(偏色)应用

2、这一抓kernel log来看OTP数据,是否正常。这块可以联系模组厂fae看OTP数据是否正常。

adb reboot
adb root
adb shell dmesg > D:\log\kernel.txt

sensor OTP的函数 》sensor型号_read_data_kernel《,获取有差异,但是大同小异。这里讲一个不一样的,万一找不到,从datasheet中找出OTP的寄存器,然后在驱动代码中搜寄存器就找到了;platform OTP可以根据camera_custom_msdk.cpp中GetCameraCalData()函数来看走那个函数来分析。

高通OTP代码

kernel层

(1)eeprom初始化

./kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c

高通OTP代码

函数主要是实现了两个功能:

  • 通过platform_driver_register函数注册平台驱动(有match device和driver的动作)(msm_eeprom_platform_driver)
  • 将msm_eeprom_i2c_driver挂载i2c总线上

(2)match驱动和设备
这之后,就会根据名称匹配驱动driver和设备device

./kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c

高通OTP代码

./kernel/msm-4.14/arch/arm/boot/dts/qcom/sm8150-camera-sensor-qrd.dtsi(//举个例子)

在dtsi中是设备的定义

平台 + 驱动 + 设备

高通OTP代码

compatible = “qcom,eeprom”.driver = {.name = “qcom,eeprom”,匹配上了,
系统就去调用probe函数probe = msm_eeprom_i2c_probe

(3)match成功,调用probe

./kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c

高通OTP代码

高通OTP代码

高通OTP代码

这个函数主要工作:

  • msm_eeprom_get_dt_data(e_ctrl);读取dtsi配置的上电时序配置/
  • msm_eeprom_parse_memory_map用于解析以下节点

高通OTP代码

  • msm_camera_power_up上电
  • read_eeprom_memory读取OTP数据
  • msm_camera_power_down下电

说白了,前面无非就是去读取dtsi的配置,进行上电,然后读取OTP数据下电
这就是整个probe函数的流程!

(4)读取OTP数据:read_eeprom_memory

高通OTP代码

高通OTP代码
qcom,page0 =
= <有效值 地址 地址类型 数据 数据类型 延迟>

qcom,page7 = <1 0x3d81 2 0x01 1 10>;/*往0x3d81写入0x01:把OTP数据加载到buffer中 */
qcom,pageen7 = <0 0x0 0 0x0 0 0>;
qcom,poll7 = <0 0x0 0 0x0 0 0>;
qcom,mem7 = <256 0x7010 2 0 1 1>;/*从0x7010开始读取256个数据*/

Userspace层

在kernel层,数据最后被保存到memptr指向的地址里

vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/eeprom/eeprom.c

高通OTP代码

高通OTP代码

用户态通过ioctl下到内核,我们看下内核的接受者函数

./kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c

高通OTP代码

高通OTP代码

高通OTP代码

Copy_to_user中将cal_data.mapdata的num_bytes个数据放到cfg.read_data.dbuffer

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程