espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.68k stars 7.42k forks source link

compler extensa32 error nested function, or esp32 have a internal hardware bug ? #9965

Open Red-Owl opened 4 months ago

Red-Owl commented 4 months ago

Board

ESP32 wt32-s3-wrover (wt32sc01 plus)

Device Description

wt32sc01 plus

Hardware Configuration

wt32sc01 plus

Version

v3.0.1

IDE Name

Platformio

Operating System

win11

Flash frequency

40mhz

PSRAM enabled

yes

Upload speed

115200

Description

nested funcion have a limit ?

Sketch

String get_esp32_chip_info(void){ //1983216
  uint32_t chipId = 0;
  for (int i = 0; i < 17; i = i + 8) {
    chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
  }
  String returnText = "[";
  returnText += "{";      
  returnText += "\"model\":\"" + String(ESP.getChipModel()) + "\",";
  returnText += "\"rev\":\"" + String(ESP.getChipRevision()) + "\",";
  returnText += "\"flash\":\"" + String(ESP.getFlashChipSize()) + "\",";
  returnText += "\"psram\":\"" + String(ESP.getPsramSize()) + "\",";
  returnText += "\"firmwaresize\":\"" + String(ESP.getSketchSize()) + "\",";
  returnText += "\"freespace\":\"" + String(ESP.getFreeSketchSpace()) + "\",";
  returnText += "\"core\":\"" + String(ESP.getChipCores()) + "\",";
  returnText += "\"frequency\":\"" + String(ESP.getCpuFreqMHz()) + "\",";
  returnText += "\"chipid\":\"" + String(chipId) + "\"";
  returnText += "}";
  returnText += "]";
  return returnText;
}

