【ESP8266】关于调试fatal exception/自动重启的一些经验分享

本人小白一枚

最近在捣鼓ESP8266的NONOS_SDK开发,本来已经写好了一个工程测试基本功能也没什么问题了,但是发现了一个很严重的问题,就是每次一跑上40来分钟的时候,就会宕机重启,自动重启,真是奇了个怪了,本来这也没啥,但出于对稳定性的追求还是决定把这bug给补上。


一、问题复现

首先还是要确定,是不是就是同一个问题导致的宕机。每次都要等上40分钟还是挺痛苦的。

基本上能确定每次都是这里导致的宕机



二、找对应代码错误点

最奇怪的就是,网上的fatal exception基本上都会有像这样子的

Fatal exception 29(StoreProhibitedCause):
epc1=0x4000df64, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

然而我的却没有……这bug不按常理出牌啊

顺便说一下通常的情况,像上述的fatal exception 我们是可以找到错误地址的,方法如下:

在 (*.S) 文件中找出对应的地址,添加打印以便定位问题。

Fatal exception 29(StoreProhibitedCause):

epc1=0x4000df64, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

比如使用的是 user1.bin,那么就在 user1.S 中找到0x4000df64 地址,并查明对应的函数。

如果使用的是 flash.bin + irom0text.bin,可以在 eagle.S 中查找出错的地址。

虽然我们也未必能看得懂汇编,但是我们可以在附近找一找有没有类似函数名的标签从而定位代码的位置。

比方说


这个我们就能猜到可能是uart0_rx_intrx_handler的代码出了问题。

言归正传,现在这条寻常的思路断了,我们就只能不断通过输出信息来调试了,通过多次重现问题,发现每次在创建TCP连接时宕机的。

这就奇怪了,因为这代码我是抄的啊!2333333
于是只能仔细读读这段代码了,反复读反复测,然后终于发现
/*
 * 函数名:	iot_station_init
 * 描述:		以ESP8266为客户端,建立tcp连接
 * 输入:		remote_ip:服务器IP
 * 			local_ip:本地IP
 * 			remote_port:服务器端口
 * 返回:		true:成功
 * 调用:		无
 */
bool ICACHE_FLASH_ATTR iot_station_init(struct ip_addr *remote_ip ,struct ip_addr *local_ip ,int remote_port )
{
#ifdef DEBUG
	os_printf("\r\ncall iot_station_init\n");
#endif
	os_printf("\r\n3");
	user_tcp_conn.type = ESPCONN_TCP;
	user_tcp_conn.state = ESPCONN_NONE;

	user_tcp_conn.proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
	//
	os_printf("\r\nuser_tcp_conn.proto.tcp: %X", user_tcp_conn.proto.tcp);
	os_memcpy(user_tcp_conn.proto.tcp->local_ip ,local_ip,4);
	os_memcpy(user_tcp_conn.proto.tcp->remote_ip ,remote_ip,4);
	user_tcp_conn.proto.tcp->local_port = espconn_port();
	user_tcp_conn.proto.tcp->remote_port = remote_port;
	os_printf("\r\n4");
	espconn_regist_connectcb(&user_tcp_conn ,user_tcp_connect_cb);
    espconn_regist_reconcb(&user_tcp_conn ,user_tcp_recon_cb);
#ifdef DEBUG
	os_printf("\nespconn_connect");
#endif
	espconn_connect(&user_tcp_conn);
	//os_free(user_tcp_conn.proto.tcp);
	//os_printf("\r\nfree: %X", user_tcp_conn.proto.tcp);
	os_printf("\r\n5");
	return true;
}

这里每次都在申请堆空间,存储tcp设置项user_tcp_conn.proto.tcp,然而却重来没有释放。

所以按道理来说应该是会堆空间溢出的,再测试一遍,确实如此。
后来我又看了很多别人的例程,这个问题也是会存在的额。

最后返回NULL了估计,那当然错啊!(谁写的例程!?!?)

三、修bug
本想着,这还不给我找到你?你没释放内存是吧?我帮你释放就好了,然而结果才是让我始料未及的


这回,一开始就宕机,以前还能撑个40分钟,现在,一开机就重启……若是大侠看到了,请告诉我是不是我的os_free用的不对,程序我注释了。
但是人家给出也这么用?

既然这样,我就直接连申请空间也不要了,直接固定空间让你用,是不是很蠢?233333

不管了,反正它现在很乖。

参考资料:
http://home.eeworld.com.cn/my/space-uid-361439-blogid-337387.html
http://blog.csdn.net/chen244798611/article/details/52762145
2c-esp8266_non_os_sdk_api_reference_cn.pdf

  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值