Search code examples
cesp32freertosplatformio

FreeRTOS application crashing when spawning 8 similar tasks, while it does work with 5 and 15 spawned tasks (ESP32-S3-DevKitC-1)


I do the following in FreeRTOS:

#define DEBUG_MODE

#define COMPUTATION_TIME(taskNr) (50)
#define DELAY_TIME(taskNr) (200 * (taskNr))
#define TASK_PRIORITY(taskNr) (tskIDLE_PRIORITY + 1 + taskNr)

#define NUMBER_OF_TASKS 8


void print_chip_info(){

    esp_chip_info_t chip_info;
    esp_chip_info(&chip_info);
    printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
        CONFIG_IDF_TARGET,
        chip_info.cores,
        (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
        (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");

    printf("silicon revision %d, ", chip_info.revision);

    printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
        (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");

    printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
}


void task_implementation(void *param){
    // configASSERT((uint32_t)param == 1UL);
    // Task variables
    taskParameters parameters = *(taskParameters *)param;
    unsigned count = 0;
    uint8_t taskNr = parameters.taskNr;
    uint16_t computationTime = parameters.computationTime;
    uint16_t delay = parameters.delay;
    TickType_t xLastWakeTime;
    // const TickType_t xPeriod = pdMS_TO_TICKS(delay);

    // A task should always run endlessly
    while (1)
    {
        xLastWakeTime = xTaskGetTickCount();
        count++;

#ifdef DEBUG_MODE
        printf("TASK %d: %d   |   (%d, %d) \n", taskNr, count, computationTime, delay);
        printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
#endif // DEBUG MODE

        while (xTaskGetTickCount() < (xLastWakeTime + computationTime));
        vTaskDelayUntil(&xLastWakeTime, delay); //xPeriod
    }
}


void app_main(void)
{

#ifdef DEBUG_MODE
    // give MCU information
    print_chip_info();
#endif // DEBUG_MODE

    // Task initialization parameters
    uint16_t i;
    struct taskParameters *taskPtr;
    taskPtr = (struct taskParameters *)malloc(NUMBER_OF_TASKS * sizeof(struct taskParameters));
    char taskName[8];
    uint8_t taskPriority;

    for (i = 1; i <= NUMBER_OF_TASKS; ++i)
    {
        sprintf(taskName, "%d", i);
        (taskPtr + i)->taskNr = i;
        (taskPtr + i)->computationTime = COMPUTATION_TIME(i);
        (taskPtr + i)->delay = DELAY_TIME(i);
        taskPriority = TASK_PRIORITY(i);

        xTaskCreate(&task_implementation, taskName, 2048, (taskPtr + i), taskPriority, NULL);
    }

    free(taskPtr);
}

Which gives as output the following repeatedly:

> This is esp32s3 chip with 2 CPU core(s), WiFi/BLE, silicon revision 0, 8MB external flash
> Minimum free heap size: 389352 bytes
> TASK 1: 1   |   (50, 200)
> ESP-ROM:esp32s3-20210327
> Build:Mar 27 2021
> rst:0xc (RTC_SW_CPU_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
> Saved PC:0x420161b6
> SPIWP:0xee
> Octal Flash Mode Enabled
> For OPI Flash, Use Default Flash Boot Mode
> mode:SLOW_RD, clock div:1
> load:0x3fcd0108,len:0x1648
> load:0x403b6000,len:0xb7c
> load:0x403ba000,len:0x2f74
> SHA-256 comparison failed:
> Calculated: 03f53ed4905ac0ddc098b12d626ddc7ef4559209f5285446ebd397a018f229c6
> Expected: 5a5923c2b428acc85433a171e05242eb380bdafa05b6cabe2f6f177bc2db819b
> Attempting to boot anyway...
> entry 0x403b6248
> ␛[0;32mI (50) boot: ESP-IDF 4.4.1 2nd stage bootloader␛[0m
> ␛[0;32mI (50) boot: compile time 10:23:12␛[0m
> ␛[0;32mI (50) boot: chip revision: 0␛[0m
> ␛[0;32mI (52) boot.esp32s3: Boot SPI Speed : 80MHz␛[0m
> ␛[0;32mI (56) boot.esp32s3: SPI Mode       : SLOW READ␛[0m
> ␛[0;32mI (62) boot.esp32s3: SPI Flash Size : 8MB␛[0m
> ␛[0;32mI (66) boot: Enabling RNG early entropy source...␛[0m
> ␛[0;32mI (72) boot: Partition Table:␛[0m
> ␛[0;32mI (75) boot: ## Label            Usage          Type ST Offset   Length␛[0m
> ␛[0;32mI (83) boot:  0 nvs              WiFi data        01 02 00009000 00006000␛[0m
> ␛[0;32mI (90) boot:  1 phy_init         RF data          01 01 0000f000 00001000␛[0m
> ␛[0;32mI (98) boot:  2 factory          factory app      00 00 00010000 00100000␛[0m
> ␛[0;32mI (105) boot: End of partition table␛[0m
> ␛[0;32mI (109) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=07994h ( 31124) map␛[0m
> ␛[0;32mI (125) esp_image: segment 1: paddr=000179bc vaddr=3fc906c0 size=026f8h (  9976) load␛[0m
> ␛[0;32mI (129) esp_image: segment 2: paddr=0001a0bc vaddr=40374000 size=05f5ch ( 24412) load␛[0m
> ␛[0;32mI (142) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=16ca4h ( 93348) map␛[0m
> ␛[0;32mI (165) esp_image: segment 4: paddr=00036ccc vaddr=40379f5c size=0675ch ( 26460) load␛[0m
> ␛[0;32mI (173) esp_image: segment 5: paddr=0003d430 vaddr=50000000 size=00010h (    16) load␛[0m
> ␛[0;32mI (178) boot: Loaded app from partition at offset 0x10000␛[0m
> ␛[0;32mI (179) boot: Disabling RNG early entropy source...␛[0m
> ␛[0;32mI (194) cpu_start: Pro cpu up.␛[0m
> ␛[0;32mI (194) cpu_start: Starting app cpu, entry point is 0x403750c4␛[0m
> ␛[0;32mI (157) cpu_start: App cpu up.␛[0m
> ␛[0;32mI (208) cpu_start: Pro cpu start user code␛[0m
> ␛[0;32mI (208) cpu_start: cpu freq: 160000000␛[0m
> ␛[0;32mI (208) cpu_start: Application information:␛[0m
> ␛[0;32mI (211) cpu_start: Project name:     PioFreeRTOS␛[0m
> ␛[0;32mI (216) cpu_start: App version:      28c61da-dirty␛[0m
> ␛[0;32mI (222) cpu_start: Compile time:     Jan 13 2023 10:20:15␛[0m
> ␛[0;32mI (228) cpu_start: ELF file SHA256:  bc4695204a8e358a...␛[0m
> ␛[0;32mI (234) cpu_start: ESP-IDF:          4.4.1␛[0m
> ␛[0;32mI (239) heap_init: Initializing. RAM available for dynamic allocation:␛[0m
> ␛[0;32mI (246) heap_init: At 3FC93798 len 0004C868 (306 KiB): D/IRAM␛[0m
> ␛[0;32mI (252) heap_init: At 3FCE0000 len 0000EE34 (59 KiB): STACK/DRAM␛[0m
> ␛[0;32mI (259) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM␛[0m
> ␛[0;32mI (265) heap_init: At 600FE000 len 00002000 (8 KiB): RTCRAM␛[0m
> ␛[0;32mI (272) spi_flash: detected chip: mxic␛[0m
> ␛[0;33mW (276) spi_flash: Detected flash size > 16 MB, but access beyond 16 MB is not supported for this flash model yet.␛[0m
> ␛[0;32mI (287) spi_flash: flash io: dio␛[0m
> ␛[0;33mW (291) spi_flash: Detected size(32768k) larger than the size in the binary image header(8192k). Using the size in the binary image header.␛[0m
> ␛[0;32mI (305) sleep: Configure to isolate all GPIO pins in sleep state␛[0m
> ␛[0;32mI (311) sleep: Enable automatic switching of GPIO sleep configuration␛[0m
> ␛[0;32mI (318) cpu_start: Starting scheduler on PRO CPU.␛[0m
> ␛[0;32mI (0) cpu_start: Starting scheduler on APP CPU.␛[0m

While when I use #define NUMBER_OF_TASKS 5 or #define NUMBER_OF_TASKS 15 everything is working fine. I have been struggling with this for quite some time now, everything seems to be narrowed down to be something very simple but I still have the same issue with the code above.


Solution

  • The solution was an off-by-one mistake in the taskPtr array. Working version would look as follows:

    for (i = 0; i < NUMBER_OF_TASKS; ++i)
    {
        sprintf(taskName, "%d", i);
        taskPtr[i].taskNr = i;
        taskPtr[i].computationTime = COMPUTATION_TIME(i);
        taskPtr[i].delay = DELAY_TIME(i);
        taskPriority = TASK_PRIORITY(i);
    
        xTaskCreate(&task_implementation, taskName, 2048, &taskPtr[i], taskPriority, NULL);
    }
    

    Also adjusted the array indexing as was mentioned by "Some programmer dude"