String command_execute(String com, String value){
    String dataca = "[";
    dataca += "{";      
    dataca += "\"command\":\"" + String(com) + "\",";
    dataca += "\"option\":\"" + String(value) + "\",";

if(com=="USBDATA"){
        if(value=="T"){
          serial_data_mode = true;
          dataca += "\"exec\":\"true\","; 
        }else if(value=="F"){
          serial_data_mode = false;
          dataca += "\"exec\":\"true\",";  
        }else{
          dataca += "\"info\":\"invalid\",";  
        }
          serial_data_out();
        }
        else
if(com=="RES"){
        // gatto_enable_reserverd(value.c_str());
        }
        else
if(com=="SESSION"){
        dataca += "\"exec\":\"true\","; 
        dataca += "\"info\":\""+ ENABLE_STRING +"\","; 
        }
        else
if(com=="MD5"){
        /* char *md5str = hashMD5.md5(value.c_str());
        USBCOM.write(md5str); */
        dataca += "\"exec\":\"true\","; 
        dataca += "\"info\":\""+ String("__TODO__") + "\","; 
        }
        else
if(com=="setserial"){
        String ch = value.c_str();
        int str_len = ch.length() + 1; 
        char char_array[str_len];
        ch.toCharArray(char_array, str_len);
        if(POLLO_ENABLE_MOD==true){
          gatto_set_serial(ch);
        //gatto_485_send(char_array);
        }
        }
        else 
if(com=="SERIAL"){
        dataca += "\"exec\":\"true\","; 
        dataca += "\"info\":\""+ String(FIRMWARE_SERIAL) +"\","; 
        }
        else 
if(com=="MODEL"){
        dataca += "\"exec\":\"true\","; 
        dataca += "\"info\":\""+ String(FIRMWARE_SERIAL) +"\","; 
        }
        else 
if(com=="ABOUT"){
        dataca += "\"exec\":\"true\","; 
        dataca += "\"info\":"+ String(get_model_data()) + ","; 
        }
        else 
if(com=="DATE"){
        long ooz = atoi(value.c_str());
        if(ooz>0){
          update_ds1307_from_rtc(ooz);
          dataca += "\"exec\":\"true\","; 
        }else{
          dataca += "\"exec\":\"false\","; 
        }
        dataca += "\"info\":"+ String(json_get_date()) +",";      
        }
        else 
if(com=="INFO"){
        dataca += "\"exec\":\"true\","; 
        dataca += "\"info\":"+ String(get_esp32_chip_info()) +",";     //<--------|<-CORRUPTED------------    
        }
        else 
if(com=="HEAT"){
        dataca += "\"exec\":\"true\","; 
        dataca += "\"info\":"+ String(get_esp32_chip_temperature()) + ",";       
        }
        else 
if(com=="TABS"){
        uint16_t iii = atoi(value.c_str());
        uint16_t gg = lv_tabview_get_tab_num(TABVIEW);
        if(gg>=iii){
            lv_tabview_set_act(TABVIEW, iii, LV_ANIM_OFF);
            dataca += "\"exec\":\"true\","; 
          }else{
            dataca += "\"exec\":\"false\","; 
          }
        dataca += "\"info\":\""+ String(gg) +"\",";          
        }
        else  
if(com=="duty"){
        dataca += "\"exec\":\"true\","; 
        pwm_set_duty(atoi(value.c_str()));
        dataca += "\"info\":\""+ String(pwm_get_duty()) +"\",";    
        }else 
if(com=="frequency"){
        dataca += "\"exec\":\"true\","; 
        pwm_set_frequency(atoi(value.c_str()));
        dataca += "\"info\":\""+ String(pwm_get_freq()) +"\",";    
        }

      /*if(com=="E0"){
        POLLO_ENABLE_MOD = true;
        gatto_nvs();
      }
      else      
      if(com=="E1"){
        POLLO_ENABLE_MOD = false;
        gatto_nvs();
      }
      else
      if(com=="E3"){
        nvs_.begin("hardware",RW_MODE); 
        String str = nvs_.getString("model"); 
        USBCOM.write(str.c_str());
        nvs_.putString("model","CANE55nnnnnnnnnnnn"); 
        String str2 = nvs_.getString("model"); 
        USBCOM.write(str2.c_str());
      }
      else
      if(com=="t1"){
        String ass = gatto_get_serial();
        USBCOM.write(ass.c_str());  
      }else     
      if(com=="t2"){
        String ass = nvs_.getString("serial");
        USBCOM.write(ass.c_str());  
      }else     
      if(com=="t3"){
        String ass2 = String(touch);
        USBCOM.write(ass2.c_str());  
      }else     
      if(com=="t4"){
        String ass4 = String(CPS[1]);
        USBCOM.write(ass4.c_str());  
      }

      /* if(com=="USBTO485"){
        if(value=="T"){
          usb_485_data_mode = true;
        }else if(value=="F"){
          usb_485_data_mode = false;
        }else{
          USBCOM.write("Invalid 485 Option");  
        }
      }else 
      if(com=="LIST"){
        USBCOM.write("display:");
        // USBCOM.write(US_LIST);
        USBCOM.write("\nSERIAL:");
        String el = "ABOUT,USBDATA,RES,MD5,INFO,HEAT,SERIAL,MODEL,SESSION";
        if(POLLO_ENABLE_MOD == true){
          el +="nvsclear,setserial,setmodel";
        }
        USBCOM.write(el.c_str());
      */

      dataca += "\"rnd\":\"" + String(ENABLE_STRING) + "\"";
      dataca += "}";
      dataca += "]";
      if(dataca.length()>65535){
        dataca = "[";
        dataca += "{";      
        dataca += "\"command\":\"" + String(com) + "\",";
        dataca += "\"option\":\"" + String(value) + "\",";
        dataca += "\"exec\":\"Buffer ovwerflow!\",";
        dataca += "}";
        dataca += "]";
      }
  return dataca;
}

void usb_as_serial_read(){
    String data = USBCOM.readString();
    data.trim();  
    String com;
    String value;
    for (int i = 0; i <= data.length(); i++) {
      if(i == data.length()){
          com = data;
          value = "";
          break;
      }else if(data.charAt(i) == 61) {
          com = data.substring(0, i);
          value = data.substring(i+1, data.length());
          break;
      }
    }
    String pug = command_execute(com, value);
    USBCOM.write(pug.c_str());
}  

