Memory Allocation fails while there is Heap space available

chrisake
Posts: 1
Joined: Sun Jan 14, 2024 12:47 pm

Memory Allocation fails while there is Heap space available

Postby chrisake » Sun Jan 14, 2024 2:01 pm

I am trying to program for the T-Display-S3-long, I have downloaded the AXS15231B.cpp library and tested the basic program where it displays 3 statically allocated images. My goal is to have an RTOS task that will handle the UI rendering accordingly. The program I am testing right now is very simple it just starts the task and draws four rectangles on the screen (or at least this is what it should happen). The configuration is set to use DMA to draw on the screen so when it tries to draw the first rectangle the AXS15231B library tries to allocate memory in order to fit the rectangle pixels inside and push them through the DMA -> QSPI to the display. Although this allocation fails and since I have enabled memory and heap corruption detection the whole program restarts. I have increased the stack size of the drawing task as well as the stack size of the main_app function, also I have added some logs to see what is the available heap size before allocation and it seems enough for the allocation. Balow I have posted the code along with the logs:

app_main.cpp

Code: Select all

static uint16_t col_back = 0x07ba;
static uint16_t col1 = 0x07ba;
static uint16_t col2 = 0xfc60;
static uint16_t col3 = 0xd800;
static uint16_t col4 = 0x16e0;

void test_lcd(void *arg) {
    xSemaphoreTake(sync_lcd_task, portMAX_DELAY);

    pinMode(TFT_BL, OUTPUT);
    digitalWrite(TFT_BL, HIGH);
    ESP_LOGI(TFT_TAG, "Display Initialised");
    axs15231_init();
    lcd_setRotation(1);
    while(1) {
        digitalWrite(TFT_BL, HIGH);
        //lcd_fill(0  ,  0, 640, 180, col_back);
        lcd_fill(10 , 20, 150, 160, col1);
        lcd_fill(170, 20, 310, 160, col2);
        lcd_fill(330, 20, 470, 160, col3);
        lcd_fill(490, 20, 630, 160, col4);
        // lcd_PushColors(0, 0, 180, 640, (uint16_t *)test1_180640_map);
        // vTaskDelay(10000);

        // lcd_PushColors(0, 0, 180, 640, (uint16_t *)test2_180640_map);
        // vTaskDelay(10000);

        // lcd_PushColors(0, 0, 180, 640, (uint16_t *)test3_180640_map);
        vTaskDelay(10000);
    }
    
}

void app_main(void)
{
    ESP_LOGI("main", "Free Heap size %d", xPortGetFreeHeapSize());
    //Allow other core to finish initialization
    vTaskDelay(pdMS_TO_TICKS(100));

    //Create semaphores to synchronize
    sync_wifi_prov_task = xSemaphoreCreateBinary();
    sync_stats_task = xSemaphoreCreateBinary();
    sync_lcd_task = xSemaphoreCreateBinary();

    xTaskCreatePinnedToCore(provision_wifi, WIFI_PROV_TASK_NAME, 4096, NULL, WIFI_PROV_PRIO, NULL, 0);
    ESP_LOGI("main", "Free Heap size %d", xPortGetFreeHeapSize());
    xTaskCreatePinnedToCore(stats_task, STATS_TASK_NAME, 4096, NULL, STATS_TASK_PRIO, NULL, tskNO_AFFINITY);
    ESP_LOGI("main", "Free Heap size %d", xPortGetFreeHeapSize());
    xTaskCreatePinnedToCore(test_lcd, "lcd_test", 220000, NULL, 4, NULL, 1);
    ESP_LOGI("main", "Free Heap size %d", xPortGetFreeHeapSize());

    xSemaphoreGive(sync_lcd_task);
    xSemaphoreGive(sync_wifi_prov_task);
    xSemaphoreGive(sync_stats_task);
}
I have modified the function that fails on the AXS15231B library to add two logs before allocation:

Code: Select all

