-
Notifications
You must be signed in to change notification settings - Fork 7.7k
-
My program is testing ok until the board is restarting. Here is the screenshot on the watchdog.
图片
Is this saying that the psram is unstable? Here is my platformio.ini screenshot
Thanks for your response!
Beta Was this translation helpful? Give feedback.
All reactions
Some updates: I now add close HTTP connection after each request, since it may free up the memory, but it is still crashing at the same traceback.
if(http.POST(toSend)>0) {
//Serial.println(http.getString());
http.clearAllCookies();
//int time_end = millis();
http.end();
//Serial.println(millis()-time_end);
delay(20);
}
and this is my platform.ini setup
[env:esp-wrover-kit]
platform = espressif32
board = esp-wrover-kit
framework = arduino
monitor_speed = 115200
upload_speed = 921600
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = qio
build_flags =
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-i...
Replies: 4 comments 8 replies
-
@blaticslm PSRAM is not necessarily the issue. The error states the WDT wasn't kicked in time on the idle task. Are you calling esp_task_wdt_reset()
in loop()
[Arduino's idle task]? Have you tried not using the PSRAM? Have you tried increasing CORE_DEBUG_LEVEL to see error messages?
Beta Was this translation helpful? Give feedback.
All reactions
-
1,At each task,I do call VTaskDelay(1)
2, I did test PSRAM, and it works properly without HTTP
3, My core debug level is set to verbose but still see only that address corrupted.
I will upload my program here to let you see.
Beta Was this translation helpful? Give feedback.
All reactions
-
@mrengineer7777 Here are some details on my program:
The running logic is shown below (the arrows are representing the time interval between two tasks):
图片
here is my task1 code
void Task1code( void * pvParameters ) {
Serial.print("Collection task running on core ");
Serial.println(xPortGetCoreID());
//local JsonDocument, initialzing here can uses PSRAM
SpiRamJsonDocument group_data1(DOCSIZE);
SpiRamJsonDocument group_data2(DOCSIZE);
JsonArray object;
//using global varible to store the reference for these two JsonDocuments
//and process them in Task2
holder1 = &group_data1;
holder2 = &group_data2;
Serial.println((String)"Memory available in PSRAM : " +ESP.getFreePsram());
for(;;){
if(digitalRead(SWITCH_PIN) != HIGH) {
vTaskDelay(1); //feeding the dog
continue;
}
//buffer switching
if(!processing) {
if(task1docInit && !task2docInit){
Serial.println("Creating group data1");
object = group_data1.createNestedArray("group_data"); //initialized here
} else if(!task1docInit && task2docInit) {
Serial.println("Creating group data2");
object = group_data2.createNestedArray("group_data"); //initialized here
}
processing = true;
}
delay(5); //simulating collecting samples in 500Hz for ADXL355
//simulation parameters
float x_pos = (float)random(0,25);
float y_pos = (float)random(0,25);
float x_act = x_pos * random(0,2);
float y_act = y_pos * random(0,2);
//fill the documents
if(counter <= 900){
//to avoid buffer overflow, once it reach the limit, we need to stop to wait
JsonObject object_in = object.createNestedObject();
object_in["Machine_ID"] = ID;
object_in["Job_ID"] = job_id;
object_in["Job_order"] = job_order;
object_in["Layer"] = layer;
object_in["X_pos"] = x_pos;
object_in["Y_pos"] = y_pos;
object_in["X_act"] = x_act;
object_in["Y_act"] = y_act;
if(job_order % 10 == 0){
layer++;
//job_order = 1;
}
job_order++;
if(layer == 1000){
job_id++;
layer = 1;
}
counter++;
}
//TODO: determine what is the proper size for job_order to collect
if(counter >= 500 && ready) {
//Serial.println("reaching here 2");
Serial.println((String)"Collecting done! counter: " + counter);
//Serial.println(ESP.getFreePsram());
processing = false;
counter = 0;
ready = false;
if(task1docInit && !task2docInit){
// serializeJson(group_data1, Serial);
Serial.println();
sending = true;
buffer_index = 1;
task1docInit = false;
task2docInit = true;
} else if(!task1docInit && task2docInit){
// serializeJson(group_data2, Serial);
Serial.println();
sending = true;
buffer_index = 2;
task1docInit = true;
task2docInit = false;
}
//rest of them give to task2 to deal with
}
}
}
here is my task2 code
void Task2code( void * pvParameters ) {
Serial.print("Task2 running on core ");
Serial.println(xPortGetCoreID());
char* toSend = (char*)heap_caps_malloc(DOCSIZE * sizeof(char), MALLOC_CAP_SPIRAM);
//char* toSend = (char*)ps_malloc(DOCSIZE * sizeof(char));
char* printtext = (char*)malloc(16 * sizeof(char));
for(;;){
if(digitalRead(SWITCH_PIN) != HIGH){
vTaskDelay(1);
continue;
}
if(!processing && sending) {
//if processing is false, and sending is true, then we need to send buffer to cloud
// determining Which buffer will be sent
switch(buffer_index){
case 1:
printtext = (char*)"Sending 1...";
Serial.println(printtext);
serializeJson((*holder1), toSend, DOCSIZE * sizeof(char));
break;
case 2:
printtext = (char*)"Sending 2...";
Serial.println(printtext);
serializeJson((*holder2), toSend, DOCSIZE * sizeof(char));
break;
}
// I have no idea why HTTP request crash the ram or stack
//I have tested the hardware, indicating the PSRAM is working properly
//I replace this HTTP post request as delay(500) to simulate request time, and no watchdog is trigged.
//But when I use this HTTP POST, memory corruption is happening.
//Sometimes the crash happens at the beginning of the process and sometimes wait for a long time
if(http.POST(toSend)>0) {
//Serial.println(http.getString());
http.clearAllCookies();
http.clear();
}
//delay(500); //simulate http request time
//Cleaning process
printtext = (char*)"Cleaning";
Serial.println(printtext);
switch(buffer_index){
case 1:
(*holder1).clear();
break;
case 2:
(*holder2).clear();
break;
}
buffer_index = 0;
sending = false;
ready = true;
}
}
}
This is the correct running screenshot
图片
And here is the screenshot of crashing
图片
Beta Was this translation helpful? Give feedback.
All reactions
-
Some updates: I now add close HTTP connection after each request, since it may free up the memory, but it is still crashing at the same traceback.
if(http.POST(toSend)>0) {
//Serial.println(http.getString());
http.clearAllCookies();
//int time_end = millis();
http.end();
//Serial.println(millis()-time_end);
delay(20);
}
and this is my platform.ini setup
[env:esp-wrover-kit]
platform = espressif32
board = esp-wrover-kit
framework = arduino
monitor_speed = 115200
upload_speed = 921600
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = qio
build_flags =
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue
-DCORE_DEBUG_LEVEL=4
; -DCONFIG_SPIRAM_USE_MALLOC=1
-DCONFIG_SPIRAM_SPEED_80M=1
build_type = debug
monitor_filters = time, default, esp32_exception_decoder
lib_deps =
bblanchon/ArduinoJson@^6.19.4
Beta Was this translation helpful? Give feedback.
All reactions
-
@blaticslm I believe you are fighting a WDT issue, not memory corruption. Calling http.end() will free up some memory but will also slow down the HTTP connection, as it can't reuse the connection that's already open.
I use HTTPClient as well. The error here is pretty clear. One of your tasks is running for longer than the WDT timeout, which I believe is 5 seconds by default. You can test that by disabling the WDT and seeing that your code doesn't crash. Based on your screenshot, I'm guessing it happens during "Creating group data2" in Task1.
In my project I used to get a WDT if the HTTP request took longer than 5 seconds, so I changed our WDT to 15 seconds, and also set a limit on HTTP requests to 9 seconds.
Beta Was this translation helpful? Give feedback.
All reactions
-
Interesting. Does this help? https://www.digikey.com/en/maker/projects/introduction-to-rtos-solution-to-part-12-multicore-systems/369936f5671d4207a2c954c0637e7d50
Beta Was this translation helpful? Give feedback.
All reactions
-
Interesting. Does this help? https://www.digikey.com/en/maker/projects/introduction-to-rtos-solution-to-part-12-multicore-systems/369936f5671d4207a2c954c0637e7d50
I am going to do some experiments to see why my task2 doesn't run well in core 0. After switching from core0 to core1, my program is running like perfect.
Beta Was this translation helpful? Give feedback.
All reactions
-
Note in the link I sent that the WiFi task runs on core 0. Perhaps calling HTTPclient from a task on core 0 causes a deadlock with WiFi as the task is blocking core 0.
Beta Was this translation helpful? Give feedback.
All reactions
-
Note in the link I sent that the WiFi task runs on core 0. Perhaps calling HTTPclient from a task on core 0 causes a deadlock with WiFi as the task is blocking core 0.
Quote from the article you have sent
- The cores in the ESP32 are labeled "Core 0" and "Core 1." Core 0 is known as the "Protocol Core" or "PRO CPU." In default ESP32 applications, protocol-related tasks, like WiFi and Bluetooth, are assigned to this core. Core 1 is known as the "Application Core" or "APP CPU," which is responsible for running user applications.
I think that is what happens to my program, and that is why ESP32 runs Arduino on core 1 instead of core 0. Thanks for sharing, now all the confusion is solved.
Beta Was this translation helpful? Give feedback.
All reactions
-
Thanks for the feedback. "Don't call HTTPClient from Core 0 as it deadlocks with WiFi Task". Good to know.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1