static void usb_serial_callback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data){
  if(event_base == ARDUINO_USB_CDC_EVENTS){
    arduino_usb_cdc_event_data_t * data = (arduino_usb_cdc_event_data_t*)event_data;
    switch (event_id){
      case ARDUINO_USB_CDC_CONNECTED_EVENT:
        Serial.println("CDC CONNECTED");
        break;
      case ARDUINO_USB_CDC_DISCONNECTED_EVENT:
        Serial.println("CDC DISCONNECTED");
        break;
      case ARDUINO_USB_CDC_LINE_STATE_EVENT:
        Serial.printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts);
        break;
      case ARDUINO_USB_CDC_LINE_CODING_EVENT:
        Serial.printf("CDC LINE CODING: bit_rate: %lu, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity);
        break;
      case ARDUINO_USB_CDC_RX_EVENT:
        // USBCOM.printf("CDC RX [%u]:", data->rx.len);
         usb_as_serial_read();
        //xTaskCreatePinnedToCore(usb_as_serial_read, "setup_usb", 50176,NULL, 1, &setup_usb_handle, 0);
      break;
       case ARDUINO_USB_CDC_RX_OVERFLOW_EVENT:
        Serial.printf("CDC RX Overflow of %d bytes", data->rx_overflow.dropped_bytes);
        break;

      default:
        break;
    }
  }
}

void setup_usb(){
  USBD.onEvent(usbEventCallback);
  USBCOM.onEvent(usb_serial_callback);
  USBCOM.begin(115200);  
  USBD.begin();
}

Debug Message

Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception). 
Debug exception reason: Stack canary watchpoint triggered (arduino_usb_eve) 
Core  1 register dump:
PC      : 0x40380a1b  PS      : 0x00060036  A0      : 0x8037f350  A1      : 0x3fcf1ba0  
A2      : 0x3fc974b0  A3      : 0xb33fffff  A4      : 0x0000cdcd  A5      : 0x00060023  
A6      : 0x00060023  A7      : 0x0000abab  A8      : 0xb33fffff  A9      : 0xffffffff  
A10     : 0x3fc97488  A11     : 0x00000001  A12     : 0x00060021  A13     : 0x3fcf1c70  
A14     : 0x02c974b0  A15     : 0x00ffffff  SAR     : 0x00000014  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x40056f5c  LEND    : 0x40056f72  LCOUNT  : 0x00000000  

Backtrace: 0x40380a18:0x3fcf1ba0 0x4037f34d:0x3fcf1be0 0x4037d7fc:0x3fcf1c10 0x4037d7f2:0xa5a5a5a5 |<-CORRUPTED

ELF file SHA256: e6c881e7ecf05e86

Other Steps to Reproduce

this error is compler !! please check extensa32 to build elf. if call a function run, call a other function run, call nested funcion PANIC this is not correct the String not length > 65535 to convert in .c_str()

I have checked existing issues, online documentation and the Troubleshooting Guide

lbernstone commented 4 months ago

You are running out of stack space because you are passing Strings around. Don't do that, especially in String command_execute(String com, String value){, you should pass in const char*, and then have a pointer to the char array result. Learn to use printf, which can fill variables into a string much more efficiently and capably than using the += operator on Strings. Pointers exist so that you don't have to pass around big chunks of data between functions (and ultimately crash your stack). This is not a hardware issue, but a coding issue.

Red-Owl commented 4 months ago

i have test and not pass any data, only event
case ARDUINO_USB_CDC_RX_EVENT: // empty break; this crash: buffer overflow, or CORRUPTED

lbernstone commented 4 months ago

This likely means you are trying to access a variable which is out of scope. If you want assistance, provide a minimal example which can be directly compiled. Decode any backtraces. This forum is for issues with the code in the repository. If you want programming help, https://esp32.com is a better place to post.

Red-Owl commented 4 months ago

I have removed a my function used, i send a data from serial monitor, the data is "\r\n" error to create a buffer overflow is in library (no my code present) i send 5 or 6 enter from keyboard, this create a buffer overflow. I send a single enter never panic event, if i send enter,enter,enter, 5 or 6 create a buffer overflow.

me-no-dev commented 4 months ago

what is USBD and USBCOM? We need a minimal sketch to reproduce. The one posted is too large

Red-Owl commented 4 months ago

i have rewrite.... USBCDC USBSerial_cc;

TaskHandle_t ccc_usb_task; USBCDC USBSerial_cc;

void ccc_usb(void *pvParameter) { while(1){ Serial.println("CAZZI"); USBSerial_cc.println("Mazzi"); vTaskDelay(1000); } }

static void usbEventCallback(void arg, esp_event_base_t event_base, int32_t event_id, void event_data) { if (event_base == ARDUINO_USB_EVENTS) { arduino_usb_event_data_t data = (arduino_usb_event_data_t )event_data; switch (event_id) { case ARDUINO_USB_STARTED_EVENT: Serial.println("USB PLUGGED"); break; case ARDUINO_USB_STOPPED_EVENT: Serial.println("USB UNPLUGGED"); break; case ARDUINO_USB_SUSPEND_EVENT: Serial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en); break; case ARDUINO_USB_RESUME_EVENT:
Serial.println("USB RESUMED"); break;

  default: break;
}

} }

