html - Guru Meditation 错误:ESP32 上的 Core 1 Panic'ed (Load Prohibited)
问题描述
所以我试图创建一个网络服务器,用 ESP32 点亮多个 LED。当一个按钮被按下时,服务器会发送一个 GET 请求。以前,HTML 页面上只有一个 LED 和一个按钮。这段代码就是这样,只是有更多的按钮和变量。但是,当我将它上传到 ESP32 并打开串行窗口时,我得到了这个:
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO,clock div: 1 load:0x3fff0018,len:4 load:0x3fff001c,len:1216 ho 0 tail 12 room 4 load:0x40078000,len:10944 load:0x40080400,len:6388 entry 0x400806b4 Guru Meditation Error: Core 1 panic'ed (LoadProhibited)。异常未处理。Core 1 register dump: PC : 0x40081041 PS : 0x00060330 A0 : 0x800d1222 A1 : 0x3ffb1f40
A2 : 0x00000004 A3 : 0x00000002 A4 : 0x0800001c A5 : 0x00000003
A6 : 0x00000003 A7 : 0x00000000 A8 : 0x3f401e08 A9 : 0xffffffff
A10 : 0xff4e0000 A11 : 0x00000048 A12 : 0x08000000 A13:0x00000003
A14 : 0xffffffff A15 : 0x00000000 SAR : 0x0000001a EXCCAUSE: 0x0000001c
EXCVADDR: 0xff4e0000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
ELF file SHA256: 0000000000000000 Backtrace: 0x40081041:0x3ffb1f40 0x400d121f:0x3ffb1f60 0x400dc8f6:0x3ffb1fb0 0x40089a52:0x3ffb1fd0 Rebooting...
我不知道这意味着什么或我做错了什么。我试过了:
1 - 最小化变量(将无符号,常量等添加到变量的前缀)
2 - 将变量放入本地函数的范围
有人可以帮忙吗?如果您这样做,将不胜感激。(我对 Arduino 编程完全陌生,所以我不知道该怎么做)。这是代码:
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoOTA.h>
// Replace with your network credentials
const char* ssid = "SSID_HERE";
const char* password = "PASSWORD_HERE";
const unsigned int outputfw = 2;
const unsigned int outputlt = 4;
const unsigned int outputrt = 7;
const unsigned int outputbw = 6;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 3.0rem;}
p {font-size: 3.0rem;}
body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
.switch {position: relative; display: inline-block; width: 120px; height: 68px}
.switch input {display: none}
.slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 34px}
.slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px}
input:checked+.slider {background-color: #2196F3}
input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
</style>
</head>
<body>
<h2>ESP Web Server</h2>
%BUTTONPLACEHOLDER%
<script>function toggleCheckbox(state, dir) {
console.log("Mouse is ")
console.log(state)
var xhr = new XMLHttpRequest();
if(state){ xhr.open("GET", "/update?" + dir + "=" + state, true); }
else { xhr.open("GET", "/update?" + dir + "=" + state, true); }
xhr.send();
}
document.getElementById("fw").addEventListener("mousedown", function(event) {
toggleCheckbox(true, "fw");
console.log("mouse down.f");
}, false);
document.getElementById("fw").addEventListener("mouseup", function(event) {
toggleCheckbox(false, "fw");
console.log("mouse up.f")
}, false);
document.getElementById("bw").addEventListener("mousedown", function(event) {
toggleCheckbox(true, "bw");
console.log("mouse down.b");
}, false);
document.getElementById("bw").addEventListener("mouseup", function(event) {
toggleCheckbox(false, "bw");
console.log("mouse up.b")
}, false);
document.getElementById("lt").addEventListener("mousedown", function(event) {
toggleCheckbox(true, "lt");
console.log("mouse down.l");
}, false);
document.getElementById("lt").addEventListener("mouseup", function(event) {
toggleCheckbox(false, "lt");
console.log("mouse up.l")
}, false);
document.getElementById("rt").addEventListener("mousedown", function(event) {
toggleCheckbox(true, "rt");
console.log("mouse down.r");
}, false);
document.getElementById("rt").addEventListener("mouseup", function(event) {
toggleCheckbox(false, "rt");
console.log("mouse up.r")
}, false);
</script>
</body>
</html>
)rawliteral";
// Replaces placeholder with button section in your web page
String processor(const String& var){
//Serial.println(var);
if(var == "BUTTONPLACEHOLDER"){
String buttons;
String outputStateValue = outputState();
//buttons+= "<h4>Output - GPIO 2 - State <span id=\"outputState\"></span></h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"output\" " + outputStateValue + "><span class=\"slider\"></span></label>";
buttons = "<h4>output button gpio5 - <span id=\"outputState\"></span></h4><button id=\"fw\">forward</button><br><button id=\"lt\">left</button><button id=\"bw\">backward</button><button id=\"rt\">right</button>";
return buttons;
}
return String();
}
String outputState(){
if(digitalRead(outputfw)){
return "checked";
}
else {
return "";
}
return "";
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
pinMode(outputfw, OUTPUT);
pinMode(outputbw, OUTPUT);
pinMode(outputlt, OUTPUT);
pinMode(outputrt, OUTPUT);
digitalWrite(outputfw, LOW);
digitalWrite(outputbw, LOW);
digitalWrite(outputlt, LOW);
digitalWrite(outputrt, LOW);
// pinMode(buttonPin, INPUT);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
ArduinoOTA.begin();
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/update?<direction>=<inputMessage>
server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
int ledState1 = LOW; // the current state of the output pin
int ledState2 = LOW;
int ledState3 = LOW;
int ledState4 = LOW;
String inputMessage;
String inputParam;
const char PARAM_INPUT_1[] = "fw";
const char PARAM_INPUT_2[] = "bw";
const char PARAM_INPUT_3[] = "lt";
const char PARAM_INPUT_4[] = "rt";
// GET input1 value on <ESP_IP>/update?state=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
digitalWrite(outputfw, inputMessage.toInt());
ledState1 = !ledState1;
}
else if (request->hasParam(PARAM_INPUT_2)) {
inputMessage = request->getParam(PARAM_INPUT_2)->value();
inputParam = PARAM_INPUT_2;
digitalWrite(outputbw, inputMessage.toInt());
ledState2 = !ledState2;
}
else if (request->hasParam(PARAM_INPUT_3)) {
inputMessage = request->getParam(PARAM_INPUT_3)->value();
inputParam = PARAM_INPUT_3;
digitalWrite(outputlt, inputMessage.toInt());
ledState3 = !ledState3;
}
if (request->hasParam(PARAM_INPUT_4)) {
inputMessage = request->getParam(PARAM_INPUT_4)->value();
inputParam = PARAM_INPUT_4;
digitalWrite(outputrt, inputMessage.toInt());
ledState4 = !ledState4;
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
// Send a GET request to <ESP_IP>/state
server.on("/state", HTTP_GET, [] (AsyncWebServerRequest *request) {
request->send(200, "text/plain", String(digitalRead(outputfw)).c_str());
});
// Start server
server.begin();
}
void loop() {
ArduinoOTA.handle();
delay(2);}
解决方案
您正在使用连接到 ESP32 闪存芯片的 GPIO 引脚。当您重新编程时,pinMode()
您会干扰 ESP32 读取和写入闪存的能力并且它会崩溃。
const unsigned int outputfw = 2;
const unsigned int outputlt = 4;
const unsigned int outputrt = 7;
const unsigned int outputbw = 6;
引脚 6 和 7 连接到 SPI 闪存芯片。在应用程序中使用它们通常不安全。它们通常也不会在 ESP32 分线板上表达出来。
尝试使用 13 和 14 而不是 6 和 7 之类的安全引脚来重建固件,您会发现它不会像以前那样崩溃。
也许您将分线板的引脚编号与 GPIO 引脚编号混淆了?您需要参考您正在使用的电路板的引脚排列来找到正确的 GPIO 引脚。ESP32 Arduino 代码将引用 GPIO 引脚号,而不是分线板引脚号。
关于如何使用 ESP32 GPIO 引脚以及哪些引脚对于哪些用途是安全的,这里有一个非常有用的参考。
推荐阅读
- javascript - 从 showModalDialog 返回数据
- swift - 其他文件中的 Swift VSCode 类无法识别
- javascript - 在 MongoDB / mongoose 中是否可以替代大型 $or 查询?
- angular - 选择框,其中月份默认值为 Angular 中的当前月份
- python - 如何有效地将值附加到 Python 中的空列表?
- swagger - Swagger:如何指定关联数组?
- python - `python3` 是否总是与 Python 3 一起安装?
- c# - 无法将流行的命名空间引用添加到 C# .DLL 类库
- oracle - PL/SQL case 语句中的意外错误
- javascript - 自定义边缘样式 - cytoscape.js