在单片机项目中,很多难解的、涉及到硬件的bug,往往会采用对比实验的方式,即正常板子和异常板子跑同一份代码来对比现象。
这里有一个很重要的认知前提,就是这份代码不一定没有问题,只能说这份代码放在正常的硬件上没有体现出问题。如果认为软件部分就是完美的判官,那么软件在异常硬件上的行为,可能导致更复杂的现象,这时若认知里执着的认为是硬件的新问题,就跑偏了。
嵌入式的问题是综合而复杂的,而且在长时间的调试之后会产生甩锅思想,主打一个我没问题。其实自己已经在这个地方栽过多次跟头了,都是跟自己看数据手册不细致有关,明明经验不丰富,却又有着完全盲目自大的直觉,靠感觉写代码。
印象很深的一次,是调试一块SPI驱动的DAC,接线很多,看手册下意识认为SYNC是片选的作用,和往常一样直接下拉选中就好,实际上这个IC依靠SYNC的上升沿才会将数据输出为模拟量。
最近的一次是调试H7+DM9000,也正是这个恶心的调试过程,让我有了写这篇记录的想法。这个项目的软件demo是5月在开发板上写好测试过的,现在7月硬件板子打好了开始跑代码测试。说实话DM9000这块片子的背后全是新知识,涉及到H7中MPU与Cache的处理、FMC外设、网络基础、lwip协议栈还有MCU MAC PHY MDI之间的原理和硬件知识,任何一部分的认知不到位,出了问题就根本没法调试。
第一个问题,最开始读不到DM9000的ID,这个直觉看是MCU和DM9000的通信有问题,背后实际是俩问题,一个是DM9000被NE1选中后映射到0x6000 0000的区域,没有做No Cache的处理,另一个是FMC驱动时序,可能由于布线问题,之前在开发板上配置的时序没跑通,放宽了BusTurn这个参数才正常,而且也意识到,这种总线的时序,不能依赖数据手册,得用经验数值去试。
第二个问题是网口灯不亮,没办法,没调试过的片子,发现的问题都这么朴素。其实这个问题的背后是网口自协商的问题,也会引发第三个问题。围绕灯不亮的问题,确实研究了很久,因为同样是网口,LAN8720这种纯PHY的片子,没有程序也能亮灯来反应网线连接和收发情况(后面发现DM9000这种集成了MAC+PHY的片子,确实得先通过程序用FMC配置到工作状态才能亮灯,当然这里又武断了,没准别的集成片子上电后就处于工作状态了)。调试先看到了LED的限流电阻是2kΩ,开发板是510Ω,补习了LED的驱动电流后,发现这里就算电流有点小,也不会完全不亮。周末下午没开灯,像个没头苍蝇一样调试到晚上之后,惊奇的发现网口灯在黑暗中很微弱的闪灯,而按照配置的LED模式,反应连接的灯也在不停的闪,于是便研究网口的自协商协议,发现10M的PHY会以一定的间隔发送NLP时序,100M会在这个基础上插入表示FLP的时序,用于给对方识别再进一步协商。到这里,直觉上认为是RJ45那边过来的信号有问题,但先得排查保证后方的通信和功能正常,于是想起在数据手册瞥见的回环模式,正巧DM9000有PHY和MAC都可以LOOPBACK,摸索之后验证了一下,MAC自发自收正常,MAC+PHY的自发自收正常,同时网口灯也会正确的亮起来指示连接与收发,顺便也验证了FMC数据收发正常,经高手提示后面把自协商关了,锁定为10M,发现可以ping通了,长舒一口气,也算有进展。这里锁定了问题后,就带着问题和硬件同事一起调试,对比开发板发现100M的情况下TX RX差分信号的电平有异常,从2.5V上拉改为3.3V后,自协商显示正常,但实际这个目前还没很好的解决办法,也会导致问题三排查时的认知错误。
第三个问题是DM9000发送UDP包给PC,PC抓包出现以太网帧整体数据错位,原本地址的位置会错位成数据。MAC帧的结构是 前导码+AAA+BBB+DDDDDDDDDD+CRC,PC这边用的是Windows+Wireshark,CRC错误的包已经被网卡丢弃,所以能抓到的以太网帧都是CRC没问题的,而CRC是DM9000自动生成的,说明从DM9000差分线到网线,数据原原本本的送到了PC,而拿开发板跑同样的程序对比,之前确实通信抓包是没问题的。那就奇了怪了,软件没问题,FMC读写没问题,MAC和PHY回环没问题,外部的MDI到PC也没问题,难道硬件还有别的问题?这里犯了两个认知错误,之前问题二真的靠3.3V电压解决了吗,软件层面就没问题吗。研究了各种例程发现,自己的DM9000发送驱动是有问题的,发送数据前或后,应该判断并死等寄存器里发送完成的标志位,才能进行下一次的发送。之前软件在开发板跑没问题,是因为开发板硬件正常,能够跑到100M的速率,H7 400M主频的应用层只管通过协议栈将UDP数据包塞给DM9000,DM9000完全可以通过100M速率消化这些数据包,通信瓶颈本身在于CPU,所以没有判断发送完成也是正常的。但目前带问题的板子,显然是没跑到100M,后面加上死等发送完成后,没有了数据错误的现象,但速率只有7M。所以一股脑的塞数据包,DM9000消化不及时,旧的数据在SRAM中被新数据覆盖,就导致了数据整体错位的现象。
DM9000硬件的问题仍然需要进一步研究,这个过程虽然恶心,但确实能够反应出自己一贯的思维方式的问题,加油吧!