NodeMCU 1.0 - Исключение 9 `Fatal exception 9(LoadStoreAlignmentCause):`
Я получаю эту ошибку в своем коде.
Фатальное исключение 9(loadstorealignmentпричина):
Использование основной версии 2.4.2
Трассировка стека
Decoding stack results
0x40213e9c: dns_gethostbyname at core/dns.c line 1472
0x40204c21: ESP8266WiFiGenericClass::hostByName(char const*, IPAddress&, unsigned int) at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp line 468
0x40205038: WiFiClient::connect(char const*, unsigned short) at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/WiFiClient.cpp line 98
0x4020306b: setPostString(int, int, Array8Int, char*) at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 516
0x40203f8a: uploadAgrigis(char const*) at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 335
0x40209080: Print::println() at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/Print.cpp line 178
0x402048e0: loop() at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 243
объявление структуры
struct Array8Int {
int array[8];
};
петля
char post[300] = "";
int pulseChange05m = rainCheck(slaveData);
int now10 = floor(unixtimeServer/10)*10;
Array8Int slaveData = slaveCheck(now()); // update slaveData array
setPostString(now10, pulseChange05m, slaveData, post);
функции
void setPostString(int unixtimeEvent, int pulseChange, Array8Int postData, char* postStr) {
bool flag = true;
float rainHour = pulseChange*0.25;
if (hour() == 10) { // 7 AM palmital
rainCount = 0;
rainCount05m = 0;
}
rainCountHour = rainCount;
int humidityBme280HourAvg = 0;
int pressureBme280HourAvg = 0;
int temperatureBme280HourAvg = 0;
int lightSensorHourAvg = 0;
int pressureBme280HourMin = 100000;
int temperatureBme280HourMin = 1000;
int temperatureBme280HourMax = -1000;
int counterLoop = counterHour;
for(int i=0;i<counterLoop;i++) {
lightSensorHourAvg += lightSensorHour[i];
pressureBme280HourAvg += pressureBme280Hour[i];
temperatureBme280HourAvg += temperatureBme280Hour[i];
temperatureBme280HourMax= max(temperatureBme280HourMax,temperatureBme280Hour[i]);
pressureBme280HourMin = min(pressureBme280HourMin,pressureBme280Hour[i]);
temperatureBme280HourMin = min(temperatureBme280HourMin,temperatureBme280Hour[i]);
humidityBme280HourAvg += humidityBme280Hour[i];
}
pressureBme280HourAvg = pressureBme280HourAvg/counterLoop;
temperatureBme280HourAvg = temperatureBme280HourAvg/counterLoop;
lightSensorHourAvg = (int)lightSensorHourAvg/counterLoop;
strcat(postStr, stationId);
strcat(postStr,"&3="); // chuva hora
strcat(postStr, dtostrf(rainHour,6,2,charDummy));
strcat(postStr,"&8=");
strcat(postStr, dtostrf(temperatureBme280HourAvg,6,2,charDummy));
strcat(postStr,"&9="); //temperature avg
strcat(postStr, dtostrf(temperatureBme280HourAvg,6,2,charDummy));
strcat(postStr,"&10="); //temperature avg
strcat(postStr, dtostrf(temperatureBme280HourMax,6,2,charDummy));
strcat(postStr,"&11="); //temperature avg
strcat(postStr, dtostrf(temperatureBme280HourMin,6,2,charDummy));
strcat(postStr,"&20=");
strcat(postStr, dtostrf(pressureBme280HourAvg,10,0,charDummy));
strcat(postStr,"&22=");
strcat(postStr, dtostrf(pressureBme280HourMin,10,0,charDummy));
strcat(postStr,"&101=");
strcat(postStr, dtostrf(lightSensorHourAvg,6,0,charDummy));
strcat(postStr,"&time=");
strcat(postStr, dtostrf(unixtimeEvent,16,0,charDummy));
strcat(postStr,"&endline=1");
strcat(postStr, "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n");
}
int rainCheck(Array8Int slaveData) {
int pulseChange = slaveData.array[0];
return pulseChange;
}
@tony gil, 👍1
Обсуждение2 ответа
Фатальное исключение 9(loadstorealignmentпричина):
Это вызвано тем, что вы (или какой-либо код, который вы запускаете) пытаетесь прочитать или записать 32-разрядное значение из памяти, которое не "выровнено" до 32 бит. Чаще всего это результат попытки привести части массива байтов (например, буфер, полученный по протоколу UDP) к 32-разрядному целому числу. Компилятор недостаточно умен, чтобы знать, что часть массива байтов, которую вы создаете, не находится на 32-разрядной границе и, следовательно, не знает, как использовать 8-разрядные инструкции загрузки/хранения для доступа к памяти.
Сопоставление структуры
с буфером также может иметь аналогичные проблемы, когда буфер выровнен по 8 битам, а структура
содержит 32-разрядные слова.
Вы можете бороться с этим, принудительно выравнивая любые буферы, которые вы обрабатываете таким образом, с помощью __атрибута__((выровненный(4))
тег:
uint8_t __attribute__((aligned(4))) buffer[128];
Вы также можете "упаковать" структуры, чтобы сообщить компилятору: "Эти переменные неправильно выровнены и не должны быть дополнены 32-битными":
struct foo {
uint8_t bar1;
uint32_t bar2;
} __attribute__((packed));
Однако, если вы сомневаетесь, просто извлеките отдельные байты из буферов (или где бы то ни было) и создайте свои большие целые числа вручную с помощью операторов сдвига битов и ИЛИ (<<
и|
) и выполните обратное для заполнения байтовых буферов.
да, я передаю структуру. попытаюсь найти эти решения и вернусь сюда, чтобы ПРИНЯТЬ их или нет. ГОЛОСОВАЛИ ЗА :), @tony gil
отредактировано в коде выше, ПОСЛЕ того как вы указали на виновника. Хорошая работа!, @tony gil
У меня была эта ошибка, в том числе на новых картах , она работала на одной карте, а не на другой .Причина в том, что мой eeprom не был инициализирован . nodemcu 8266, который работал должным образом, был тем, который я использовал для разработки. Потому что я использовал тест для записи на своем eeprom, поэтому в него было введено значение. Я не понял, что добавить после, я пытаюсь перепрошить, перезагрузить исходную настройку и т. Д... Я прочитал ваш ответ и передаю эту программу (которая является глупым ручным написанием моего eeprom). Я заставляю его работать один раз и после этого Я мог бы без проблем загружать другие свои программы
#include <EEPROM.h>
struct credential {
char WIFI_SSID [39] = " ";
char WIFI_PASSWORD [39] = " ";
char SMTP_HOST[44] = " ";
uint16_t SMTP_PORT = 465;
char AUTHOR_EMAIL[39] = " ";
char AUTHOR_PASSWORD[39] = " ";
char RECIPIENT_EMAIL[39] = " ";
uint16_t NbOfProbe = 1; //number of probe 1-to 16
char TypeOfDevice[16] = "f";// F or f fridge R freezer O hot exemple fRoFRr
char AlertMin [54] = "30";//with always a sign like-10+0+2 the sign act like a separator
char AlertMax [54] = "38";//with always a sign like-10+0+2 the sign act like a separator
uint16_t NbOfMinNormMail = 60 ;//time to wait in sec between 2 normal messages eg 14400 sec(4 hours)
uint16_t PowerOffMinWait = 1 ;
uint16_t TempOffLimitWait = 1;
char AlertPowerMsg[41] = "alerte coupure de courant "; //Message alerte coupure de courant
char AlertTempMsg[41] = "alerte temperature hors limite";
char NormalTempMsg[41] = "Tout est ok ";
char DateMsg[16] = "vide";
};
typedef struct credential settingcredent;
settingcredent parametersEeprom;
uint addr = 0;
void setup()
{
Serial.begin(115200);
delay (100);
/*
// fake data
struct {
uint val = 0;
char str[20] = "";
} data;
*/
// commit 512 bytes of ESP8266 flash (for "EEPROM" emulation)
// this step actually loads the content (512 bytes) of flash into
// a 512-byte-array cache in RAM
// EEPROM.begin(512);
// read bytes (i.e. sizeof(data) from "EEPROM"),
// in reality, reads from byte-array cache
// cast bytes into structure called data
//
showeprom ();
strncpy(parametersEeprom.WIFI_SSID,"myssid",39);
strncpy(parametersEeprom.WIFI_PASSWORD,"passmyssid",39);
strncpy(parametersEeprom.SMTP_HOST,"smtp.gmail.com",44);
parametersEeprom.SMTP_PORT=465;
strncpy(parametersEeprom.AUTHOR_EMAIL,"[email protected]",39);
strncpy(parametersEeprom.AUTHOR_PASSWORD,"iottest01",39);
strncpy(parametersEeprom.RECIPIENT_EMAIL,"[email protected]",39);
parametersEeprom.NbOfProbe = 4; //number of probe 1-to 16
strncpy(parametersEeprom.TypeOfDevice,"rffo",16);// F or f fridge R freezer O hot exemple fRoFRr
strncpy(parametersEeprom.AlertMin,"-20+0+2+23",54);//with always a sign like-10+0+2 the sign act like a separator
strncpy(parametersEeprom.AlertMax,"-15+5+7+28",54);//with always a sign like-10+0+2 the sign act like a separator
parametersEeprom.NbOfMinNormMail = 60 ;//time to wait in sec between 2 normal messages eg 14400 sec(4 hours)
parametersEeprom.PowerOffMinWait = 10 ;
parametersEeprom.TempOffLimitWait = 20;
strncpy(parametersEeprom.AlertPowerMsg,"alerte coupure de courant ",41); //Message alerte coupure de courant
strncpy(parametersEeprom.AlertTempMsg, "alerte temperature hors limite",41);
strncpy(parametersEeprom.NormalTempMsg, "Tout est ok ",41);
strncpy(parametersEeprom.DateMsg,"vide",16);
EEPROM.put(addr, parametersEeprom);
EEPROM.commit();
EEPROM.get(addr,parametersEeprom);
Serial.println("New values are: "+String(parametersEeprom.WIFI_PASSWORD)+","+String(parametersEeprom.WIFI_SSID)+","+String(parametersEeprom.SMTP_HOST));
}
void showeprom ()
{
EEPROM.begin(sizeof(parametersEeprom));
EEPROM.get(addr, parametersEeprom); //read data from array in ram and cast it into struct called parametersEeprom
Serial.println("-------------------------"); //Showing the details
Serial.print("your SSID ="); Serial.println( parametersEeprom.WIFI_SSID);
Serial.print("your password for SSID ="); Serial.println( parametersEeprom.WIFI_PASSWORD);
Serial.print("your SMTP_HOST ="); Serial.println( parametersEeprom.SMTP_HOST);
Serial.print("your SMTP_PORT ="); Serial.println( parametersEeprom.SMTP_PORT);
Serial.print("Your less secure email="); Serial.println( parametersEeprom.AUTHOR_EMAIL);
Serial.print("Your password for not secure email="); Serial.println( parametersEeprom.AUTHOR_PASSWORD);
Serial.print("Your email that must receive msg like [email protected]="); Serial.println( parametersEeprom.RECIPIENT_EMAIL);
Serial.print("The number of thermometers probe you have is ="); Serial.println( parametersEeprom.NbOfProbe);
Serial.print("Enter in order type of device (F)ridge f(R)ezzer (O)ven like RFFO="); Serial.println( parametersEeprom.TypeOfDevice);
Serial.print("Enter mintemp in order per device like(suppose RFFO) -22-1+5+180="); Serial.println( parametersEeprom.AlertMin);
Serial.print("Enter maxtemp in order per device like(suppose RFFO) -16+4+10+220="); Serial.println( parametersEeprom.AlertMax);
Serial.print("Number of sec between 2 normal mails like(4hours) 240 ="); Serial.println( parametersEeprom.NbOfMinNormMail);
Serial.print("Number of sec to wait before sending message Power off like 5 ="); Serial.println( parametersEeprom.PowerOffMinWait);
Serial.print("Number of sec to wait before sending message warning temp like 5 ="); Serial.println( parametersEeprom.TempOffLimitWait);
Serial.print("Message power down(30 char) like WARNING POWER OFF GRID="); Serial.println( parametersEeprom.AlertPowerMsg);
Serial.print("Message temperature off min/max(30 char) like WARNING TEMPERATURE ABNORMAL="); Serial.println( parametersEeprom.AlertTempMsg);
Serial.print("Message report state of all fridges freezer Oven like Everything is OK in the kitchen ="); Serial.println( parametersEeprom.NormalTempMsg);
Serial.print("Enter date of the modif parameters like 08/23/21-18:25="); Serial.println( parametersEeprom.DateMsg);
}
void loop()
{
delay(10000);
showeprom ();
}
~
~
I hope that this experiment can be usefull
I cannot explain why it work
eeprom имеет ограниченное количество записей, около 100 тыс., @tony gil
- NodeMCU - Vin контакт как выход 5V?
- Как заставить 5-вольтовое реле работать с NodeMCU
- ESP8266 не подключается к Wi-Fi
- Разве в узле MCU v3 (LoLin) нет встроенного светодиода?
- Разница между этими двумя платами NodeMCU?
- NodeMCU - использовать кнопку flash в качестве входного сигнала в loop()
- Как определить размер Flash?
- Использование датчика рН 5В с узлом 3,3В
ваш код и базовая версия esp8266, пожалуйста, @Juraj
2000 строк? может быть, сузить круг поисков... я был бы признателен за некоторую помощь со стеком -> указывает ли он на строку 243 или 1472, как выполненную в последний раз? tks @Juraj, @tony gil
по крайней мере, код вокруг
setPostString(int, int, Array8Int, char*) в /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.строка ино 516
, @JurajЛесканна, ты спасаешь мне жизнь! Это работает!, @Joel Sandberg