ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

高通平台Camera Sensor Bring Up实战:从硬件时序到3A调试

高通平台Camera Sensor Bring Up实战:从硬件时序到3A调试 高通平台的Camera sensor bring up是我这几年做得最多的技术活。很多人以为点亮一颗sensor就是改几个寄存器、调一调驱动那么简单真上手才发现从硬件时序确认到kernel驱动移植再到平台适配和3A调试中间任何一个环节掉链子都可能让你在一颗芯片上耗掉一两周。这篇内容我按自己实际做项目的路径来写从拿到模组规格书开始到最终稳定出图、跑通验证为止把完整的思路、关键命令、踩坑记录都放进来希望能帮你少走几趟弯路。做sensor bring up的人一般有三种情况一是做手机/平板整机方案二是做车载或IoT摄像头模组三是做类似拇指相机这类小型化产品的硬件工程师。不管哪种场景核心链路都是同一套区别只在你手里拿到的sensor size、MIPI lane数、电源方案和平台配置不同。1. 整体设计与思路拆解先把流程在脑子里跑一遍1.1 为什么说bring up不是“写驱动”这么简单很多刚入行的同学拿到一颗新sensor第一反应就是找kernel驱动、改I2C地址、编译烧录结果常常卡在“I2C能读到ID但不出图”或者“出图了但是全屏花”这类问题上。我自己的经验是真正成熟的bring up流程应该先花半天时间把整条链路在脑子里过一遍再动手。一条完整的高通Camera sensor链路大致是这样的sensor硬件模组通过MIPI CSI接口连接到SoC的CSI控制器控制通路走CCI实际上是I2C总线读写寄存器上电时SoC通过PMIC GPIO/LDO给sensor供AVDD、DVDD、IOVDD同时输出MCLK时钟复位引脚控制sensor的启动状态kernel侧有对应的sensor驱动负责做电源控制、I2C读写、sensor ID匹配、stream on/off控制再往上层走高通camera driverCamX或旧平台的CamSvc会加载sensor mode表、tuning参数把曝光、增益、白平衡这些控制参数跟3A算法对接起来最终通过HAL层把预览流、拍照流送出来。这一条链路里任何一个环节不匹配都会表现为“点不亮”。最常见的情况是I2C探测正常、ID读回来了但preview开不起来仔细查才发现是GPIO复位引脚配置错了或者某个电源的上电时序不满足sensor datasheet要求。所以我的习惯是先把整条链路的依赖关系画出来再一个节点一个节点验证。1.2 动手前要准备好的资料、工具和环境开工之前下面这些资料和工具有没有到位直接决定后面是顺风顺水还是反复折腾。从资料角度说最少需要五样东西sensor datasheet特别是其中的register map、power-up timing、MIPI输出参数这几章模组原理图确认I2C地址上拉、reset引脚、电源引脚是怎么连的是否有eeprom/ois/actuator等附属器件高通平台对应的Camera BSP文档比如Camera Sensor Bring Up Guide不同平台如SM8250、SM8450、QCM6490细节略有差异原厂或模组厂提供的初始化寄存器数组这组数据很关键很多sensor必须初始化后才能正常输出sensor tuning参数如果之前有做过同型号可以直接复用。从工具角度说必备的东西包括一台能正常编译烧录的开发板或手机串口或ADB通路要稳定示波器至少双通道以上带宽不用太高100MHz够用主要测MCLK、reset、电源上电时序逻辑分析仪或带I2C解码的示波器用来抓CCI总线上的读写波形一套能跑高通camera测试的环境包含QCamera或mm-qcamera-app这类工具稳定的光源环境比如灯箱或者标准光源后边调AWB、AE都要用到。提示我见过不少人带着“代码能编译过”就直接开干结果硬件上某个LDO没供电白折腾了两天。资料没齐之前不建议动代码。2. 硬件侧确认上电时序、时钟和复位这里偷懒后面全是坑2.1 先从模组datasheet里读懂电源和时序要求很多sensor“读不到ID”或者“读ID偶尔成功偶尔失败”的问题追根溯源都出在硬件时序上。常见的高通平台sensor供电有三路IOVDD一般1.8V、DVDD根据sensor不同可能是1.05V、1.1V或1.2V、AVDD一般是2.8V或2.85V。这还只是典型值不同sensor的电压范围差异很大不能想当然照着上一个sensor的配置抄。看datasheet里的power-up timing图时重点抓三个时间参数MCLK稳定到reset释放之间的delayIOVDD稳定到其他电源上电之间的delayreset释放到I2C可以开始读写之间的delay。这三个参数如果设置得太极限就会遇到“有时候能读到ID有时候读不到”这种玄学问题。我的习惯是把这些delay稍微放宽一点比如datasheet要求reset释放后等1ms可以操作我就配置成2ms到5ms留出足够余量。稳定的bring up比极限性能重要得多。另外还要确认reset引脚的极性。有的sensor是高有效复位有的是低有效复位搞反了会导致sensor一直处于复位状态或者工作状态异常。这个信息一般在pin description表里有标注实在不确定就用示波器抓一下模组厂参考设计板上的实际波形。2.2 用示波器实际量测别只看原理图软件配置写得再对硬件实际走的通路不对一切都是白搭。我自己在bring up阶段习惯先把MCLK、Reset、IOVDD、DVDD、AVDD这几个信号用示波器同时抓出来。举个例子MCLK一般要求是19.2MHz或24MHz用示波器看频率是否准确幅度是否在sensor接受范围内。有些平台MCLK幅度不足比如只有1.2V左右但sensor要求1.8V这种情况下sensor工作会不稳定。复位引脚的时序也要仔细看。如果SoC的GPIO默认状态是拉高但sensor需要低有效复位那么在驱动加载前sensor可能处于异常状态就会导致CCI通信不稳定。用逻辑分析仪抓I2C波形也很有用。有一次我遇到I2C写寄存器成功但读寄存器返回全0xFF的情况用逻辑分析仪一看发现SDA线上的上拉电阻没焊好信号幅度被拉得很低。这种问题光看日志是定位不了的。2.3 关于sensor和镜头选型的一点思考在带摄像头的产品项目里sensor和镜头选型会在bring up之前就决定好。以拇指相机这类小型化产品为例体积小、功耗低是硬约束所以一般不会选大靶面sensor反而会倾向于尺寸小但像素密度合适的型号。此时考虑的不只是分辨率还有镜头视场角、光圈、模组高度能不能塞进结构里。从bring up角度看不同sensor的不同特性会影响后续调试背照式BSIsensor和堆栈式sensor的灵敏度、暗电流表现不同tuning参数不能混用支持HDR的sensor要确认平台侧是否启用了对应的HDR mode否则预览画面可能异常支持binning/裁剪输出的sensor在mode table里要配置正确不然分辨率切换时会黑屏。这些信息建议在bring up之前就跟模组厂确认好而不是等sensor点亮后再去翻datasheet。3. Kernel侧驱动移植从I2C探测到状态注册3.1 高通msm_camera_sensor驱动的基本结构高通平台从MSM8996时代开始sensor驱动基本都是围绕msm_camera_sensor框架来的。到现在的CamX时代底层驱动结构有所变化但核心逻辑仍是那几个步骤probe的时候注册v4l2 subdevopen的时候做电源上电和ID匹配s_parm/stream_on/stream_off的时候下发模式配置和输出控制。如果你拿到的sensor已经有高通平台的老驱动比如msm_sensor_ov5645.c或msm_sensor_imx258.c迁移到新平台时主要改的地方并不多驱动名称和compatible字符串power up/power down时序包括各路电源的GPIO/regulator配置I2C地址和寄存器读写位宽init setting寄存器数组。我一般先把老驱动中的xxxxxxxx_init数组替换成新sensor的初始化寄存器数组再对比datasheet确认ctrl_data的寄存器配置比如输出分辨率、MIPI lane数、时钟分频系数编译烧录后先看probe是否成功。3.2 DTS和设备树配置示例高通的sensor配置在dtsi里通常分成几个层级CCI节点、eeprom节点、actuator节点、sensor节点。这里给一个典型的sensor节点配置片段供参考cci0_active { /* CCI0 I2C频率配置一般设400K或1M */ qcom,cci-master 0; }; cam_sensor_rear_default { /* 电源配置 */ cam-supply pm8150_l17; /* AVDD */ cam_vio-supply pm8150_l6; /* IOVDD */ cam_vdig-supply pm8150_l5; /* DVDD */ qcom,cam-vreg-name cam_vio, cam_vdig, cam_supply; qcom,cam-vreg-min-voltage 1800000 1050000 2800000; qcom,cam-vreg-max-voltage 1800000 1050000 2800000; qcom,cam-vreg-op-mode 105000 105000 105000; /* 时钟与复位 */ pinctrl-names cam_default, cam_suspend; pinctrl-0 cam_sensor_mclk0_active cam_sensor_active; pinctrl-1 cam_sensor_mclk0_suspend cam_sensor_suspend; gpios tlmm 28 0, /* MCLK */ tlmm 30 0, /* RESET */ tlmm 29 0; /* 备用GPIO */ qcom,gpio-reset 1; qcom,gpio-vana 2; qcom,gpio-req-tbl-num 0 1 2; qcom,gpio-req-tbl-flags 1 0 0; qcom,gpio-req-tbl-label CAMIF_MCLK, CAM_RESET, CAM_VANA; };这里面的GPIO编号和电源配置必须跟原理图一一对应。我犯过的低级错误是复制上一个sensor的dtsi结果GPIO编号没改导致复位引脚控制的是另一个模块的GPIO点亮当然失败。电源配置这里有一个容易被忽略的点cam-supply这类属性指向的regulator在高通平台上通常由PMIC LDO控制。如果某个电源不需要额外供电路径而是sensor内部自带的DCDC那就要把对应的supply配置跳过否则驱动会尝试去操作一个不存在的regulator导致probe失败。3.3 I2C读写探测的实操方法配置完驱动和dtsi编译烧录后第一步不是急着开预览而是先确认I2C通路能否正确读写sensor寄存器。我常用的方法有两种。第一种是在内核启动日志里看sensor probe是否match成功。如果sensor驱动注册了i2c_device_id和of_match那么在内核启动阶段通常会打印类似msm_sensor_probe、sensor id matched的信息。如果ID匹配失败日志里会直接打印读到的ID值非常方便定位问题。第二种是在系统起来以后手动操作I2C。比如# 查看sensor挂载在哪个I2C总线上 adb shell ls /sys/bus/i2c/devices/ # 如果sensor I2C地址是0x20可用i2cget读取寄存器 adb shell i2cget -y bus 0x20 0x0000 w不过要注意高通sensor一般挂在CCI总线上而CCI在Linux下被抽象成i2c adapteri2cget这类工具大多数时候能用。如果系统裁剪过没有i2c-tools也可以直接用高通自带的camx调试接口或者驱动里的debugfs节点。关系到一个常见坑sensor的8-bit写地址和7-bit设备地址之间要做一次右移。比如sensor datasheet上写slave address是0x20这是8-bit写地址那么7-bit地址实际上是0x10。在驱动配置i2c_addr时容易填错导致读ID失败。我通常会在dtsi里写一个注释直接把7-bit地址标出来。4. 平台配置与Tuning数据点亮只是开始4.1 从sensor驱动到camera HAL的配置链路sensor驱动注册成功只代表kernel侧认到了这颗sensor不等于上层camera能正常出图。从驱动往上还需要经过几个关键配置才能让hal层识别到这个sensor。高通CamX架构里sensor相关的配置分散在几个地方kernel的dtsi负责底层GPIO、电源、I2CCamX sensor config通常是一份xml或json文件定义了sensor的mode table、曝光增益范围、HDR模式、输出格式tuning data放在/vendor/etc/camera/或/vendor/lib64/下给3A算法提供参考参数。如果平台有多个sensor还要在cam_sensor_module或类似的配置里把新sensor的优先级、CSI接口、sensor slot编号定义好。否则上层枚举sensor的时候可能把它识别成另外一颗。实际操作中我一般这样做先在kernel dtsi里把sensor节点挂到对应的CCI控制器上编译烧录用adb确认kernel probe成功并能读到sensor ID往平台对应的sensor config目录里加入该sensor的配置文件和tuning文件重启camera服务查看logcat确认sensor status是否变成open/available用QCamera或mm-qcamera-app打开preview确认出图。第3步很容易出问题。很多平台对sensor配置文件有严格的格式要求少一个字段解析就会失败。遇到这类问题我的经验是先查看/vendor/etc/camera/camera_configuration.xml不同平台路径不同对比已有的sensor配置项重点检查sensorName、posid、slaveAddress、laneCount这些字段是否一致。4.2 sensor mode table和曝光参数的关系sensor mode table定义了sensor支持的每一个输出模式包括分辨率、帧率、binning、HDR mode、行长度、帧长度、像素时钟等参数。这些参数直接影响3A算法对曝光和增益的换算不能随便填。先解释几个关键概念line_length_pck行长度单位pixel和frame_length_lines帧长度单位行决定了帧率公式大致是帧率 vt_pix_clk_freq_mhz / (line_length_pck * frame_length_lines)曝光时间一般通过coarse_integration_time控制实际曝光时长 coarse_integration_time * line_length_pck / vt_pix_clk_freq_mhz增益分为模拟增益和数字增益sensor datasheet里会有对应的寄存器换算关系。打个比方mode table像是一把尺子3A算法通过这把尺子计算“我要让sensor曝光多少毫秒、放大多少倍”。尺子刻度错了算出来的曝光和增益就全错了。曾经遇到过一个sensor出图后预览整体偏亮倍率不对排查到最后发现是line_length_pck填错了导致实际曝光时间比预期多了一倍。4.3 一个实操案例新sensor点亮的关键步骤在国内用得非常多的sensor型号比如OV5645、IMX258、IMX362这些bring up思路是相通的。我以一颗典型的sensor为例描述实操流程型号就不具体点名了避免大家照抄配置。第一步打开sensor datasheet找到register initialization部分把一串初始化寄存器整理成驱动可用的格式。这串寄存器通常包括软件复位、输出格式设置、MIPI lane数、分辨率、帧率、曝光增益默认值等。第二步在dtsi里完成电源和GPIO配置按2.1节说的把时序余量放宽。第三步编译烧录后先通过I2C读取sensor ID寄存器确认通信正常。第四步把初始化寄存器数组灌进去设置stream on通常是设置0x0100寄存器为1用示波器在CSI接口上看是否有MIPI数据输出。第五步平台侧把该sensor的tuning文件放好用QCamera打开预览看画面是否正常。这里要特别提一句sensor单独stream on之后MIPI接口有数据输出但不代表hal层能正常出图。我遇到过一次sensor输出正常平台侧预览黑屏的情况排查发现是平台侧sensor config的MIPI lane数配置和sensor实际lane数不一致数据全部无效。做小型化产品时比如拇指相机sensor和镜头选型往往还会影响camera多媒体buffer管理的设计。小内存设备上如果预览分辨率设置偏高buffer不够用就表现为出图卡顿或黑屏。这种问题单靠驱动层调不通得从应用层和buffer分配策略上一起调整。5. 点亮后的验证与调试工具箱5.1 出图后第一步从RAW数据开始验证当预览画面能正常显示时真正的调试工作才开始。sensor点亮不等于图像质量达标很多画质问题都需要在RAW域里检查。我建议步骤是这样的先拍一张RAW图直接在电脑上用rawpytools或Imatest打开看整体曝光是否均匀检查是否有竖条纹、横条纹这类问题往往跟MIPI传输、电源纹波、sensor内部PLL配置有关检查是否有坏点坏点分为静态坏点和动态坏点前者需要查sensor bad pixel correction配置后者可能跟温度、曝光时间有关检查暗角情况镜头本身的lens shading需要靠tuning里的LSCLens Shading Correction数据来补偿。RAW图检查过关后再看预览和拍照的YUV效果。这里就涉及到一个平时容易忽略的点camera多媒体buffer管理。预览流、拍照流、回调流各自的buffer数量、格式、对齐方式如果不匹配就会导致画面撕裂、卡顿。尤其是在高分辨率传感器上YUV格式和RAW格式之间转换时如果buffer大小算错容易出现“最后一行是绿色”这种问题。5.2 3A调试AE收敛、AWB色偏、AF对焦3A的调试可以说是sensor bring up之后最花时间的一块。AE方面先确认不同亮度环境下曝光时间和增益的变化是否符合预期。比如在暗光下如果曝光时间已经到上限增益也到上限但画面仍然偏暗就要检查mode table里的参数或者sensor最大的gain配置是否太低。AWB方面如果拍白色物体偏蓝或偏黄优先检查tuning数据里的AWB参考点和CCM矩阵是否匹配该sensor的光谱响应。有些sensor改了封装或者加了IR filter之后光谱响应会有变化直接沿用同款tuning会导致色偏。AF方面先确认sensor驱动的focuser是否能正常工作。如果项目里用了actuator那么在kernel层面就要确保actuator驱动注册成功并对正方向。测试时可以先用一个固定的DAC值拍近处物体再用大的DAC值拍远处物体确认对焦方向没有接反。5.3 第三方工具与自动化测试的搭配使用除了高通自带的工具实际调试时我还会用一些第三方工具来辅助验证。sensor box for android这类工具可以把常见的sensor调试参数集中在一个界面里方便快速切换曝光、增益、模式比手动改寄存器效率高很多。open camera这种开源相机应用也很实用它功能比系统相机简洁但参数暴露更完整可以方便地锁定曝光、白平衡、对焦模式排查问题时能做到单变量控制。next camera这类第三方apk同样可以用来做对比验证确认问题出在应用层还是sensor/平台侧。平台自带的VTS/ITS测试则适合做回归。比如android.hardware.camera.provider这类VTS用例会验证摄像头设备枚举、基本功能是否完整。ITSImage Test Suite则会跑一些基础的图像质量用例比如色彩一致性、lens shading、noise等。每次改动tuning或者驱动后跑一遍VTS/ITS能快速发现有没有引入新的问题。6. 高频问题排查实录与避坑清单6.1 常见现象与根因速查表下面这张表是我这些年做bring up过程中总结出来的高频问题清单每次遇到问题我都会先对着这张表过一遍很多时候能省下半天时间。现象大概率原因排查方向I2C读ID失败地址配置错误、sensor未正常上电、reset极性不对用示波器测电源和reset时序核对7-bit地址读ID偶尔成功偶尔失败上电时序余量不足、MCLK不稳定放宽时序delay检查MCLK频率/幅度probe成功但预览黑屏MIPI lane数配置不对、CSI接口选择错误核对sensor lane数和dtsi中lane映射预览花屏MIPI信号翻转、时钟参数不符检查lane swap/polarity配置跑MIPI调试工具画面过亮/过暗mode table中曝光参数错误核对line_length_pck、frame_length_lines颜色偏色tuning数据不匹配、eeprom数据没加载检查AWB参考点、CCM矩阵、eeprom读取预览卡顿buffer数量不足、分辨率过高调整buffer分配策略和预览分辨率拍照后照片发绿RAW域处理格式错误检查tuning中demosaic和bayer pattern设置6.2 我在实际项目中踩过的几个坑第一个坑跟eeprom有关。某款sensor带有一颗eeprom里面存了AWB校准数据和镜头参数结果我在配置eeprom驱动的时候I2C地址填错了系统读出来的eeprom全是0xFF导致相机预览颜色严重偏红。排查很久才发现是地址少移位了一位痛定思痛之后我在所有sensor/eeprom地址上都会加一行注释标注清楚是8-bit还是7-bit。第二个坑是MIPI lane极性。板子layout里lane P/N接反了但原理图上标注是正常的平台默认配置也不报错预览就是花屏或者完全没有信号。后来我直接在驱动里把lane polarity翻转之后画面立刻正常。遇到这类问题优先检查硬件连接和平台侧lane配置是否一致。第三个坑是sensor上电时序。某颗sensor datasheet要求reset释放之后至少等10ms才能开始I2C通信但驱动里只等了1ms结果读ID失败率很高。后来我把时序放宽到20ms问题彻底消失。这个案例让我认识到datasheet里的时序参数务必留足余量不要卡着最小值写。第四个坑出现在tuning参数上。同一个平台同时兼容两颗sensor形态和分辨率相近但sensor A和sensor B的Bayer排列是相反的我一开始复用sensor A的tuning给sensor B导致整幅图像的色彩通道全部错位。最后把所有与Bayer排列相关的配置都改成sensor B对应的顺序才恢复正常。6.3 提速建议从“玄学调试”到“按图索骥”最后分享几个我自己的节奏习惯能帮你把bring up整体时间从将近两周压缩到三五天。第一严格按链路逐级验证。先确认I2C通信再确认sensor ID再确认MIPI输出最后才让上层出图。任何一步不过不要继续往下走否则问题叠加在一起很难定位。第二日志和示波器互相印证。内核日志说probe成功了不代表硬件真的工作正常示波器看到的信号才是最真实的。反过来示波器看到信号正常但驱动层报错那就要检查配置参数是否写错。第三把每次改动的配置保存下来做好版本管理。tuning参数也好dtsi配置也好频繁改动后很容易忘记哪个组合是能工作的。我自己的做法是每次出图正常后立刻把对应的配置文件和tuning数据打一个tag备份。第四多借力工具。sensor box for android这类工具能帮你快速切换参数open camera能帮你锁定应用层变量VTS/ITS能替代一部分手工回归。工具用得好调试效率会翻倍。我看过太多人在bring up阶段靠“猜”和“试”来解决问题浪费了大量时间。其实sensor bring up是一门很讲究方法的工程活流程清晰、工具到位、日志完整绝大多数问题都能快速精确地定位。做多了自然会发现所谓“玄学”问题基本都是某个环节没验证彻底。整个流程走下来最大的体会就是前面越仔细后面越省事。
返回列表