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

资讯详情

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

040、sensor上电时序的毫秒级精度——AVDD/DVDD/IOVDD加载顺序错误导致的诡异花屏——从示波器抓取到驱动代码修正的完整排查案例

040、sensor上电时序的毫秒级精度——AVDD/DVDD/IOVDD加载顺序错误导致的诡异花屏——从示波器抓取到驱动代码修正的完整排查案例 040、sensor上电时序的毫秒级精度——AVDD/DVDD/IOVDD加载顺序错误导致的诡异花屏——从示波器抓取到驱动代码修正的完整排查案例凌晨两点半实验室的灯还亮着。面前这块搭载OV5640模组的样机屏幕上的画面像被揉皱的锡箔纸——横向条纹、随机彩点、偶尔整屏泛绿但最诡异的是这花屏不是每次都出现。十次上电三次正常七次花屏而且花屏的形态每次都不一样。客户那边反馈说“低温环境下概率更高”但我们在常温下复现率已经够让人头疼了。第一反应是MIPI信号完整性。毕竟花屏嘛十有八九是lane上数据错位。拿起示波器怼上clock lane和data lane眼图看着还行摆幅够上升沿也没明显畸变。又怀疑是sensor初始化寄存器没写对翻来覆去对照datasheet检查了不下五遍甚至把初始化序列里每个寄存器的延时都拉长了一倍问题依旧。这时候才有人小声提了一句“会不会是上电时序的问题”说实话当时心里是有点不屑的。上电时序这种基础功课硬件原理图设计阶段就该确认过驱动代码里也写了对应的延时怎么可能是这里。但架不住没别的思路还是把示波器探头挂到了AVDD、DVDD、IOVDD三路电源上触发条件设成AVDD上升沿抓上电瞬间的波形。这一抓问题就现形了。AVDD先起来这没问题datasheet要求AVDD先于DVDD和IOVDD。但DVDD和IOVDD的间隔只有不到200微秒。而OV5640的datasheet上白纸黑字写着DVDD和IOVDD之间需要至少1毫秒的间隔而且IOVDD必须晚于DVDD稳定。更麻烦的是IOVDD的上升沿上还叠了一个明显的毛刺——那是DVDD的耦合噪声因为两路电源在PCB上走线挨得太近而DVDD起来时的大电流抽动干扰了还没稳定的IOVDD。为什么是间歇性花屏因为200微秒的间隔虽然不满足规格但sensor内部的POR电路有时候能扛过去有时候扛不过去。扛过去就正常出图扛不过去就进入一种半初始化状态——寄存器能写进去但内部模拟前端和像素阵列的偏置没建立好输出就是花屏。低温下概率更高因为低温时电源芯片的启动特性变化间隔会更短毛刺更大。根因找到了但怎么改硬件那边说PCB已经投板改走线要等下一版时间等不起。那就只能在驱动代码里做文章。我当时的思路是既然硬件时序不达标那就用软件把时序“拉”到达标。具体做法是在驱动初始化函数的最开头把IOVDD对应的GPIO控制引脚先拉低然后通过一个精确的延时函数确保AVDD、DVDD、IOVDD三路电源的加载顺序和间隔都满足datasheet要求。这里踩过一个大坑。最初我直接用了mdelay(2)想着延时2毫秒总够了吧。结果上机一测花屏概率反而更高了。后来查了内核源码才发现mdelay在有些平台上会被编译成忙等待但有些平台会调用schedule_timeout一旦被调度出去延时精度就完全不可控。而且我们的驱动是放在probe函数里跑的probe上下文里如果触发了调度整个上电时序的毫秒级精度就全毁了。正确的做法是使用usleep_range配合忙等待的混合策略。具体来说在AVDD和DVDD之间用usleep_range(1000, 1100)在DVDD和IOVDD之间用usleep_range(1500, 1600)并且在每次延时前后都读取一下GPIO状态确认电源域确实已经稳定。别这样写usleep_range(1000, 2000)——这个范围太宽如果内核调度导致实际延时落在1.5毫秒以上虽然满足规格但会让后续的sensor软复位时序变得紧张。我最终用的是固定下限、窄上限的写法确保每次延时的实际值都在规格窗口内。代码修正后花屏概率从七成降到了零。但这事儿还没完。我后来在另一个项目里又遇到了类似问题这次是安霸方案配索尼IMX290症状是画面右半侧有固定竖条纹。有了上次的经验我第一件事就是抓上电时序果然IOVDD和DVDD的间隔只有300微秒而且IOVDD的上升沿斜率特别缓足足有800微秒才爬到90%。这次硬件能改板但改板周期要三周客户等不了。我用了另一个招在驱动里把sensor的软复位引脚拉低然后通过GPIO模拟一个“伪上电”过程——先把所有电源域通过GPIO控制强制拉低再按正确时序逐路释放。这招的本质是绕过硬件电源管理芯片的默认行为用软件接管上电控制权。效果立竿见影竖条纹消失画质完全正常。这两次经历让我总结出几条个人经验写在这里供参考。第一上电时序问题最隐蔽的地方在于“间歇性”。如果故障是100%复现反而好查因为你能稳定抓到错误波形。间歇性故障意味着时序参数刚好落在规格边缘这时候不要只盯着示波器看一次波形要抓十次、二十次把每次的间隔时间都记录下来看分布。如果发现间隔时间在规格临界点附近抖动那基本就是时序问题没跑了。第二驱动代码里的延时函数选择直接决定上电时序的精度。mdelay在多数平台上会忙等但有些内核配置下会变成可调度的睡眠这是致命的。usleep_range虽然精度高但范围不能太宽。我个人的习惯是凡是涉及sensor上电、复位、PLL锁定这类毫秒级时序的操作一律用udelay加忙等待宁可占用CPU也不让出调度。代价是功耗高一点但换来的是时序确定性值。第三也是最容易被忽略的一点上电时序不只是“顺序”问题还有“斜率”问题。IOVDD上升沿太缓会导致sensor内部电平转换电路在阈值附近反复震荡轻则寄存器写入错误重则损坏IO口。示波器上看到上升沿超过500微秒就要警惕了。这时候软件能做的有限最多是延长后续的延时时间给电源稳定留出余量但根治还得靠硬件改板。第四如果你在调试过程中发现“改了寄存器初始化序列就好了”千万别高兴太早。那很可能只是碰巧把初始化时序拉长了掩盖了上电时序的缺陷。真正的根因还在那里换一颗sensor、换一个温度环境问题就会原形毕露。我见过太多工程师在这个坑里反复跳进跳出最后被客户一句“低温测试不过”打回原形。回到这个案例本身最后交付的代码里我在上电时序那段加了一行注释“此处延时精度要求极高禁止修改禁止使用mdelay禁止优化编译选项。”后来有个新来的同事觉得这行注释太啰嗦自作主张把udelay换成了msleep结果花屏问题在产线上复现整批3000台机器全部返工。从那以后我在这行注释后面又加了一句“改这里的人请先看完OV5640 datasheet第23页的Figure 23-1再看第47页的Table 47-2然后来找我签字。”上电时序这东西看起来是硬件工程师的活但驱动工程师才是最后一道防线。硬件原理图评审的时候多问一句“DVDD和IOVDD的间隔余量是多少”产线测试的时候多看一眼“常温下IOVDD上升沿斜率”能省下后面无数个凌晨两点半。示波器抓波形不丢人丢人的是抓了波形还看不出问题。
返回列表