Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

May someone here tell me how is my program is stopped? #7624

Answered by blaticslm
blaticslm asked this question in Q&A
Discussion options

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!

You must be logged in to vote

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

Comment options

@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?

You must be logged in to vote
1 reply
Comment options

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.

Comment options

@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
图片

You must be logged in to vote
0 replies
Comment options

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
You must be logged in to vote
0 replies
Answer selected by blaticslm
Comment options

@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.

You must be logged in to vote
7 replies
Comment options

Comment options

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.

Comment options

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.

Comment options

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.

Comment options

Thanks for the feedback. "Don't call HTTPClient from Core 0 as it deadlocks with WiFi Task". Good to know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /