ARTICLE DETAIL

资讯详情

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

MTK6582平台imx135 sensor驱动开发:从datasheet到联调实战

MTK6582平台imx135 sensor驱动开发:从datasheet到联调实战 简介面向联发科MTK6582平台安卓驱动开发者的IMX135摄像头驱动源码与数据手册整合包覆盖传感器移植与调试所需的关键资料。包内共24个文件以C/C头文件与源文件为主12个h、6个cpp、1个c另含2份PDF手册索尼官方IMX135规格书与打印预览版和3个文本说明压缩包仅2.43MB轻量便于快速学习。已有273人学习下载适合正在从事MTK平台Camera移植、图像质量调优或驱动学习的开发者。从内容看驱动源码遵循V4L2框架涵盖模块注册、I2C通信、传感器与PLL初始化、MIPI CSI-2接口及DMA数据通路文本说明针对驱动移植、闪光灯移植和相机性能优化配合PDF中的电气特性、像素格式、电源时序等参数可帮助定位适配问题是理解MTK Camera驱动架构与IMX135传感器特性的实用参考。1. 从 imx135 datasheet 到 MTK6582 驱动这个组合到底要解决什么问题MTK6582 平台加 imx135 sensor是 Android 4.4 时代千元机最典型的 camera 方案。imx135 是索尼的 1300 万像素 Exmor RS 背照式 CMOS走 MIPI 接口而 MTK6582 内置的 ISP 需要一套完整的 sensor 驱动源码才能把数据流从 sensor 拉到屏幕预览。标题里同时给了「驱动源码」和「datasheet」说明你不只是要跑通一个摄像头而是要从寄存器手册一路读到驱动代码的每个分支最后让预览、拍照、录像三条链路都稳定工作。这篇文章适合三类人需要在旧平台上移植 sensor 的 BSP 工程师、维护古董项目但还没摸清 imx135 细节的底层开发以及想搞明白 MTK camera 架构里 sensor 层到底做了什么的学生。我会按 datasheet 精读、驱动结构拆解、联调排错的顺序把这条路完整走一遍。2. imx135 datasheet 精读先抓住 4 个关键寄存器再碰代码2.1 为什么 datasheet 比源码更先决定成败很多新手拿到 imx135 驱动源码第一反应是直接搜 preview 函数、找初始化序列然后迫不及待地编进内核。这个顺序在 MTK6582 平台上大概率会让你多花两天排一个本来可以避免的错。原因在于MTK6582 的 camera 驱动架构里sensor 驱动只是中间的一层它依赖两个外部输入——I2C 地址和 chip id 寄存器定义来自 datasheetMIPI lane 数和时钟频率来自硬件原理图与 sensor mode 表。如果这些参数和硬件不匹配驱动在 probe 阶段就会直接失败连 log 都不太容易看懂。我一般的做法是动代码之前在 datasheet 里先确认四件事——sensor 的 I2C 从机地址、chip id 寄存器地址与期望值、MIPI 接口的 lane 分配、以及 sensor 输出格式RAW10 还是 RAW8。其中 chip id 是最重要的。imx135 的 datasheet 里chip id 寄存器通常在 0x0016/0x0017 两个字节上期望值对应型号 ID。驱动源码里的 imx135_SensorInit 函数第一件事就是读这个寄存器读不到或者值不对后面的 init sequence 根本不会执行。2.2 从 datasheet 抄下 I2C 地址和 chip id驱动 probe 的第一道关卡打开 imx135 的 datasheetSony 的 sensor 手册一般是几十页的 PDF前面是电气特性中间是寄存器描述先找两个东西I2C 从机地址表以及 chip id 寄存器描述。常见配置下 imx135 走 8-bit I2C 地址 0x207-bit 地址 0x10但具体是主地址还是副地址取决于 sensor 的 ADO 引脚电平。MTK6582 平台上这个值写在 sensor list 里/* 在 kernel-3.10/arch/arm/mach-mt6582/camera/sensorlist.c 附近 */ static struct imgsensor_list_t sensor_list[] { /* sensor 名字要对应 imx135mipiraw_Sensor.c */ { imx135mipiraw, 0x20 }, // I2C 地址来自 imx135 datasheet };参数说明这里的 0x20 是 8-bit 写地址驱动内部 i2c 读写函数会自动处理 7-bit/8-bit 转换不用你在代码里再移位。I2C 地址如果和 datasheet 不一致probe 读 chip id 时所有寄存器都会返回 0xFFlog 里会看到[imgsensor] imx135_sensor_id_read fail之类的报错。chip id 的检查函数在驱动里长这样static kal_uint32 imx135_get_id(void) { kal_uint32 id 0; /* 读 0x0016/0x0017 两个字节拼成 16-bit id */ id ((read_cmos_sensor(0x0016) 8) | read_cmos_sensor(0x0017)); /* 期望值与 datasheet 中 imx135 的 chip id 一致 */ if (id 0x0135) return ERROR_NONE; return ERROR_SENSOR_CONNECT_FAIL; }这段代码是调试时最常用的一个函数。如果你改完驱动发现 sensor 一直没有 probe 成功第一步就是在这函数里加一条 printk 把实际读到的 id 打出来。如果实际 id 是 0xFF 或者 0x0135 都不对那先别查驱动回头量 I2C 波形、确认 sensor 供电和 MCLK 是否到位顺序不能反。2.3 imx135 的 mode 表每一个分辨率都是一组寄存器组合datasheet 里最值钱的部分其实是 mode 表。imx135 支持最大 4208x3120 的输出也支持 1080p、720p 等裁剪模式而每一种分辨率对应一组完全不同的寄存器配置——包括水平/垂直消隐、增益、曝光、输出尺寸。在 MTK6582 的 imx135 驱动里这些 mode 会被组织成imgsensor_mode_struct数组static struct imgsensor_mode_struct imsensor_mode_data[] { /* IMGSENSOR_MODE_PREVIEW / CAPTURE / VIDEO 都需要 */ { .pclk 420000000, /* 像素时钟需要从 datasheet 的时序参数换算 */ .linelength 2100, /* 一行包含消隐的总长度 */ .framelength 2016, /* 一帧包含消隐的总行数 */ .startx 0, .starty 0, .grabwindow_width 1280, .grabwindow_height 960, .mipi_pixel_rate 420000000, }, };参数说明pclk是 sensor 输出的像素时钟由 datasheet 推荐设置和主控 MCLK 决定linelength和framelength直接决定帧率——帧率 pclk / (linelength * framelength)。这三个参数如果和 datasheet 算出来的不一致预览会花屏或者帧率不对。MTK6582 平台的常见坑是 pclk 设得过高导致 ISP 带宽不够画面出现横纹后面联调章节里会专门讲。3. 驱动源码结构拆解把 imx135 驱动从 probe 到 preview 串起来3.1 一段最小可用的 imx135 sensor 驱动骨架拿到 imx135 驱动源码后先别急着编译按文件功能把它分成三层控制层SensorInit / GetInfo / Preview 函数、I2C 读写层read_cmos_sensor / write_cmos_sensor、配置层camera_para 和 mode 表。MTK6582 的 imx135 驱动一般叫imx135mipiraw_Sensor.c放在kernel-3.10/drivers/misc/mediatek/imgsensor/src/下。整个文件的核心入口是sensor_init和sensor_control上层通过 ioctl 调用下来。最精简的驱动骨架长这样static struct imgsensor_ctrl_t imx135_ctrl { .sensor_init imx135_init, /* 上电后初始化寄存器序列 */ .sensor_control imx135_control, /* 处理 preview/capture/etc 命令 */ .sensor_id IMX135_SENSOR_ID, /* 内部用于匹配 sensor list */ }; static int imx135_control(enum IMGSENSOR_IOCTL_CMD cmd, void *arg) { switch (cmd) { case IMGSENSOR_CTL_INIT: imx135_init(); break; case IMGSENSOR_CTL_SET_READ_GAIN: /* 设置模拟增益对应 datasheet 的 gain 寄存器组 */ imx135_set_gain(arg); break; } return 0; }这段代码精妙的地方在于它把 sensor 和主控解耦了。上层 camera HAL 不会知道 imx135 的存在只通过imgsensor_ctrl_t这个接口下发命令。你改仿真的 sensor 驱动时只要保证这些回调都存在上层代码一行不用动。逻辑说明sensor_control是每个命令的入口你收到什么命令就执行什么函数参数说明arg在 SET_READ_GAIN 时是一个整型指针值代表增益倍数这个倍数怎么换算成寄存器值需要查 datasheet 的 gain 表格。3.2 配置 camera_paraEEPROM、lane 数、时钟在哪个文件里改MTK6582 平台的 sensor 驱动并不是一个孤立的文件。除了imx135mipiraw_Sensor.c你还需要处理 camera_para 里的 EEPROM 配置、工程模式参数、以及 MTK 特有的camera_para.c文件。camera_para 文件里保存的是每个分辨率下的微调参数包括 AWB、AE 的初始收敛范围、以及 sensor 模组厂商写入的校准数据映射。实际开发中你会改动的文件一般有三个文件作用常见改动点imx135mipiraw_Sensor.csensor 寄存器操作初始化序列、增益映射、mode 表camera_para.c预览/拍照的初始参数EEPROM 偏移地址、校准数据读取方式kd_camera_hw.c或camera_clock.c上电时序和时钟配置MCLK 频率、DVDD/AVDD 上电顺序这里有一个 MTK6582 特有的参数值得注意sensor 的 MIPI lane 数量和 data rate。imx135 是 4-lane MIPI 接口如果你模组实际只拉出 2 条 lane省钱方案那么驱动里的mipi_data_rate和imx135_SensorSetup里的 lane 配置必须同步改否则画面只能出一半或者完全黑屏。改法是在 sensor 初始化函数里找到 lane 设置的地方/* imx135 SensorInit 尾部设置 MIPI 相关寄存器 */ write_cmos_sensor(0x0114, 0x03); /* 0x03 4-lane, 0x01 2-lane */ write_cmos_sensor(0x0115, 0x02); /* 差分输出设置由 datasheet 表给出 */参数说明0x0114 是 MIPI lane number 配置寄存器bit[1:0] 表示 lane 数减一4-lane 写 32-lane 写 1。0x0115 是连续时钟模式设置建议直接抄 datasheet 推荐值不要自己发明。3.3 三个最常改的小函数preview、capture、night mode源码里你会经常跟三个函数打交道。第一个是 preview 的实现一般叫imx135_preview它会把 sensor 切到预览分辨率、设置合理的曝光和增益初始值第二个是 captureimx135_capture拍照瞬间要把 sensor 切成全尺寸输出第三个是imx135_night或者低光模式本质是同一套初始化序列加长曝光时间。这三个函数的共同点是开头都是一长串write_cmos_sensor(0xXXXX, 0xYY)。随便截一段预览初始化如下static void imx135_preview(kal_uint32 dumb) { /* 先把 sensor 切成 preview 模式 */ write_cmos_sensor(0x0100, 0x00); /* 关闭 sensor stream */ /* 设置 preview 尺寸相关寄存器 */ write_cmos_sensor(0x0340, 0x07); /* framelength 高位 */ write_cmos_sensor(0x0341, 0xE0); /* framelength 低位 */ write_cmos_sensor(0x0342, 0x08); /* linelength 高位 */ write_cmos_sensor(0x0343, 0x34); /* linelength 低位 */ /* 打开 sensor stream */ write_cmos_sensor(0x0100, 0x01); }这些寄存器的含义在 datasheet 的 register map 里都有明确描述——0x0340/0x0341 是帧长0x0342/0x0343 是行长0x0100 是 stream on/off。注意0x0100的时机改任何尺寸相关参数前必须先把 stream 关掉否则 sensor 内部状态机可能不同步。这条经验在 MTK6582 平台尤其重要因为 ISP 侧的同步信号以 sensor 的 vsync 为准你关闭 stream 的瞬间如果再等一帧 vsync能避免大量的花屏问题。4. mtk6582 平台联调避坑5 个一定会遇到的现场与处理顺序4.1 现象一preview 黑屏但 log 无 error现象预览界面是黑的但 dmesg 里没有任何 camera errorlogcat 里只有Camera HAL open正常。原因有三个方向sensor 没在出图、ISP 没收到数据、LCD 图层错误。排查顺序是固定的。先看 dmesg 里有没有[imgsensor] imx135 preview ok如果有说明 sensor 侧已经出图问题在 ISP 或者显示层如果没有说明 preview 函数没执行或者执行失败。这时在imx135_preview函数入口加一个 printk确认确实被调到了。如果被调到但仍黑屏用示波器量 sensor 的 MIPI 时钟脚确认有没有波形——没有波形就去查上电时序最常见的问题是 DVDD/AVDD 上电间隔太短sensor 处于半复位状态I2C 能通但 MIPI 不工作。解决把上电时序的延时从 1ms 拉到 10msMTK6582 的kd_camera_hw.c里camera_power_on函数每步之间加延迟。这种「I2C 通但 MIPI 不出」的现场是最折磨人的因为驱动看起来一切正常。4.2 现象二启动 camera 直接 abortlogcat 里有 NULL sensor现象点击相机 icon 后 app 立刻退出logcat 里能看到CameraService: getCameraInfo failed或者NULL sensor。原因sensor list 里没匹配到 imx135。不是驱动没编译进去就是 sensor list 的名字和驱动文件里的名字不一致。MTK6582 平台的 sensor list 匹配是字符串精确比对imx135mipiraw少一个字母都不行。解决打开sensorlist.c确认 sensor 名字和imx135mipiraw_Sensor.c里struct imgsensor_ctrl_t的.sensor_name完全一致注意大小写。这条坑的隐蔽之处在于编译不会报错只是运行时匹配失败你可能会在 HAL 层浪费很多时间。4.3 现象三画面偏绿/偏紫AWB 实效现象预览画面整体偏绿或偏紫自动白平衡不收敛手动调 AWB 也不对。原因可能是两个一个是 sensor 的 color matrix 配得不对另一个是 lens 的 shading 校准数据没正确加载。在 MTK6582 平台偏紫通常是 ISP 的 color correction 矩阵在等 EEPROM 里的校准数据而 imx135 模组如果没有 EEPROM 会在初始化后写一段默认参数这段默认参数如果和 sensor 的实际色彩响应偏差大就会出现偏紫。解决先确认 camera_para 里是否配置了 EEPROM。如果模组有 EEPROM 但驱动没读修改 camera_para 里 EEPROM 的 slave addr 和偏移地址。如果模组没有 EEPROM就得在 imx135 驱动里把一套可靠的 color matrix 作为默认值写死。这里值得用掉半天时间找一个同平台其他项目的 imx135 camera_para 作为参考往往比对着色卡调更快。4.4 现象四录像卡顿预览帧率只有 15fps现象录像时画面明显不流畅用adb shell dumpsys media.camera看帧率只有 15fps 左右。原因pclk 和 sensor mode 不匹配。MTK6582 的最大 ISP 输入带宽有限如果 imx135 的 mode 里 mipi_pixel_rate 设得太高ISP 会丢掉部分帧设得太低帧率也起不来。另一个常见原因是 sensor 初始化时 framelength 没配够导致 sensor 的实际帧率预算不够。解决按公式重新算一遍这一行。比如目标是 30fpspclk 设为 420MHzframelength 420M / (30 * linelength)。如果算出来小于 datasheet 推荐的最小值就说明 pclk 不够得把 pclk 调大。假设 linelength 是 2100那么 framelength 420000000 / (30 * 2100) ≈ 6666。如果 imx135 的最大 framelength 只有 6000那 pclk 至少要提到 378MHz 以上。这种换算是在联调现场最常做的计算别偷懒。4.5 现象五EEPROM 读出来全 0xFF现象打开 camera 能看到画面但画质差把 EEPROM dump 出来看全是 0xFF。原因EEPROM 挂在和 sensor 同一条 I2C 总线上但地址可能不同。imx135 模组的 EEPROM 常见地址是 0xA08-bitMTK6582 的 camera_para 里默认可能写的是 0x507-bit两者差一位导致读写失败。解决把 EEPROM 的地址换算统一。camera_para 里填的是 8-bit 还是 7-bit要看你的 I2C 读写函数怎么处理。MTK6582 的i2c_write_datas函数用 8-bit 地址所以直接填 0xA0。如果换了一颗 EEPROM先量的它的地址引脚电平再对照 datasheet 确认地址别默认所有模组都是同一颗 EEPROM。这个坑我在不同项目的 sensor 调试里遇到不止一次每次都浪费了半天时间。5. 收在验证与进阶用 log 和一张图确认驱动「真交了差」5.1 一路查到底logcat dmesg 双通道验证流程驱动编译完不要直接打开相机测功能。先把命令通道搭好让你能看到 sensor 层发生了什么。我习惯一次性开三个终端一个adb logcat | grep -i imx135一个adb shell dmesg | grep -i imgsensor一个adb shell cat /proc/driver/camera检查 sensor list 是否加载成功。验证顺序也有讲究先确认 probe 成功再测 preview最后测 capture。每个环节看不同的 log 关键词——probe 看sensor_idpreview 看preview okcapture 看capture done。如果你在 logcat 里看到[imgsensor] imx135(0x0135) sensor_id read ok这样的信息说明驱动和硬件之间的匹配已经打通了后续的坑大概率在 ISP 配置而不是 sensor 本身。5.2 进阶用一张灰阶卡验证 sensor 输出没有暗角与坏点功能通了不代表能交货。我最后总会做一件事拍一张均匀光照下的灰阶卡照片然后用 ImageJ 或者 Python 脚本检查四角亮度差和坏点数量。# 抓一张 raw 图检查四角亮度 (需要先进入工程模式) adb shell echo capture /sys/devices/platform/camera/capture adb pull /sdcard/DCIM/test_raw.raw . python3 check_shading.py test_raw.raw --width 4208 --height 3120脚本的逻辑很简单把图像分成 3x3 九宫格比较中心格和四角格的平均亮度。如果四角亮度比中心低 20% 以上说明 lens shading 校准没生效如果出现单个像素点亮度异常说明 sensor 有坏点需要做坏点校正或换模组。这个验证做完imx135 的驱动工作才算真正收尾。回头看我自己的调试经历卡得最久的一次就是 4.1 的黑屏问题查了两天最后发现是上电时序里 AVDD 和 DVDD 之间缺了 10ms 延时而驱动代码本身一行没动。从那以后我给自己定了一个规矩任何 sensor 驱动问题的排查顺序永远是硬件时序 → I2C 通信 → sensor 寄存器 → ISP 配置 → 上层 HAL而不是反过来从 log 往下猜。这个顺序救了我不止一次希望也能帮到你。本文还有配套的精品资源点击获取
返回列表