微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ESP8266 闪存必须在每次崩溃后完全擦除才能再次使用

如何解决ESP8266 闪存必须在每次崩溃后完全擦除才能再次使用

我有一个 ESP8266 D1 mini,我在上面编写了一个程序,用于在小型 OLED 显示屏上获取显示加密货币价格。它使用库 ESP8266WiFi、ESP8266HTTPClient、EEPROM、pgmspace、Wire、ArduinoJson、oled 和 ESPAsyncWebServer。用户配置信息存储在 EEPROM 中。

某处存在问题,可能会在连续运行 30 或 40 小时后导致程序偶尔在随机时间崩溃。发生这种情况时,处理器重新启动,开始运行 setup() 函数,然后给出异常 (3)。这种复位/异常然后一遍又一遍地发生,直到设备断电。如果设备恢复供电,相同的重置/异常序列将无限期恢复。

将程序重新加载到闪存中并不能解决问题。即使是简单的 Blink 草图也不会运行。事实上,我发现让设备再次可用的唯一方法是使用esptool完全擦除闪存,然后重新加载程序。这当然也会清除所有用户配置信息。

对重复异常的分析表明这是错误

#! /usr/env python

import math

matrix = []
for i in range(9):
    matrix.append([])
    for x in range(9):
        matrix[i].append(i+x*2)

mode = {}
avg = 0
stddev = 0
count = 0
for i in range(len(matrix)):
    for x in range(len(matrix[i])):
        avg+=matrix[i][x]
        if matrix[i][x] in mode:
            mode[matrix[i][x]]+=1
        else:
            mode[matrix[i][x]]=1
        count+=1
maxcount = max(mode,key=mode.get)
avg /= count
# if you calculate the count from the dimensions...
# avg /= len(matrix)*len(matrix[0])
print(f'Mode = {maxcount} with {mode[maxcount]} occurrences')
print(f'Avg = {avg}')

# get the std dev
for i in range(len(matrix)):
    for x in range(len(matrix[i])):
        stddev += (matrix[i][x]-avg) ** 2
stddev /= count-1
print(f'Stddev = {math.sqrt(stddev)}')

到目前为止这种情况已经发生了几十次,我有很多打印语句显示了程序中不同点的堆栈和堆大小,但似乎没有一个提供任何关于崩溃原因的线索。展开堆栈也没有意义,因为异常解码器会显示许多程序位置的问号。接近堆栈底部的是我的代码中触发整个崩溃的调用 - 一个 Print::println(__FlashStringHelper const)* 语句,它可以完美运行,直到发生崩溃。有趣的是,我的程序在崩溃分析中显示的位置没有 println 语句。

我想,通过足够的努力,我可以找出导致闪存内容损坏的原始崩溃的原因。我无法理解的是它如何如此糟糕,以至于我什至无法通过重新加载程序来修复它 - 必须先擦除整个闪存,然后才能让设备再次工作。我曾尝试更换设备,认为可能是硬件问题,但新设备也因此失败。我在这里错过了什么?

解决方法

问题

这可能是堆碎片造成的,其中每次改变专门针对 String 的变量大小时都会创建空洞,直到它达到零可用内存: enter image description here


观察

您可以使用以下方法监控 FreeHeap:

 Serial.println(ESP.getFreeHeap());

在循环中运行它以观察可用内存。


解决方案

在 loop() 函数中定期调用 tcpCleanup。

// do this before including other stuff like wificlient.h
#include "lwip/tcp_impl.h"

void tcpCleanup()
{
  while(tcp_tw_pcbs!=NULL)
  {
    tcp_abort(tcp_tw_pcbs);
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。