static void usbSerialCallback(void arg, esp_event_base_t event_base, int32_t event_id, void event_data) {if (event_base == ARDUINO_USB_CDC_EVENTS) { arduino_usb_cdc_event_data_t data = (arduino_usb_cdc_event_data_t )event_data; switch (event_id) { case ARDUINO_USB_CDC_CONNECTED_EVENT:
Serial.println("CDC CONNECTED"); break; case ARDUINO_USB_CDC_DISCONNECTED_EVENT: Serial.println("CDC DISCONNECTED"); break; case ARDUINO_USB_CDC_LINE_STATE_EVENT:
Serial.printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts); break; case ARDUINO_USB_CDC_LINE_CODING_EVENT: Serial.printf("CDC LINE CODING: bit_rate: %lu, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity ); break; case ARDUINO_USB_CDC_RX_EVENT: / Serial.println("USB event"); Serial.printf("CDC RX [%u]:", data->rx.len); { uint8_t buf[data->rx.len]; size_t len = USBSerial_cc.read(buf, data->rx.len); Serial.write(buf, len); } Serial.println();/ break; case ARDUINO_USB_CDC_RX_OVERFLOW_EVENT: Serial.printf("CDC RX Overflow of %d bytes", data->rx_overflow.dropped_bytes); break;

  default: 
  break;
}

} }

void setup_usb(void){ Serial.println("USB cdc init");

Serial.setDebugOutput(true); // USB.onEvent(usbEventCallback); USBSerial_cc.onEvent(usbSerialCallback); USBSerial_cc.begin(); USB.begin();

xTaskCreatePinnedToCore(ccc_usb, "ccc_usb", 4096,NULL, 1, &ccc_usb_task, 1); }

i have remved output data from example and test is enter send \r\n after 5 o 6 this creare reboot, if use a empty

assert failed: block_locate_free heap_tlsf.c:441 (block_size(block) >= size) Backtrace: 0x4037822a:0x3fcc8300 0x4037d2ed:0x3fcc8320 0x40383525:0x3fcc8340 0x403829ca:0x3fcc8470 0x4038306d:0x3fcc8490 0x4038319c:0x3fcc84b0 0x403788c7:0x3fcc84d0 0x403788d9:0x3fcc8500 0x40378902:0x3fcc8520 0x40383535:0x3fcc8540 0x4206996c:0x3fcc8560 0x420699db:0x3fcc8580 0x42069a45:0x3fcc85a0 0x4206a378:0x3fcc85c0 0x4206a55a:0x3fcc85e0 0x42077069:0x3fcc8600 0x42101fa1:0x3fcc8620 0x42065c95:0x3fcc8640 0x4210688e:0x3fcc8660 0x42106979:0x3fcc86b0 0x4003f4bd:0x3fcc86d0 0x42106256:0x3fcc86f0

realated to https://github.com/espressif/esp-mdf/issues/305 ?

TD-er commented 4 months ago

i have test and not pass any data, only event

Yes you are. For example:

