Search code examples
cesp32

ESP32 Crashing on vTaskDelay


I put this code onto my ESP32 using ESP32-IDF in PlatformIO:

#include <driver/gpio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>

#define RELAY 2


void hello_task(void *pvParameter)
{
    printf("Hello world!\n");
    for (int i = 10; i >= 0; i--) {
        printf("Restarting in %d seconds...\n", i);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
    printf("Restarting now.\n");
    fflush(stdout);
    esp_restart();
}


void led_blink(void *pvParams)
{
    printf("Resetting pin\n");
    gpio_reset_pin(RELAY);
    printf("Setting pin direction\n");
    gpio_set_direction(RELAY,GPIO_MODE_OUTPUT);
    while (1) {
        printf("Setting GPIO level low\n");
        esp_err_t error_num = gpio_set_level(RELAY,0);
        printf("error_num: %d\n", error_num);
        vTaskDelay(pdMS_TO_TICKS(500)); // Here is where the panic happens
        printf("Setting GPIO level high\n");
        error_num = gpio_set_level(RELAY,1);
        printf("error_num: %d\n", error_num);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}


void app_main()
{
    xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL);
    xTaskCreate(&led_blink,"LED_BLINK",1024,NULL,5,NULL);
}

And it panics when reaching the first vTaskDelay in led_blink. This is what the last bit of the log shows (I can put the whole thing if someone says it's necessary):

␛[0;32mI (306) app_start: Starting scheduler on CPU0␛[0m
␛[0;32mI (311) app_start: Starting scheduler on CPU1␛[0m
␛[0;32mI (311) main_task: Started on CPU0␛[0m
␛[0;32mI (321) main_task: Calling app_main()␛[0m
Hello world!
Restarting in 10 seconds...
Resetting pin
␛[0;32mI (321) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 ␛[0m
Setting pin direction
Setting GPIO level low
error_num: 0
␛[0;32mI (341) main_task: Returned from app_main()␛[0m
Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x400869c8  PS      : 0x00060033  A0      : 0x800883ea  A1      : 0x3ffb0e50  
A2      : 0x00000001  A3      : 0x0000000a  A4      : 0x00000035  A5      : 0x00000005  
A6      : 0xb33fffff  A7      : 0xb33fffff  A8      : 0x00000001  A9      : 0x00000000  
A10     : 0x00000000  A11     : 0x80000001  A12     : 0x00000000  A13     : 0x00060023  
A14     : 0xb33fffff  A15     : 0xb33fffff  SAR     : 0x0000001e  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x0000000e  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  


Backtrace: 0x400869c5:0x3ffb0e50 0x400883e7:0x3ffb0e70 0x40088231:0x3ffb0e90 0x40082732:0x3ffb0ea0 0x4008467f:0x3ffb5290 0x400d385f:0x3ffb52b0 0x40086726:0x3ffb52d0 0x40087c79:0x3ffb52f0

I have a power supply connected which can support 2A, which is far more than enough, so it's not a power issue. I note that the log says OutputEn: 0 which made me think that maybe there was an issue with setting the pin, but the return code for pin setting is 0...

Why would a crash like this happen? I basically just copied some tutorial code and added some printf statements.


Solution

  • Most likely explanation is that task LED_BLINK runs out of memory. Unfortunately printf()&friends consume unexpectedly large amounts of stack memory, definitely over 1KiB that you've allocated. Bump the stack to 2KiB for starters, prepare to double it again as soon as you call any other non-trivial libraries.

    To be honest, I start any task stack at 8KiB or more, then lower it after stack usage metrics from vTaskList() show how much stack this task is actually consuming. It's a massive waste of time starting your work with stack debugging :)