尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

MTK Camera点不亮?kernel_log.boot定位sensor探测与PWDN反极性

MTK Camera点不亮?kernel_log.boot定位sensor探测与PWDN反极性 简介《MTK Camera调试指南》是一份面向手机摄像头驱动开发与调试工程师的实战文档聚焦MTK 89平台下IMX、OV系列常见sensor的调试方法涵盖imx111、imx188、imx135、ov9724、ov8825、ov12830等型号的上电与初始化流程。文档从开机检测切入先分析Projectconfig.mk中的sensor配置、kdSensorList数组与kdSetDriver索引的含义再说明系统如何将同一颗sensor依次当作后摄和前摄上电读ID并揭示power down极性、kdCISModulePowerOn上电函数对识别结果的影响针对摄像头点不亮也给出了I2C不通、电源时序异常、sensor枚举冲突等典型问题的排查思路。文中还演示了利用mobilelog、kernel_log.boot中的关键log辅助定位以及加入新sensor时需同步修改的驱动位置方便现场调试时参考。资源包共1个docx文件大小约231KB便于随时查阅。当前已有1626人学习下载是社区验证过的实用参考资料。对正在调试MTK Camera或需要移植新sensor的开发者这份指南能帮助快速配置驱动、理解上电时序并缩小问题排查范围。1. 从开机日志定位 Camera 点不亮MTK 平台的探测机制远比你想的复杂很多人拿到 MTK 89 平台的 Camera 驱动问题第一反应是抓串口 log、看 I2C 波形忙活半天发现还是定位不到根因。其实 MTK 平台在开机阶段已经把「哪些 sensor 活着、哪些 sensor 死了」写进了mobilelog里的kernel_log.boot只是这份日志的解读方式很少有人系统讲清楚。本文以mt89_v10_vanzo_test项目为例完整拆解 MTK Camera 上电探测流程、前后摄判定的硬件逻辑、imx111 这种 power down 极性反挂的 sensor 为什么会导致「单摄正常、双摄互相干扰」以及从零添加一颗新 sensor 需要动哪些文件。内容基于实际调试经验整理覆盖 imx111、ov9724、imx135、soc5140 等常见 sensor 的共性问题适合正在做 MTK 平台 Camera 驱动的工程师参考。2. MTK Kernel 层 Camera 驱动骨架从 ProjectConfig 到 kdSensorList 的完整链路2.1 ProjectConfig.mk 与 sensor 探测的启动关系MTK 开机过程中系统会遍历ProjectConfig.mk中配置过的所有 camera sensor相关配置形如CUSTOM_HAL_IMGSENSORimx111_mipi_raw ov9724_mipi_raw CUSTOM_KERNEL_IMGSENSORimx111_mipi_raw ov9724_mipi_raw这两行配置决定了系统在开机阶段要探测哪些 sensor。CUSTOM_HAL_IMGSENSOR对应 HAL 层 sensor 注册列表CUSTOM_KERNEL_IMGSENSOR对应 Kernel 层 sensor 驱动列表。配置项本身很好理解但容易忽略的是这两行配置的 sensor 名称必须与驱动文件夹名、注册数组中的字符串完全一致任何一处不匹配都会导致 sensor 探测静默失败。我曾经遇到过一个项目驱动文件和注册数组都改了唯独 ProjectConfig.mk 里漏加了一颗 sensor开机日志中完全没有这颗 sensor 的探测记录排查了很久才定位到是配置遗漏。sensor 探测不是简单地在开机时把所有 sensor 轮流上电读 ID而是由kd_sensorlist.c中的流程驱动的。系统通过kdGetSensorInitFuncList(pSensorList)获取配置好的kdSensorList[]数组这个数组定义在mediatek/custom/common/kernel/imgsensor/src/kd_sensorlist.h中。如果你新增的 sensor 没有加入这个数组即使 ProjectConfig.mk 配了、驱动文件也放了系统依然不会调用到这个 sensor 的初始化函数。2.2 kdSetDriver 与 pDrvIndex 数组的编码规则sensor_probe阶段的核心函数是kdSetDriver它接收一个pDrvIndex数组作为参数。这个数组的编码规则是理解整个探测流程的关键位域含义典型取值第一个成员前 16 位后摄和前摄的下标1 表示后摄2 表示前摄第一个成员后 16 位sensor 索引1、2、3、4第二个成员目前 MTK 代码未实际调用0也就是说pDrvIndex[0]的低 16 位存的是 sensor 在kdSensorList[]中的索引高 16 位存的是当前探测的是主摄还是副摄的标识。驱动中对这个数组的解析逻辑分散在CAMERA_HW_Ioctl、adopt_CAMERA_HW_CheckIsAlive等多个函数中调试时如果看到pDrvIndex相关日志可以通过这两段位域快速判断当前的探测状态。2.3 kdSensorList 注册与 sensor 驱动加载的先后顺序kdSensorList[]数组的注册顺序会直接影响开机探测的物理行为。MTK 平台并不是把前摄、后摄分开探测的而是 先把所有配置的 sensor 当成后摄来上电读 ID再把所有 sensor 当成前摄来上电读 ID。这就意味着同一颗 sensor 在开机阶段会被访问两次第一次以「后摄身份」上电第二次以「前摄身份」上电。举个例子假设某项目配置了 imx111 和 ov9724 两颗 sensor开机流程是第一次探测当作后摄 imx111 上电 - 读 ID - 记录结果 ov9724 上电 - 读 ID - 记录结果 第二次探测当作前摄 imx111 上电 - 读 ID - 记录结果 ov9724 上电 - 读 ID - 记录结果最终哪颗 sensor 被记为后摄哪颗被记为前摄由「哪次探测能正确读到 ID」决定。如果 imx111 接的是后摄物理接口那么第一次以「后摄身份」探测时应该能读到 ID第二次以「前摄身份」探测时由于前摄的 power down 引脚和后摄是分离的imx111 不应该被上电因此读不到 ID。这个机制依赖硬件上前摄和后摄 power down 引脚的物理隔离——这也是为什么硬件设计上必须把前摄和后摄的 PWDN 分开接 GPIO。3. Camera 上电与读 ID 的实现路径CAMERA_HW_Ioctl 的分发逻辑3.1 KDIMGSENSORIOC_T_CHECK_IS_ALIVE 到 adopt_CAMERA_HW_CheckIsAlive 的上电过程开机探测的入口在kd_sensorlist.c的kdSetDriver函数真正执行上电动作的是CAMERA_HW_Ioctl中的KDIMGSENSORIOC_T_CHECK_IS_ALIVE分支static long CAMERA_HW_Ioctl( struct file *a_pstFile, unsigned int a_u4Command, unsigned long a_u4Param) { switch (a_u4Command) { case KDIMGSENSORIOC_T_CHECK_IS_ALIVE: i4RetValue adopt_CAMERA_HW_CheckIsAlive(); break; case KDIMGSENSORIOC_X_FEATURECONCTROL: i4RetValue adopt_CAMERA_HW_FeatureControl(pBuff); break; } return i4RetValue; }KDIMGSENSORIOC_T_CHECK_IS_ALIVE分支完成 sensor 的上电动作它最终会调用kdCISModulePowerOn函数设置各个 power 域的 GPIO 和 LDO。上电是否成功取决于kd_camera_hw.c中定义的上电序列与硬件实际连接的引脚是否一致。3.2 KDIMGSENSORIOC_X_FEATURECONCTROL 与 GetSensorID 的联动上电完成后系统通过KDIMGSENSORIOC_X_FEATURECONCTROL分支调用adopt_CAMERA_HW_FeatureControl在pBuff中回调具体 sensor 驱动中的getSensorID函数。这个函数通过 I2C 读取 sensor 的 ID 寄存器与驱动中预设的imx111_SENSOR_ID做比对static kal_uint32 getSensorID(kal_uint32 *sensorID) { kal_uint32 id 0; // 读取 sensor 的 ID 寄存器0x00 为 imx111 的 ID 寄存器地址 id *(volatile kal_uint16 *)0xF0000000; // 实际项目中通过 I2C 读取 // 与驱动中定义的 sensor ID 做比对 if (id imx111_SENSOR_ID) { *sensorID id; return ERROR_NONE; } return ERROR_SENSOR_CONNECT_FAIL; }getSensorID的返回值直接决定这颗 sensor 是否会被记录为「存在」。读到正确 ID 后sensor 会被加入系统的可用 sensor 列表读不到 ID则跳过这颗 sensor继续探测下一颗。这里的return ERROR_NONE与ERROR_SENSOR_CONNECT_FAIL的区分非常重要——前者表示 sensor 存在但可能后续出图有问题后者表示 I2C 通信本身就失败了。3.3 I2C 不通与读到 ID 但无预览的故障分流在实际调试中Camera 点不亮的问题可以快速分成两类故障现象可能原因排查方向读不到 sensor IDI2C 不通、上电时序不对、PWDN/RST 极性配置错误检查 kd_camera_hw.c 上电序列对照硬件原理图核对 GPIO能读到 ID 但无预览sensor 被重复探测、上下电时序冲突、mclk 频率不对检查 kernel_log.boot 中前后摄探测记录确认是否出现同一 sensor 被前后摄同时记录第二种情况往往比第一种更难排查因为它不涉及硬件通信问题而是逻辑层面的冲突。接下来用 imx111 的实际案例详细拆解。4. imx111 双摄项目实战PWDN 极性反转与前摄后摄探测冲突4.1 kernel_log.boot 中探测日志的字段含义mobilelog中的kernel_log.boot文件对 Camera 问题定位非常有效关键是它不需要串口 log 就能抓取。抓取方式为手机连接 PC 后通过 adb 命令抓取 mobilelog 即可。adb pull /data/mobilelog/kernel_log.boot打开这个文件后搜索 sensor 名称关键字比如imx111可以看到类似下面的日志序列[0][1][1][imx111mipiraw][32] sensor probe start [0][1][1][imx111mipiraw][32] sensor id 0x0111 [0][1][2][imx111mipiraw][32] sensor probe start [0][1][2][imx111mipiraw][32] sensor id 0x0111这一段日志看起来很平常但对于 imx111 接在后摄的项目来说隐藏着一个严重问题[0][1][2]表示 imx111 在「被当作前摄」时也读到了 ID。刚才讲过前摄和后摄的 power down 引脚是分离的当系统把 imx111 当作前摄上电时imx111 所在的硬件线路本不该通电ID 也不该被读到。但日志显示两次探测都能读到 ID这说明 PWDN 控制没有在硬件层面真正隔离。4.2 日志参数逐位拆解pDrvIndex、enable 与前后摄身份日志中每个字段都有明确含义逐位拆解如下[0] pDrvIndex 数组的第一个成员目前代码中只用第一个成员 [1] enable 标记1 表示使能 [1] 当前作为后摄探测2 表示作为前摄探测 [imx111mipiraw] sensor 名称字符串 [32] sensor 名称缓冲区最大长度[0][1][1]与[0][1][2]的区别就在第三个字段。正常情况下后摄 sensor 在[0][1][1]时读到 ID 是符合预期的但[0][1][2]还读到 ID 就说明 PWDN 的极性控制出了问题。4.3 camera_pdn_reverse 全局变量的作用与 getsensorID 内的手动矫正在kd_camera_hw.c中定义了一个全局变量camera_pdn_reverse初始值为 0static int camera_pdn_reverse 0;kdCISModulePowerOn函数在设置 PWDN 引脚时会读取这个变量如果为 1则反转 PWDN 的极性。正常情况下这个变量应该由 sensor 驱动在getSensorID中根据实际情况设置static kal_uint32 getSensorID(kal_uint32 *sensorID) { kal_uint32 id 0; // 手动调整 PWDN 极性让 imx111 在上电阶段能正确读到 ID camera_pdn_reverse 1; // 然后读取 ID 寄存器 id read_sensor_register(0x00); if (id imx111_SENSOR_ID) { *sensorID id; return ERROR_NONE; } return ERROR_SENSOR_CONNECT_FAIL; }这段代码的关键点在于camera_pdn_reverse 1必须在第一次调用getSensorID时执行。为什么因为开机探测时系统第一次以「后摄身份」给 imx111 上电此时如果 PWDN 极性是错的ID 本来读不到而当camera_pdn_reverse被置 1 后PWDN 极性被修正后续所有上电流程都会沿用修正后的极性。这个动作只需要做一次因为正常使用场景中getSensorID不会再被调用后续打开 Camera 走的是open函数流程。4.4 从「前后摄同时使用时后摄无图像」反推根因mt89_v10_vanzo_test项目中出现的典型症状是前摄单独使用正常后摄单独使用也正常但前后摄同时使用比如切换摄像头时后摄能读到 ID 却没有图像输出。根因在于 imx111 在 MT6589 项目上既做前摄也做后摄而它的 PWDN 极性是反的。当系统第一次以「后摄身份」探测 imx111 时getSensorID被调用camera_pdn_reverse被置为 1紧接着系统以「前摄身份」探测 imx111 时PWDN 极性已经修正imx111 在前摄上电条件下也能正常读 ID。两颗 sensor 都被记录为可用。关键在于当后续打开后摄时open流程中如果先做了前摄的close操作camera_pdn_reverse可能被重置为 0导致后摄上电时 PWDN 极性错误sensor 虽然能读到 ID因为探测阶段已经记录但实际出图时 sensor 没有被正确唤醒。调试这类问题需要在open/close流程中检查camera_pdn_reverse的值是否被意外重置以及kdCISModulePowerOn/kdCISModulePowerOff中 PWDN 极性设置分支是否被多次调用。5. Kernel 与 HAL 层新增 sensor 驱动的完整清单5.1 Kernel 层驱动添加步骤以 imx111 为例Kernel 层需要新增和修改的文件如下新增文件夹 mediatek\custom\common\kernel\imgsensor\imx111_mipi_raw\ imx111mipiraw_Sensor.c imx111mipiraw_Camera_Sensor.c imx111mipiraw_OTP.c可选 imx111mipiraw_otp.h可选 修改文件 mediatek\custom\common\kernel\imgsensor\src\kd_sensorlist.h mediatek\custom\common\kernel\imgsensor\inc\kd_imgsensor.hkd_sensorlist.h中需要添加 imx111 的注册声明extern struct KDIMGSENSOR_FUNC_STRUCT imx111_mipi_raw_sensor;同时在kd_sensorlist.c的kdSensorList[]数组中注册struct KDIMGSENSOR_FUNC_STRUCT *kdSensorList[] { imx111_mipi_raw_sensor, ov9724_mipi_raw_sensor, };kd_imgsensor.h中需要添加 imx111 的枚举定义和头文件包含#include kd_imgsensor_define.h #include imx111mipiraw_Sensor.h typedef enum { IMX111_MIPI_RAW_SENSOR_ID 1, // 其他 sensor ID } KD_IMGSENSOR_ENUM;这段注册逻辑的本质是把 sensor 驱动文件的KDIMGSENSOR_FUNC_STRUCT实例暴露给上层探测框架。KDIMGSENSOR_FUNC_STRUCT中主要包含open、close、getSensorID等函数指针探测框架通过函数指针调用驱动能力。5.2 Hal 层驱动添加步骤Hal 层主要修改两个位置新增文件夹 mediatek\custom\mt6589\hal\imgsensor\imx111_mipi_raw\ imx111mipiraw_Sensor.cHal 层的 Sensor 参数配置 imx111mipiraw_Camera_Sensor.cCamera 参数配置 修改文件 mediatek\custom\common\hal\imgsensor\src\sensorlist.cppsensorlist.cpp中需要在全局 sensor 列表中加入 imx111static SensorList sensorList[] { {IMX111_MIPI_RAW_SENSOR_ID, imx111_mipi_raw}, // 其他 sensor };5.3 常见遗漏点名字不一致导致探测失败在添加新 sensor 驱动时最容易踩的坑是Kernel 层的 sensor name、Hal 层的 sensor name 和 ProjectConfig.mk 中的配置名三者不完全一致。MTK 探测框架使用字符串匹配来确认驱动与配置的对应关系任何一处不一致都会导致Kernel 层驱动加载了但 Hal 层找不到对应的 sensor 参数打开 Camera 时直接报错ProjectConfig.mk 中配置了 sensor但kdSensorList[]数组没有注册开机日志根本不会出现该 sensor 的探测记录还有一个容易被忽略的细节imx111_mipi_raw中的_mipi_raw后缀不是随便写的它决定了 sensor 的接口类型。MIPI raw sensor 需要平台开启 MIPI CSI-2 接收端DVP sensor 则不需要。修改新 sensor 驱动时如果接口类型变了还需要同步检查cust_imgsensor.c中 MIPI 相关配置。6. 排错实操如何用 kernel_log.boot 快速定位前后摄探测冲突6.1 日志过滤与特征字段提取拿到kernel_log.boot后按以下顺序提取关键信息。过滤出所有 sensor 探测日志grep -a sensor probe kernel_log.boot每次探测会输出一行日志包含pDrvIndex信息、sensor 名称和探测结果。需要关注的是同一 sensor 是否出现在两行日志中且第二个字段不同grep -a imx111mipiraw kernel_log.boot对比输出的日志行如果发现[0][1][1]和[0][1][2]都出现了sensor id且数值相同基本可以判定该 sensor 存在前后摄探测串扰问题。6.2 日志中传感器 ID 与上电序列的对应关系探测日志中输出的 sensor ID 值也值得分析。实际项目中如果两次探测读到的 ID 不相同可能意味着第一次读到的是 sensor 上电不完全时的随机值第二次读到的是正确 ID这种情况下问题通常出现在上电时序上kdCISModulePowerOn中某个电源域的稳定等待时间不够导致 sensor 还没完全启动就被读取寄存器。处理方法是在kdCISModulePowerOn的电源建立后增加延迟比如mdelay(10)或udelay(100)具体值需要根据 sensor datasheet 中的 power on sequence 和实际波形确定。6.3 特定场景排查双摄同时使用时后摄无图像的现场定位针对前后摄同时使用时的异常推荐以下排查流程# 抓取完整的 mobilelog包含开机和相机操作阶段 adb shell mkdir /data/mobilelog chmod 777 /data/mobilelog adb shell logcat -c # 开启相机切换前后摄抓取日志 adb pull /data/mobilelog/在日志中搜索关键函数名grep -a kdCISModulePowerOn\|kdCISModulePowerOff\|camera_pdn_reverse kernel_log.boot同时关注传感器驱动的open和getSensorID是否被再次调用grep -a getSensorID\|imx111open kernel_log.boot如果日志中出现后摄open时调用了getSensorID说明该 Sensor 在运行期仍然走探测流程而非正常的open流程此时应检查上层是否错误调用了KDIMGSENSORIOC_T_CHECK_IS_ALIVE。6.4 快速验证手段短接 GPIO 模拟 PWDN 极性当怀疑 PWDN 极性配置错误导致问题但不想反复重新编译内核时可以在硬件上用杜邦线短接 PWDN GPIO 到地或电源观察 sensor 是否能被正常枚举。如果短接后日志中该 sensor 的探测结果发生改变可以确认 PWDN 极性确实配反了。这个方法在模组调试初期特别实用能快速区分「硬件接错」与「驱动配置错误」。更进一步的定位手段是直接在kdCISModulePowerOn中临时加入 GPIO 状态打印// 临时调试代码确认 PWDN 引脚的输出状态 printk(PWDN GPIO %d, camera_pdn_reverse %d\n, gpio_get_value(CAMERA_CMRST_PIN), camera_pdn_reverse);通过kernel_log.boot中新增的打印可以确认代码设置的是高电平还是低电平再与硬件原理图上的有效电平比对就能判定极性配置是否正确。整个排查过程不需要反复编译烧录修改kd_camera_hw.c并在kernel_log.boot中观察输出即可完成。最后一次强调kernel_log.boot里[0][1][1]与[0][1][2]两组日志在同一 sensor 上都出现 read ID 成功时优先查看camera_pdn_reverse的赋值位置和生命周期这是双摄项目中最容易出问题的环节也是 89 平台后续几个平台沿用至今的排查起点。本文还有配套的精品资源点击获取
返回列表