ESP32 OTA更新在启动时不断崩溃
ESP32 OTA update keeps crashing on start
我正在尝试OTA更新ESP32,让它向Azure blob存储上的文件发出get请求。
由于某种未知的原因,它不允许我使用WifiClient.connect((函数,因为它总是返回0。所以现在我正在使用HTTPClient库向Azure上的blob存储发出get请求。我得到了它来提出请求,现在我正试图将它流式传输到:
Update.writeStream();
但每当我到达那个部分时,它就会崩溃,并给出以下信息:
Guru Meditation Error: Core 1 panic'ed (InstrFetchProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x00000000 PS : 0x00060630 A0 : 0x800d1a18 A1 : 0x3ffb1f30
A2 : 0x00000000 A3 : 0x3ffb1f64 A4 : 0x3ffc11b8 A5 : 0x00000000
A6 : 0x3ffbd484 A7 : 0x00000000 A8 : 0x800d3304 A9 : 0x3ffb1f10
A10 : 0x3ffb1f64 A11 : 0x3f40124c A12 : 0x00000001 A13 : 0x3ffbd44c
A14 : 0x00000000 A15 : 0x3ffc1678 SAR : 0x0000000a EXCCAUSE: 0x00000014
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
Backtrace: 0x00000000:0x3ffb1f30 0x400d1a15:0x3ffb1f50 0x400d63bb:0x3ffb1fb0 0x40088b9d:0x3ffb1fd0
这是代码:
http.begin("https://AZUREACCOUNT.blob.core.windows.net/CONTAINER/firmware.bin");
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK) {
WiFiClient * stream = http.getStreamPtr();
unsigned long timeout = millis();
while (stream->available() == 0) {
if (millis() - timeout > 5000) {
Serial.println("Client Timeout !");
stream->stop();
return;
}
}
int contentLength = http.getSize();
if (Update.begin(contentLength)) {
Serial.println("Begin OTA. This may take 2 - 5 mins to complete. Things might be quite for a while.. Patience!");
// No activity would appear on the Serial monitor
// So be patient. This may take 2 - 5mins to complete
size_t written = Update.writeStream((WiFiClient &)stream);
if (written == contentLength) {
Serial.println("Written : " + String(written) + " successfully");
} else {
Serial.println("Written only : " + String(written) + "/" + String(contentLength) + ". Retry?" );
// retry??
// execOTA();
}
if (Update.end()) {
Serial.println("OTA done!");
if (Update.isFinished()) {
Serial.println("Update successfully completed. Rebooting.");
ESP.restart();
} else {
Serial.println("Update not finished? Something went wrong!");
}
} else {
Serial.println("Error Occurred. Error #: " + String(Update.getError()));
}
}
else {
Serial.println("Not enough space");
}
我如何使此代码工作,以便设备从Azure blob存储中获取文件并更新自身?
您必须找出它崩溃的原因。如果没有工具,回溯对您没有帮助。
堆栈
请在Arduino IDE中安装此工具:
https://github.com/me-no-dev/EspExceptionDecoder
把你的错误放在里面,得到调用堆栈,看看它在哪里崩溃。可能它与Update无关,只与httpclient有关。
SSL:
您正在调用https
页面,您使用secureClient吗?您使用SSL证书吗?如果没有它,您将无法通过安全连接进行通信。
最后:VERBOSE
在启用详细模式的情况下编译。当某些事情不起作用时,得到每一条信息真的很重要。对于https来说,每一条信息都非常重要,以找出它为什么不能像预期的那样工作。
此回复可能不会直接解决您的问题(因为我使用的是ESP8266HTTPUpdateServerSecure
,而不是像您一样使用API请求(,但可能对遇到类似问题的其他人有用
最有可能的是,这是由OOM(内存不足(异常引起的,即某个库试图为变量分配内存,但失败了。TLS文件上传通常占用大量内存。根据@Andriano的建议,您应该使用EspExceptionDecoder(或其姊妹工具https://github.com/littleyoda/EspStackTraceDecoder)。
我设法通过在我的设备上实现"安全模式"来解决这个问题:
// true = allow for OTA updates in normal mode
// false = allow OTA update ONLY in safeBoot
#define OTA_AVAILABLE_IN_NORMAL_MODE false
bool safeBoot = false;
void setup()
{
//...
delay(INITIAL_BOOT_DELAY_ms);
safeBoot = (digitalRead(PIN_BUTTON) == BUTTON_PRESSED_STATE);
initializeWiFi();
if (safeBoot || OTA_AVAILABLE_IN_NORMAL_MODE) {
// initializeOTA & TLSWebServer443
}
if(!safeBoot) {
// initialize all other stuff, including HTTPWebServer80
}
}
启用后,只初始化负责OTA更新的结构
(在我的情况下,这些是ESP8266WebServerSecure
和ESP8266HTTPUpdateServerSecure
。我通过TLS页面更新固件,所有其他东西都通过未加密的HTTP工作-它更快,适合我的威胁模型(。
通过这种方式,您将增加可用堆空间(在我的情况下是十倍(,从而增加OTA无错误上传文件的机会。
- ESP32 OTA更新在启动时不断崩溃
- 如何在启动过程中崩溃时使用 gdb 调试可执行文件
- 如何重新启动崩溃的线程
- 如何在同一程序中在Qt应用程序崩溃时自动重新启动Qt应用程序
- OpenGL 应用程序在启动时立即崩溃
- 在Cuda中启动2d线程块时崩溃
- 代码编译,但是在启动后崩溃(rot13)
- 我有一个 c++ 代码,它在启动时崩溃,然后到达问题所在 main() 的执行
- Arduino崩溃并在"random points"重新启动
- Win7 / Eclipse / OpenCV / MinGW:应用程序每次启动时都会崩溃
- QTimer 在以单独的方法启动时崩溃
- GDB 在启动时崩溃(内部错误:follow_die_offset)
- 本机C++程序在使用 C++/CLI 和 C# 互操作 DLL 启动时崩溃
- 新线程启动时应用程序崩溃
- 声明SDL_Rect数据成员在启动时崩溃,找不到原因
- 程序崩溃时重新启动应用程序
- QT应用程序在启动时崩溃(c++ windows)
- 不稳定的cython扩展在使用valgrind启动时不会崩溃
- 为什么当我第二次尝试启动同一个线程时,应用程序会崩溃
- 我的win32程序是否有办法告诉它启动的子进程已经崩溃(而不仅仅是退出)?