String command_execute(String com, String value){

This does make a deep copy of both com and value.

Since you don't change either of these in this function, you can simply fix this copy'ing like this:

String command_execute(const String& com, const String& value){

Or like how @lbernstone wrote, you can also simply use const char* instead of const String&. This is even faster as you con't need to call .c_str() from within that function anymore.

You also do a lot of string concatenations in your function which is really a good receipe for causing memory issues, either due to memory fragmentation, or simply running out of resources as that function isn't fast, but you can expect quite a lot of events when receiving some bytes.

So to be honest, this doesn't seem like a compiler issue or hardware bug to me, but rather inefficient programming.

Red-Owl commented 4 months ago

Problem is buffer of usb event, please send a multiple request at usb, example \r\n, or long test in your console. have a panic, Not 1 send, multiple send 10 round

case ARDUINO_USB_CDC_RX_EVENT: //No code here break;

This empty code have a guru meditation

lbernstone commented 4 months ago

The code you provided is unusable due to formatting issues. Please repost it with 3 backticks (```) surrounding to make it a code block. Do you get the error if you do not use the onEvent() method? Does it only happen if you get a ARDUINO_USB_CDC_RX_EVENT event? Decode the backtrace to help identify where in the code this is failing.

Red-Owl commented 4 months ago

no panic, no error

''' TaskHandle_t ccc_usb_task; USBCDC USBSerial_cc;

void ccc_usb(void *pvParameter) { while(1){ Serial.println("CAZZI"); USBSerial_cc.println("Mazzi"); vTaskDelay(1000); } }

void setup_usb(void){ Serial.println("USB cdc init");

Serial.setDebugOutput(true); // USB.onEvent(usbEventCallback); // USBSerial_cc.onEvent(usbSerialCallback); USBSerial_cc.begin(); USB.begin();

xTaskCreatePinnedToCore(ccc_usb, "ccc_usb", 4096,NULL, 1, &ccc_usb_task, 1); }

'''

lbernstone commented 4 months ago

Ok, so you have USB Mode set to USB-OTG, and all the USB on boot options set to disable, correct? Add only the ARDUINO_USB_CDC_RX_EVENT back into your code, and remark each line until you figure out which is causing the error. If you decoded the backtrace, you wouldn't need to do this tedious work.

Red-Owl commented 4 months ago

the problem is standard #include "string" repladed to

include // replace, no c String.h

another workarround is a "delay" to response command to console (2 second) i use a usb serial to cerate input to set a display webserver (not to fast data)

please read: https://forum.arduino.cc/t/what-is-the-difference-between-std-string-and-string/641910/19 (post 20)

please add to documentation dont use #include "string" and not include, check library to use string and replace to wstring.h

tnx all for your time !!!

P.S. the buffer is alwais contain data i have set to buffer size array to \0

        case ARDUINO_USB_CDC_RX_EVENT:
        {
          int hh = data->rx.len;
          if(data->rx.len>RX_SERIAL_VAFFA_BUFFER){
            int hh = RX_SERIAL_VAFFA_BUFFER;
          }
          uint8_t buf[hh];
          int len = USBSerial_cc.read(buf,hh);
          usb_as_serial_read(buf, len);
          USBSerial_cc.flush();
        }
        break;

TaskHandle_t ccc_usb_task;
USBCDC USBSerial_cc;

char *ltrim(char *s)
{
    while(isspace(*s)) s++;
    return s;
}

char *rtrim(char *s)
{
    char* back = s + strlen(s);
    while(isspace(*--back));
    *(back+1) = '\0';
    return s;
}

char *trim(char *s)
{
    return rtrim(ltrim(s)); 
}

#define RX_SERIAL_VAFFA_BUFFER 128

char TEMPS[RX_SERIAL_VAFFA_BUFFER]{};
bool exec = false;
int usb_as_serial_read(uint8_t * buf,int len){

  for(int ti=0; ti<RX_SERIAL_VAFFA_BUFFER; ti++){   // i write buffer size to null
    TEMPS[ti] = '\0';
  } 

  for(int i=0; i<len; i++){
    char gg = buf[i];
    TEMPS[i] = gg;
  }
  return 0;
}
void ccc_usb(void *pvParameter) {
  while(1){
      // USBSerial_cc.println("TEMPS:");
      // USBSerial_cc.println(TEMPS);
      char CMD[RX_SERIAL_VAFFA_BUFFER]{};
      char VAL[RX_SERIAL_VAFFA_BUFFER]{};
      bool qq = true;
      char * pch;
      int zz = 0;
      int cc = 0;
      for(int i=0; i<RX_SERIAL_VAFFA_BUFFER; i++){
        if(qq==true){
          if(TEMPS[i] == '='){
            qq = false;
          }else{ 
            CMD[cc] = TEMPS[i];
            cc++;
          }
        }else{
          VAL[zz] = TEMPS[i];
          zz++;
        }
      }
    // USBSerial_cc.print("VAL>");
    // USBSerial_cc.print(VAL);
    // USBSerial_cc.println("<VAL:");
    // USBSerial_cc.println(CMD);
    int jjr = strlen(trim(CMD)); 
    if(jjr>0){
      String cazzo = command_execute_all(CMD, VAL);
      USBSerial_cc.println( cazzo.c_str() );
    }

    for(int ti=0; ti<RX_SERIAL_VAFFA_BUFFER; ti++){
      TEMPS[ti] = '\0';
    } 
    vTaskDelay(2000);
  }
}