static const char *TFT_TAG = "display";
void lcd_fill(uint16_t xsta,
              uint16_t ysta,
              uint16_t xend,
              uint16_t yend,
              uint16_t color)
{

    uint16_t w = xend - xsta;
    uint16_t h = yend - ysta;
    uint32_t size = w * h * 2;
    ESP_LOGI(TFT_TAG, "Free Heap size %d", xPortGetFreeHeapSize());
    ESP_LOGI(TFT_TAG, "Trying to allocate %lu bytes", size);
    uint16_t *color_p = (uint16_t *)heap_caps_malloc(size, MALLOC_CAP_INTERNAL);
    if (color_p == NULL) {
        ESP_LOGE(TFT_TAG, "Failed to allocate memory (%lu bytes)", size);
        return;
    }
    int i = 0;
    for(i = 0; i < w * h ; i+=1)
    {
        color_p[i] = color;
    }

    lcd_PushColors(xsta, ysta, w, h, color_p);
    free(color_p);
}
The logs I get when it runs:

Code: Select all

Task allocation on app_main:
I (454) main: Free Heap size 296752
I (558) main: Free Heap size 291928
I (558) main: Free Heap size 287440
I (565) main: Free Heap size 67048
...
Memory allocation on AXS15231B:
...
I (1377) display: Free Heap size 44024
I (1378) display: Trying to allocate 39200 bytes

Mem alloc fail. size 0x00009920 caps 0x00000800


Backtrace: 0x40375c72:0x3fce7c40 0x4037e47d:0x3fce7c60 0x403765dd:0x3fce7c80 0x40376632:0x3fce7ce0 0x40376d15:0x3fce7d00 0x40376e3d:0x3fce7d50 0x4200c238:0x3fce7d70 0x4200ba76:0x3fce7da0 0x403811de:0x3fce7dc0
0x40375c72: panic_abort at C:/Users/~/esp/esp-idf/components/esp_system/panic.c:452

0x4037e47d: esp_system_abort at C:/Users/~/esp/esp-idf/components/esp_system/port/esp_system_chip.c:84

0x403765dd: heap_caps_alloc_failed at C:/Users/~/esp/esp-idf/components/heap/heap_caps.c:96

0x40376632: heap_caps_malloc at C:/Users/~/esp/esp-idf/components/heap/heap_caps.c:201

0x40376d15: trace_malloc at C:/Users/~/esp/esp-idf/components/heap/include/heap_trace.inc:95

0x40376e3d: __wrap_heap_caps_malloc at C:/Users/~/esp/esp-idf/components/heap/include/heap_trace.inc:184

0x4200c238: lcd_fill(unsigned short, unsigned short, unsigned short, unsigned short, unsigned short) at ###/main/AXS15231B.cpp:284

0x4200ba76: test_lcd(void*) at ###/main/app_main.cpp:48 (discriminator 1)

0x403811de: vPortTaskWrapper at C:/Users/~/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:162
Does anyone know why this allocation fails since there is enough memory and how to overcome this issue?

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Memory Allocation fails while there is Heap space available

Postby ESP_Sprite » Mon Jan 15, 2024 3:44 am

You probably have enough memory available, but it's fragmented (as in: many small regions of memory available, but not one large enough for the buffer you need to allocate) and as such the allocation fails.

User avatar
ok-home
Posts: 78
Joined: Sun May 02, 2021 7:23 pm
Location: Russia Novosibirsk
Contact:

Re: Memory Allocation fails while there is Heap space available

Postby ok-home » Mon Jan 15, 2024 4:10 am

Hi
Try checking the size of free memory via
size_t heap_caps_get_largest_free_block(uint32_t caps)

https://docs.espressif.com/projects/esp ... k8uint32_t

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Memory Allocation fails while there is Heap space available

Postby MicroController » Mon Jan 15, 2024 10:47 am

One option for this specific case would be to 'push' multiple smaller areas, like for(i = 0; i < 8; ++i) { lcd_PushColors(xsta, ysta+(h/8)*i, w, h/8, color_p); }
Another option would be to use a different library which uses the heap more 'responsibly'.

Who is online

Users browsing this forum: No registered users and 130 guests