ZYNQ裸机跑LWIP,频繁收发,时间一长就会死机问题解决
问题描述:
前阵子已经调试好数据收发,在去老化跑硬件的时候,发现数据频繁收发久了会死机,当时第一反应就是lwip的内存泄漏,或者指针跑飞,但到底是哪个地方,重现概率又很小,着实头秃.网上查阅资料
但是也看到了说1.4版本以上这个bug被官方修复完毕,而我用的lwip版本是2.1.1,理论上不会再出现指针自己指向自己的问题,但我不甘心,跟着楼主操作一番
发现果然不是这个地方的问题,参考了一下大多数人都是开线程上轮询的办法来获取网口数据,而我是采取中断的方式获取数据,难道是中断的问题?后来静下心来满满定位问题,发现每次都是在发送数据的时候翻车的,有头绪了。
原因分析:
我是在裸机上跑的lwip,数据接收由回调函数处理,回调函数已经涉及到tcp_recved,而tcp_recved包含了tcp_output,同时,lwip的定时器里面在跑一个的tcp_slowtmr,tcp_slowtmr里面也有tcp_output,在我传输数据时,主程序中由于数据需要立即回复,所以我的每一个tcp_write后面都跟着一个tcp_output,这就造成了tcp_output很有可能在执行一半的时候被打断,也就是重入了,查看tcp_output
前面省略。。。。
后面省略。。。。
定位每次都是执行到tcp_output_segment之后就被打断重入了,下面一段代码
显然,重入之后,再执行回原点位置开始执行的话,指针数据会跑飞。
解决方案:
其实tcp_output这个函数就是把tcp_write写入缓存的内容立即发送出去,如果被重入了,那么先跳出来即可,后面定时器跑的tcp_slowtmr也会把需要发送的数据再发送出去,重入的数据并不会被丢弃,所以我在tcp_output函数开始的地方添加锁,结束的地方解锁,如果有重入数据进来,那么直接退出去就好了。
以上仅个人记录