Паника ядра в esp32
- Войдите на сайт для отправки комментариев
Вс, 21/08/2022 - 23:54
Всем добрый вечер. Помогите пожалуйста с кодом. Я полный новичок в программирование, поэтому простите за код.
#include <GyverPortal.h>
#include <FS.h>
#include <SPIFFS.h>
#include <ArduinoJson.h>
#define FORMAT_SPIFFS_IF_FAILED true
struct config_wifi_struct {
char* ssid;
char* pass;
bool DHCP;
char* ip;
char* gt;
char* mac;
char* dns;
};
config_wifi_struct str;
//===================================================================
//spiffs functions
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
Serial.printf("Listing directory: %s\r\n", dirname);
File root = fs.open(dirname);
if(!root){
Serial.println("- failed to open directory");
return;
}
if(!root.isDirectory()){
Serial.println(" - not a directory");
return;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory()){
Serial.print(" DIR : ");
Serial.println(file.name());
if(levels){
listDir(fs, file.name(), levels -1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print("\tSIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
String readFile(fs::FS &fs, const char * path){
Serial.printf("Reading file: %s\r\n", path);
String return_err = "error";
File file = fs.open(path);
if(!file || file.isDirectory()){
Serial.println("- failed to open file for reading");
return return_err;
}
String msg_string;
while(file.available()){
//Serial.write(file.read());
msg_string += char(file.read());
}
file.close();
return msg_string;
}
void writeFile(fs::FS &fs, const char * path, String message){
Serial.printf("Writing file: %s\r\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("- failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("- file written");
} else {
Serial.println("- write failed");
}
file.close();
}
void appendFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Appending to file: %s\r\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file){
Serial.println("- failed to open file for appending");
return;
}
if(file.print(message)){
Serial.println("- message appended");
} else {
Serial.println("- append failed");
}
file.close();
}
//========================================================================
//gyver portal functions
void build_login() {
BUILD_BEGIN();
GP.THEME(GP_DARK);
GP.FORM_BEGIN("/login");
GP.TEXT("lg", "Login");
GP.BREAK();
GP.TEXT("ps", "Password", str.pass);
GP.BREAK();
GP.LABEL("DHCP: ");
GP.BREAK();
GP.CHECK("DHCP", str.DHCP);
GP.BREAK();
GP.TEXT("ip", "ip", str.ip);
GP.BREAK();
GP.TEXT("gt", "gt", str.gt);
GP.BREAK();
GP.TEXT("mac", "mac", str.mac);
GP.BREAK();
GP.TEXT("dns", "dns", str.dns);
GP.BREAK();
GP.SUBMIT("Submit");
GP.FORM_END();
BUILD_END();
}
void action_login(GyverPortal& p) {
if (p.form("/login")) {
p.copyStr("lg", str.ssid);
p.copyStr("ps", str.pass);
str.DHCP = p.getCheck("DHCP");
p.copyStr("ip", str.ip);
p.copyStr("gt", str.gt);
p.copyStr("mac", str.mac);
p.copyStr("dns", str.dns);
WiFi.softAPdisconnect();
load_config_wifi();
}
}
void loginPortal() {
Serial.println("Portal start");
// запускаем точку доступа
WiFi.mode(WIFI_AP);
WiFi.softAP("WiFi Config");
// запускаем портал
Serial.println("Запуск портала");
GyverPortal portal;
portal.attachBuild(build_login);
Serial.println("Запуск build_login");
portal.start(WIFI_AP);
Serial.println("Запуск WIFI_AP");
portal.attach(action_login);
Serial.println("Запуск action_login");
// работа портала
while (portal.tick());
}
bool read_config_wifi(String msg_json_wifi_config){
config_wifi_struct str;
StaticJsonDocument<300> doc;
DeserializationError error = deserializeJson(doc, msg_json_wifi_config);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return false;
}
str.ssid = strdup(doc["ssid"]);
str.pass = strdup(doc["pass"]);
str.DHCP = strdup(doc["DHCP"]) == "1";
str.gt = strdup(doc["gt"]);
str.mac = strdup(doc["mac"]);
str.dns = strdup(doc["dns"]);
str.ip = strdup(doc["ip"]);
Serial.println(str.ssid);
Serial.println(str.pass);
Serial.println(str.DHCP);
Serial.println(str.ip);
Serial.println(str.gt);
Serial.println(str.mac);
Serial.println(str.dns);
return true;
}
bool load_config_wifi(){
StaticJsonDocument<300> doc;
doc["ssid"] = str.ssid;
doc["pass"] = str.pass;
doc["DHCP"] = str.DHCP;
doc["ip"] = str.ip;
doc["gt"] = str.gt;
doc["mac"] = str.mac;
doc["dns"] = str.dns;
String msg_return;
serializeJson(doc, msg_return);
Serial.print(msg_return);
writeFile(SPIFFS, "/config_wifi.json", msg_return);
return true;
}
//========================================================================
//wifi functions
bool DHCP_switch (){
if(!str.DHCP){
IPAddress local_IP(ipaddr_addr(str.ip));
IPAddress gateway(ipaddr_addr(str.gt));
IPAddress subnet(ipaddr_addr(str.mac));
IPAddress primaryDNS(ipaddr_addr(str.dns));
if (WiFi.config(local_IP, gateway, subnet, primaryDNS) == false) {
Serial.println("Configuration failed.");
return false;
}
}
return true;
}
void wifi_connect(){
Serial.print("Connect to: ");
Serial.println(str.ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(str.ssid, str.pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Connected! Local IP: ");
Serial.println(WiFi.localIP());
Serial.print("DHCP: ");
Serial.println(str.DHCP);
}
//========================================================================
//arduino functions
void setup() {
Serial.begin(115200);
Serial.println();
if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)){
Serial.println("SPIFFS Mount Failed");
}
pinMode(27, INPUT_PULLUP);
delay(500);
Serial.println(read_config_wifi(readFile(SPIFFS, "/config_wifi.json")));
delay(500);
if (!digitalRead(27)){
loginPortal();
}
DHCP_switch();
wifi_connect();
}
void loop() {
}
Думаю, тут все дело в том, что я плохо использую переменные и функции для перезаписи массивов. Заранее огромное спасибо.
А стектрейс я сам должен выяснить?
Извините, не совсем понял что вам нужно
GyverPortal?
Ну, это пусть пейсатель библиотеки разбирается.
Думаю, тут все дело в том, что я ...
забыл написать в чём именно состоит моя проблема и выложить сообщения об ошибках.
понял
сейчас всё напишу
bool read_config_wifi(String msg_json_wifi_config){ config_wifi_struct str; StaticJsonDocument<300> doc; DeserializationError error = deserializeJson(doc, msg_json_wifi_config); if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return false; } str.ssid = strdup(doc["ssid"]); str.pass = strdup(doc["pass"]); str.DHCP = strdup(doc["DHCP"]) == "1"; str.gt = strdup(doc["gt"]); str.mac = strdup(doc["mac"]); str.dns = strdup(doc["dns"]); str.ip = strdup(doc["ip"]); Serial.println(str.ssid); Serial.println(str.pass); Serial.println(str.DHCP); Serial.println(str.ip); Serial.println(str.gt); Serial.println(str.mac); Serial.println(str.dns); return true; }Думаю, все дело в этой функции. Без нее, код работает исправно. Остальные функции были взяты с примеров к библиотекам.
Ошибки в логах при запуске этой функции:
ets Jun 8 2016 00:22:57
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:1044
load:0x40078000,len:10124
load:0x40080400,len:5856
entry 0x400806a8
Reading file: /config_wifi.json
111
111
0
255.255.255.255
255.255.255.255
255.255.255.255
255.255.255.255
1
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x401350f3 PS : 0x00060330 A0 : 0x80135358 A1 : 0x3ffb1ea0
A2 : 0x00000000 A3 : 0x3ffb1edc A4 : 0x00000001 A5 : 0x00000001
A6 : 0x00060320 A7 : 0x00000000 A8 : 0x80085450 A9 : 0x3ffb1ef0
A10 : 0x3ff000e0 A11 : 0x00000001 A12 : 0x3ffbe958 A13 : 0x0000ff00
A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x0000001b EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
ELF file SHA256: 0000000000000000
Backtrace: 0x401350f3:0x3ffb1ea0 0x40135355:0x3ffb1ed0 0x400d1b33:0x3ffb1f00 0x400d368f:0x3ffb1f70 0x400dc6ca:0x3ffb1fb0 0x40089966:0x3ffb1fd0
В строка №№12-18 производится запрос памяти (strdup вызывает malloc).
Вопрос: кто, где, когда и при каких обстоятельствах эту память освобождает?
Если никто и никогда, то память со временем переполняется и "приплыли", тем более, что в программе даже не проверяется удачно отработала strdup или её памяти не хватило.
Спасибо, так и думал
Только я не знаю как сделать то, что вы написали
Если не трудно, пришлите пожалуйста какой нибудь пример
https://bit.ly/3QEZ16s
bool read_config_wifi(String msg_json_wifi_config){ StaticJsonDocument<300> doc; DeserializationError error = deserializeJson(doc, msg_json_wifi_config); if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return false; } str.ssid = strdup(doc["ssid"]); str.pass = strdup(doc["pass"]); str.DHCP = strdup(doc["DHCP"]); str.gt = strdup(doc["gt"]); str.mac = strdup(doc["mac"]); str.dns = strdup(doc["dns"]); str.ip = strdup(doc["ip"]); Serial.println(str.ssid); Serial.println(str.pass); Serial.println(str.DHCP); Serial.println(str.ip); Serial.println(str.gt); Serial.println(str.mac); Serial.println(str.dns); free (str.ssid); free (str.pass); free (str.DHCP); free (str.gt); free (str.mac); free (str.dns); free (str.ip); return true; }Стало лучше работать. При первом запуске этой функции, все нормально, но при повторном опять ошибка ядра.
Раньше str был описан в этой функции. А сейчас ...
Я же его за функцию вытащил
или лучше обратно его засунуть ?
Я же его за функцию вытащил
А мне это, простите откуда, знать? Что Вы вытащили, куда, зачем и как именно? Вы же мне только огрызок кода выложили, весь не доверяете.
К тому же, по-прежнему
Вы до этого не дочитали? Или решили проигнорировать?
Весь код я выложил в первом вопросе
bool read_config_wifi(String msg_json_wifi_config){ StaticJsonDocument<300> doc; DeserializationError error = deserializeJson(doc, msg_json_wifi_config); if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return false; } str.ssid = strdup(doc["ssid"]); free (str.ssid); str.pass = strdup(doc["pass"]); free (str.pass); str.DHCP = strdup(doc["DHCP"]); free (str.DHCP); str.ip = strdup(doc["ip"]); free (str.ip); str.gt = strdup(doc["gt"]); free (str.gt); str.mac = strdup(doc["mac"]); free (str.mac); str.dns = strdup(doc["dns"]); free (str.dns); Serial.println(str.ssid); Serial.println(str.pass); Serial.println(str.DHCP); Serial.println(str.ip); Serial.println(str.gt); Serial.println(str.mac); Serial.println(str.dns); return true; }Поменял код. Теперь не вылезает ошибка ядра, но появилась другая проблема. Функция не корректно записывает данные в структуру.
Лог:
16:42:42.574 -> ets Jun 8 2016 00:22:57
16:42:42.574 ->
16:42:42.574 -> rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
16:42:42.574 -> configsip: 0, SPIWP:0xee
16:42:42.574 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
16:42:42.574 -> mode:DIO, clock div:1
16:42:42.574 -> load:0x3fff0018,len:4
16:42:42.574 -> load:0x3fff001c,len:1044
16:42:42.574 -> load:0x40078000,len:10124
16:42:42.574 -> load:0x40080400,len:5856
16:42:42.574 -> entry 0x400806a8
16:42:42.901 ->
16:42:43.508 -> Reading file: /config_wifi.json
16:42:43.508 -> <⸮⸮?xV⸮⸮
16:42:43.508 -> <⸮⸮?xV⸮⸮
16:42:43.508 -> <⸮⸮?xV⸮⸮
16:42:43.508 ->
16:42:43.508 ->
16:42:43.508 ->
16:42:43.508 ->
16:42:43.508 -> 1
16:42:43.973 -> Portal start
16:42:44.113 -> Запуск портала
16:42:44.113 -> Запуск build_login
16:42:44.113 -> Запуск WIFI_AP
16:42:44.113 -> Запуск action_login
16:43:19.375 -> {"ssid":" ","pass":" ","DHCP":" ","ip":"Ԩ⸮?xV⸮⸮","gt":"Ԩ⸮?xV⸮⸮","mac":"Ԩ⸮?xV⸮⸮","dns":"Ԩ⸮?xV⸮⸮"}Writing file: /config_wifi.json
16:43:19.375 -> - file written
в программе даже не проверяется удачно отработала strdup или её памяти не хватило.
Насчет этого я помню. Но в интернета не нашел, как правильно это сделать. А реализовать самому не получается. Если есть пример, скиньте пожалуйста
Возвращаемое значение
Указатель на копию строки. Если выделение памяти закончилось неудачей, то создания копии не происходит и *функция возвращает NULL*.
Понял, спасибо. Но мне обязательно нужно выполнить создание копии. Как можно это реализовать, что бы 100% происходило создание копии.
Или же можно обойтись без функции strdup? Просто, я ее использую из-за того, что мне нужно преобразовать значение из const char* в char*.
Все зависит от того, где использовать поля данной структуры...
Мне нужно передать значение в структуру. JSON функция отдает мне их в const char*, а мне нужно хранить их в структуре с переменными char.
То, что нужно - видно из кода. А вот какова должна быть область видимости - неочевидно. Это же основополагающий вопрос.
Нужно прочитать учебник по языку и написать нормальную RAII-структуру вместо этого мусора.