esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
16.08k stars 13.33k forks source link

Exception (28): epc1=0x4021276d epc2=0x00000000 epc3=0x00000000 excvaddr=0x0000544e depc=0x00000000 #7368

Closed aginbarus closed 4 years ago

aginbarus commented 4 years ago

Basic Infos

Platform

Settings in IDE

Problem Description

I'm new to programming stuff, sorry if the question is ridiculous When I received a data from another esp8266/32 device using wifi theres some error in the received data (and followed by headers like when esp reboot)

Exception (28): epc1=0x4021276d epc2=0x00000000 epc3=0x00000000 excvaddr=0x0000544e depc=0x00000000

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 3456, room 16 tail 0 chksum 0x84 csum 0x84 va5432625 ~ld

but when I sending data to other esp32, It works and read fine by the esp32. i've tried to decode the exepction

0x4020bc84: lwip_cyclic_timer at core/timeouts.c line 233 0x401008e7: free(void) at C:\Users\J\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 362 0x4020bc84: lwip_cyclic_timer at core/timeouts.c line 233 0x4020bc94: lwip_cyclic_timer at core/timeouts.c line 243 0x4020af91: memp_free at core/memp.c line 447 0x4020be2c: sys_check_timeouts at core/timeouts.c line 390 0x40100648: umm_free_core(void) at C:\Users\J\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 316 0x401008e7: free(void*) at C:\Users\J\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 362 0x40100b74: calloc(size_t, size_t) at C:\Users\J\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 820 0x40202808: __esp_yield() at C:\Users\J\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266/core_esp8266_features.h line 92 0x40202dbe: __delay(unsigned long) at C:\Users\J\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\core_esp8266_wiring.cpp line 54 0x402012f1: loop() at C:\Users\J\Documents\Arduino\Project\ESP8266\ESP8266_mtm/ESP8266_mtm.ino line 131 0x40202930: loop_wrapper() at C:\Users\J\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\core_esp8266_main.cpp line 197

MCVE Sketch


#ifdef ESP32
#include <WiFi.h>
#include <esp_now.h>
#else
#include <ESP8266WiFi.h>
#include <espnow.h>
#endif

uint8_t broadcastAddress1[] = {0x24, 0x62, 0xAB, 0xE4, 0x3F, 0x18};
uint8_t broadcastAddress2[] = {0xA4, 0xCF, 0x12, 0x88, 0x3D, 0x68};
uint8_t broadcastAddress3[] = {0x50, 0x02, 0x91, 0xC8, 0x41, 0x5C};

// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
  int id;
  String egi;
  int statusUnit;
} struct_message;

// Create a struct_message called myData
struct_message myData;

// Create a structure to hold the readings from each board
struct_message board1;
struct_message board2;
struct_message board3;

// Create an array with all the structures
struct_message boardsStruct[3] = {board1, board2, board3};

// callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  //void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, uint8_t len) {
  char macStr[18];
  Serial.print("Packet received from: ");
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  Serial.print(macStr);
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.printf(" - No Unit: %u, Received %u bytes", myData.id, len);
  // Update the structures with the new incoming data
  boardsStruct[myData.id - 1].egi = myData.egi;
  boardsStruct[myData.id - 1].statusUnit = myData.statusUnit;
  //Serial.printf(", EGI: %s ", boardsStruct[myData.id - 1].egi);
  Serial.print(", EGI: ");
  Serial.print(boardsStruct[myData.id - 1].egi);
  Serial.printf(", Status Unit: %d \n", boardsStruct[myData.id - 1].statusUnit);
  Serial.println();
}

//callback when data is sent
void OnDataSent(uint8_t *mac, uint8_t  sendStatus) {
  char macStr[18];
  Serial.print("Packet to: ");
  // Copies the sender mac address to a string
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  Serial.print(macStr);
  Serial.print(" send status:\t");
  Serial.println(sendStatus == 0 ? "Delivery Success" : "Delivery Fail");
}

void setup() {
  //Initialize Serial Monitor
  Serial.begin(115200);

  //Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  //Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  esp_now_set_self_role(ESP_NOW_ROLE_COMBO);

  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_register_recv_cb(OnDataRecv);

  esp_now_register_send_cb(OnDataSent);

  // register peer

  // esp_now_peer_info_t peerInfo;
  // peerInfo.channel = 0;
  // peerInfo.encrypt = false;
  //   register first peer
  //    memcpy(peerInfo.peer_addr, broadcastAddress1, 6);
  //    if (esp_now_add_peer(&peerInfo) != 0) {
  //      Serial.println("Failed to add peer");
  //      return;
  //    }
  //    // register second peer
  //    memcpy(peerInfo.peer_addr, broadcastAddress2, 6);
  //    if (esp_now_add_peer(&peerInfo) != 0) {
  //      Serial.println("Failed to add peer");
  //      return;
  //    }
  //    /// register third peer
  //    memcpy(peerInfo.peer_addr, broadcastAddress3, 6);
  //    if (esp_now_add_peer(&peerInfo) != 0) {
  //      Serial.println("Failed to add peer");
  //      return;
  //    }

  esp_now_add_peer(broadcastAddress1, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
  esp_now_add_peer(broadcastAddress2, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
  esp_now_add_peer(broadcastAddress3, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}

void loop() {
  myData.id = 103;
  myData.egi = "DT";
  myData.statusUnit = 4;
  esp_now_send(0, (uint8_t *) &myData, sizeof(struct_message));
  //  esp_now_send(0, (uint8_t *) &myData, sizeof(struct_message), uint8_t sendStatus);

  //  if (sendStatus == 0) {
  //    Serial.println("Sent with success");
  //  }
  //  else {
  //    Serial.println("Error sending the data");
  //  }

  delay(2000);
}

Debug Messages

Writing at 0x00030000... (100 %)
Wrote 273776 bytes (201626 compressed) at 0x00000000 in 18.1 seconds (effective 120.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
Jeroen88 commented 4 years ago

I am not familiar with esp_now_send functions, but in the OnDataRecv callback you copy the received buffer to a struct with a String inside, which is not okay. The String is a dynamic type and needs to be constructed and next set with the right data. You cannot just use memcpy. I am not sure though if this is the cause of your problems, but you need to correct this anyway.

JiriBilek commented 4 years ago

@Jeroen88 : Although it's definitely a bad practice, I think it may work here with strings up to 10 bytes. See https://github.com/esp8266/Arduino/blob/a70e834d1ea26316d28ae41b4623550d7b47ed34/cores/esp8266/WString.h#L289

Jeroen88 commented 4 years ago

Well maybe you are right, but in the trace I see several alloc functions, so your problem might have something to do with memory management.

I took a quick look at WString.h It might work if the string is in SSO mode at the sending and the receiving side and if indeed the string is small enough. I was not aware that String has several modes. But anyway, too many "mights" and "ifs" for a good program IMHO.

I think you should send a zero terminated string. If you want to receive the result in a String, have a char * pointer to the beginning and just construct it with String(pointer).

Again, I am not sure if this is the cause of your problems, but it is definitely worth a try.

devyte commented 4 years ago

@Jeroen88 's comment above about memcpy into a struct with a String is absolutely correct. String is a non-contiguous object with mem management (i. e. it has ptrs inside). You need to serialize/deserialize your messages. Closing due to user error.