I am getting this error in my code.
Fatal exception 9(LoadStoreAlignmentCause):
Using core version 2.4.2
Stack trace
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 declaration
struct Array8Int {
int array[8];
};
loop
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);
functions
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;
}
2 Answers 2
Fatal exception 9(LoadStoreAlignmentCause):
This is caused by you (or some code you are running) attempting to read or write a 32 bit value from memory that is not "aligned" to 32 bits. It is most often the result of trying to cast portions of a byte array (for instance a buffer received over UDP) to a 32-bit integer. The compiler is not clever enough to know that the byte array portion you are casting isn't at a 32-bit boundary and thus doesn't know to use the 8-bit load/store instructions to access the memory.
Mapping a struct
over a buffer can also have similar issues where the buffer is 8-bit aligned and the struct
contains 32-bit words.
You can combat it by forcing the alignment of any buffers which you treat in such a way with the __attribute__((aligned(4))
tag:
uint8_t __attribute__((aligned(4))) buffer[128];
You can also "pack" structures to tell the compiler "These variables are mis-aligned and should not be padded to 32-bits":
struct foo {
uint8_t bar1;
uint32_t bar2;
} __attribute__((packed));
If in doubt, though, just pull individual bytes out of buffers (or wherever) and build up your larger integers manually with bit shifting and OR operators (<<
and |
), and do the reverse for filling byte buffers.
-
yes, i am passing a struct. will attempt these solutions and get back here to ACCEPT or not. UPVOTED :)tony gil– tony gil07/26/2019 10:00:56Commented Jul 26, 2019 at 10:00
-
edited in code above, AFTER you pointed the culprit out. Good job!tony gil– tony gil07/26/2019 13:19:10Commented Jul 26, 2019 at 13:19
I had this error including on new cards it worked on one card and not on another the reason is that my eeprom was not initialized the nodemcu 8266 that was working properly, was the one I used for development. Because i was using test to write on my eeprom so the value was put in it. I did not understand what append After, I try flashing reload original setup etc... I read your answer and I pass this program (which is a stupid manual writing of my eeprom) I make it running once and after that I could load my other programs without problems
#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
-
the eeprom has a limited amount of writes, around 100Ktony gil– tony gil10/15/2021 23:19:09Commented Oct 15, 2021 at 23:19
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