08年的时候,我所在的公司调试三星的一款新的arm9 CPU,型号是S3C2416,是S3C2450的简配版。开发板刚入手的时候还是热乎的,因为三星的这个芯片刚刚出来,国内的代理商一共就几块开发板。各公司评估开发板都是分时使用的,只能预约几天。开发板入手的时候,三星那面连BSP都没有准备好,没有test code,没有u-boot,没有linux-kernel,甚至连Spec都是错误百出。还好我公司虽然小,研发能力在本地区还算不差,没有的东西可以自己移植。
公司急着要出新品,在没有完全验证处理器的情况下,已经layout好了PCB,并且去打样了(当时竞争确实比较激烈,400M主频处理器而且这么低的价格绝对非常有诱惑力,所以公司决定冒这个险了)。在没黑没白的工作两周后,硬件和软件做的都差不多稳定了。这时候经理说,功能上问题不大了,我们来调一调休眠时的功耗吧(我们的产品一直以待机时极低功耗作为产品的卖点之一)。然而这却是噩梦的开始……
公司的指标是待机时休眠电流500uA~800uA(电源电压4V)之间。以前所有的产品都在这个范围之内,三星方面的技术支持也明确表示,他们的解决方案达到这个指标。
在我们调试过程中发现,整个系统休眠时的功耗在1800uA左右,一直降不下来。我们重新核对了所有的IO和外围电路的所有连接,以及IO口的电平配制,都没有问题。这时,我们决定测试每一个单元的功耗,用电流表分别串联进每一个外围电路,每个单元都很正常,就是系统总体偏大1000uA。
我们连flash和ram的待机电流都测过了,仍然正常。好了,通过排除法已经确定了就是CPU的功耗过大。但是在开发板上调试休眠的时候,CPU功耗却是正常的。
我们怀疑是开发板上CPU批号和我们自己拿到的CPU样品的批号之间有区别导致的,因为三星那面也在同步修正CPU的BUG,所以我们“大胆地”把开发板上的CPU用风枪吹下来,换到我们的PCB上,把我们的CPU贴到了开发板上进行交叉验证。结果是开发板仍然功耗正常,我们自己的板子上功耗偏大,还是大了1000uA。
CPU周边的核心电路设计出现了问题!这是我们一致的判断!但是问题出在哪里,我们反复核对开发板的原理图和我们自己板子的原理图,简直就是一模一样!因为整个核心电路这部分就是从开发板上抄过来的,实在没有什么可比对的。我们转而又去怀疑PCB的问题了。
我是做系统移植和软件的,纯电气的问题我就无能为力了。闲着没事,我就反复检查我在linux中对系统休眠的IO引脚配置。然后挂着电流表做反复测试。电流表也对的起我,每次都是那个数。在一次系统待机的时候,我实在忍无可忍,一把抓起了板子。突然之间,电流表的读数飞快下降,降到了300uA!我松开手电流表的读数就又爬回来了。我把我这个惊奇的发现告诉了同事——一个硬件工程师。同事说可能是哪儿摸短路了,让我试试还能不能唤醒系统。我给了一个外部中断,系统神奇的正常唤醒了!
“难道这就是问题?”,我想重现一下。但是再次在待机的时候抓起电路板的时候,读数并没有显著发生变化。“可能是手法不好”,我这么想着,用手在板子上继续抚摸着。果然!当我的手指按到PCB中的某一个位置时,电流又降了下来!反复试了几次,都是这样,就是在我手指按压的这一片,只要是用手指按着,电流就正常!
这回同事开始重视了,打开PCB图,拿着电路图和万用表,查查我摸的到底是那块电路。硬件工程师觉得不可思议,因为我摸的部分并没有连接任何的电路——焊盘是空的。他于是用万用表的表笔去检查是不是PCB制版的问题,测一下这些空焊盘到底哪一个有电压。但是万用表中没有读数,这块都没有电。但是当万用表的表笔落在一处空焊盘的时候,电流表的读数又降下来了!
这可是重大发现,我们对照了一下电路图。这处空焊盘是CPU中USB-Host模块的D+信号。由于我们的产品不需要USB的主机功能,所以这一块儿没有做任何处理。多亏了画原理图和PCB的同事,多留了一手,把USB Host的引脚都在PCB上做了个引出。谁也没想到是这个引脚出现了问题,辛亏这个信号引出来了,要是没有引出来,一辈子也查不出问题。我们给D+信号加了一个下拉电阻后,系统的功耗瞬间正常了。
事后分析,三星自己开发板上有USB-Host的功能,所以USB-Host的外围电路也是完备的,所以功耗不会有问题。但是我们自己的产品上不使用USB-Host功能,没有相关外围电路,所以出了问题。这是因为在CPU休眠的时候,D+信号内部被悬空了!一句话,是三星CPU自己的BUG。我们修改了我们的PCB,增加了一个下拉电阻,同时将问题反馈给了三星。
一个月后,当我们的产品量产时,三星也及时的解决了这个问题。那个下拉电阻也不需要再贴上去了。
最后用手指头找到了CPU的BUG,不知道这算不算是最难调的。
反正这么多年了,这个经历留给我的印象是最深的。