C6678网口初始化失败

C6678的网络协处理器NETCP模块有两个对外千兆网口,但PDK提供的网口驱动示例只支持单网口,需要做修改。采用多核导航器描述符中的一个字段来区分两个网口完成了这一任务。使用了几个月后没有出现大的问题。然而某一天当工程的优化属性配置为O3优化时,网口启动有一定概率失败。将O3优化取消再测,则启动一直能成功。

首先定位是哪里出现问题,将单独的网口驱动文件取消优化再测,没有出现失败的情况,因此将问题聚焦到网口驱动中。

然后分析代码,画出网口模块的初始化流程图。在这个过程中发现其中有延时操作。因此重点怀疑是延时时间不够,查手册后发现手册中并不要求延时,这里是照抄PDK示例代码,但将其扩大一百倍后再测仍有概率出错,因此主要问题不在延时上。

这时需要进一步精细定位。把驱动文件拆分为两个文件,一部分优化一部分不优化,用这个方法来精细定位到函数级别。最后发现是硬件初始化的几个函数有问题。但这几个函数中并不涉及延时操作,只是单纯的配置寄存器。对照文档逐比特查看配置的寄存器值,并没有发现问题。

这时调试又陷入僵局。只能再次仔细分析文档和代码。在阅读文档过程中发现代码中的初始化流程与文档要求不一致。会不会是这个问题呢?
修改代码的初始化流程后再测,居然成功了。O3优化后测试近百次,也没有再出错。问题解决。

回过头来再分析,为什么原来没有出错,而O3优化后就出错了呢?应该是某个时序上正好处于临界值,无优化时恰好符合条件,当优化后又恰好不符合条件。因此优化只是将原本就存在的问题放大并暴露出来而已。

联想到另一个C6455网口驱动的Bug。在测试完毕后交付使用,然后某次在某个网络中,一台机器死活ping不通本板。最后在该机器上WireShark抓包发现本板发送的ARP包有问题,其FCS校验不通过因而被该机器丢弃。与正常的ARP包相比发现有问题的包最后四字节为全零,而非以太网数据帧的帧校验。
最后也是花费了大量时间排查问题,最终证明是C6455网口驱动中用于补齐小包的分支中将小包错误地补齐到了64字节,而非正常的60字节(不含FCS)。而这处错误正是从TI的示例代码中沿袭而来。

这些教训都证明了一个真理:Demo不可信,抄袭要谨慎!

你可能感兴趣的:(C6678)