esp8266 开发调试和异常排查方法
1分析方法概述
ESP8266在开发的过程中无法进行仿真,所以,为了排查问题,我们只能用别的方法,使用的方法根据实际测试情况,大概可以分为三类:
1.设备没有重启,但是运行异常,添加打印信息查证。
2.重启前报Fatal错误,根据Fatal信息查证。
3.设备重启,根据重启信息进行判断。
2详细阐述
下面详细来了解一下:
2.1添加UART打印
对于 ESP8266_NONOS_SDK,示例代码
os_printf("SDK version:%s\n", system_get_sdk_version());
对于 ESP8266_RTOS_SDK,示例代码
printf("SDK version:%s\n", system_get_sdk_version());
2.2 Fatal 查证方法
当程序崩溃时,可以根据Fatal exception 号协助问题排查调试。Fatal exception号以及描述如下:
下面以我在开发中实际遇到的一次Fatal信息为例,来说明下查证方法,我使用的是ESP8266_RTOS_SDK的工程,实际出现此信息的打印如下:
Fatal exception (28):
epc1=0x401000e3
epc2=0x00000000
epc3=0x00000000
epcvaddr=0x00011bb0
depc=0x00000000
rtn_add=0x401003d4
查证步骤如下:
(1)在当前运行固件的文件夹 (ESP8266_RTOS_SDK-master\bin\upgrade)中,找到当前运行固件对应的 “.s” 文件,注意目录可能跟你的不一样。
例如,烧录运行的是“user1.4096.new.6.bin”,则对应“user1.4096.new.6.s”文件(如果使用的是eagle.irom0text.bin,就在eagle.s中查找exception地址)。
(2)在运行固件对应的 “.s” 文件中搜索 exception 报错的 epc1 地址,如上例中是“epc1=0x401000e3”,那就在对应的.s文件中搜索“401000e3”,定位问题出现在哪个函数。搜索结果显示如下:
(3)在工程中搜索定位的函数接口,然后查看是否能明显看出问题所在。如果不能,就在出现问题的函数调用前后,添加 UART 打印信息,进一步查证来排查问题原因。
另外,注意:如果查找不到对应的地址,说明程序崩溃问题是在中断中发生或者是ROM里面的代码问题,比如:
- 4000e190 <memset>
- 4000df48 <memcpy>
- 4000dea8 <memcmp>
- 4000de84 <bzero>
- 4000e1e0 <strstr>
还有实际使用过程出现了下面的Fatal信息:
Fatal exception (9):
epc1=0x4000432b
epc2=0x00000000
epc3=0x40100644
epcvaddr=0x3ffefa02
depc=0x00000000
rtn_add=0x60000200
在.s文件中查不到地址,并且上面列出的也没有,但是既然是Fatal exception (9)的异常,那就是读/写Cache地址不对齐或者有函数野指针。很多人认为函数野指针只有在使用了指针或者申请动态内存没处理好的时候才有,其实不然,也有可能是变量,变量也是靠地址访问的,尤其是全局变量,在线程切换过程中,有可能出现野指针或者地址不对造成变量数据不对的情况,如果不是必须用全局变量,就申请成局部的。我这个问题就是在出问题的接口里面使用了全局变量,修改其他地方代码就有可能导致启动的时候出现了野指针等问题。
2.3重启原因判断
2.3.1 ROM Code判断重启原因
ESP8266每次重启,ROM code都会将此次重启原因的序号打印出来,如下图。用户可以根据该序号知道此次重启的原因。这种调试方式用于用户程序无法启动,但是需要分析此次重启原因时。
ROM code 里面打印的重启原因如下图:
2.3.2用户程序判断重启原因
用户也可以通过应用层添加程序判断此次重启的原因。这种方式判断比较全面。该方式用于发生崩溃的位置打印乱码,无法调试。
添加代码如下:
struct rst_info *rtc_info = system_get_rst_info();
os_printf("reset reason: %x\n", rtc_info->reason);
if (rtc_info->reason == REASON_WDT_RST ||
rtc_info->reason == REASON_EXCEPTION_RST ||
rtc_info->reason == REASON_SOFT_WDT_RST)
{
if (rtc_info->reason == REASON_EXCEPTION_RST)
{
os_printf("Fatal exception (%d):\n", rtc_info->exccause);
}
os_printf("epc1=0x%08x, epc2=0x%08x, epc3=0x%08x,excvaddr=0x%08x, depc=0x%08x\n",
rtc_info->epc1, rtc_info->epc2,
rtc_info->epc3, rtc_info->excvaddr,
rtc_info->depc); //此次会打印上次崩溃的地址,多用于崩溃时乱码调试。
}
关于system_get_rst_info()和相关数据结构,请参考SDK的API参考:《ESP8266 Non-OS SDK API 参考》和《ESP8266 RTOS SDK API 参考》
(链接为:https://www.espressif.com/zh-hans/support/download/documents )
通过添加判断重启原因的代码,得到的重启原因如下图:
- 分享
- 举报
-
浏览量:1387次2023-11-22 11:57:38
-
2024-07-19 15:13:16
-
2020-08-11 11:58:23
-
浏览量:2507次2024-02-28 15:36:09
-
浏览量:2048次2023-04-19 09:11:52
-
浏览量:4644次2021-03-30 14:17:51
-
浏览量:5761次2021-03-30 14:44:45
-
浏览量:2924次2020-10-30 09:43:15
-
浏览量:6917次2020-11-26 17:02:47
-
浏览量:14513次2021-01-16 15:43:02
-
浏览量:1511次2023-02-13 10:31:50
-
浏览量:5289次2021-07-09 15:20:08
-
浏览量:5199次2021-07-09 15:23:33
-
浏览量:6225次2021-07-09 15:17:28
-
浏览量:7087次2021-05-11 17:04:57
-
浏览量:8358次2021-01-20 17:16:00
-
浏览量:4927次2021-04-01 16:31:35
-
浏览量:4533次2021-05-14 09:48:13
-
浏览量:1448次2018-10-23 09:01:01
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
林
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明