Description
ESP32 Program written with ESP-IDF Framework is Crashing if lv_timer_handler
is called @ 5milliseconds, but working fine when called @10milliseconds
What MCU/Processor/Board and compiler are you using?
ESP32 with Custom Board
What do you want to achieve?
I wanted to integrate the LVGL with my display board, and it is working also if I set the 10ms delay for calling lv_timer_handler
function
What have you tried so far?
I am reading online what could be the issue, for learning purposes I wrote the ILI9341 drivers and XPT2046 by taking reference from the porting example, so I assume there could be some problem, as I did this for learning purposes.
Code to reproduce
void display_init( void )
{
// for LVGL 8.3.11
static lv_disp_draw_buf_t draw_buf; // contains internal graphics buffer called draw buffer
static lv_disp_drv_t disp_drv; // contains callback functions
static lv_indev_drv_t indev_drv; // input device drivers
// initialize the lvgl library
lv_init();
// initialize the tft and touch library
tft_init();
lv_color_t *buf1 = heap_caps_malloc(DISP_BUFFER_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf1);
lv_color_t *buf2 = heap_caps_malloc(DISP_BUFFER_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf2);
// LVGL Draw Buffer
// initialize the working buffer
lv_disp_draw_buf_init(&draw_buf, buf1, buf2, DISP_BUFFER_SIZE);
// Register Display Driver to LVGL
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = tft_get_width();
disp_drv.ver_res = tft_get_height();
// disp_drv.flush_cb = display_flush_slow_cb;
disp_drv.flush_cb = display_flush_cb;
// disp_drv.flush_cb = display_flush_swap_cb;
disp_drv.drv_update_cb = NULL; // todo
disp_drv.draw_buf = &draw_buf;
// user data todo
// lv_disp_t *disp = lv_disp_drv_register(&disp_drv);
lv_disp_drv_register(&disp_drv);
// Tick Interface for LVGL using esp_timer to generate 2ms periodic event
const esp_timer_create_args_t lvgl_tick_timer_args =
{
.callback = &lvgl_tick,
.name = "lvgl_tick"
};
esp_timer_handle_t lvgl_tick_timer;
ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, LV_TICK_PERIOD_MS * 1000)); // here time is in micro seconds
// configuring input devices
lv_indev_drv_init(&indev_drv); // Basic initialization
indev_drv.type = LV_INDEV_TYPE_POINTER; // touchpad and mouse
indev_drv.read_cb = display_input_read; // register callback
// Register the driver in LVGL and save the created input device object
// lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);
lv_indev_drv_register(&indev_drv);
// callback function, task name, stack size, parameters, priority, task handle
xTaskCreate(&display_mng, "display mng", 4096, NULL, 5, NULL);
}
// Private Function Definitions
/**
* @brief Display Manager Function which calls the lvgl timer handler function
* @param *pvParameter task parameter
*/
static void display_mng(void *pvParameter)
{
while(1)
{
lv_timer_handler();
vTaskDelay(5 / portTICK_PERIOD_MS);
}
}
/**
* @brief LVGL Tick Funtion Hook
* LVGL need to call funcion lv_tick_inc periodically @ LV_TICK_PERIOD_MS
* to keep timing information.
* @param arg
*/
static void lvgl_tick(void *arg)
{
(void) arg;
lv_tick_inc(LV_TICK_PERIOD_MS);
}
The following is my flush function.
static void display_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
size_t width = (area->x2 - area->x1 + 1);
size_t height = (area->y2 - area->y1 + 1);
size_t len = width * height * 2;
ili9341_set_window(area->x1, area->y1, area->x2, area->y2)
// while here the first command i.e. ILI9341_GRAM using polling method
// while the send data method using spi_device_transmit function
tft_send_cmd(ILI9341_GRAM, 0, 0);
tft_send_data((uint8_t*)color_map, len);
lv_disp_flush_ready(drv);
}
and following are ttft_send_cmd
and tft_send_data
functions.
void tft_send_cmd( uint8_t cmd, const uint8_t *data, size_t len )
{
esp_err_t ret;
spi_transaction_t t;
TFT_CS_LOW();
TFT_DC_LOW();
// Send Command
memset( &t, 0x00, sizeof(t) ); // zero out the transaction
t.length = 8; // Commands are 8-bits
t.tx_buffer = &cmd; // The data is command itself
ret = spi_device_polling_transmit(spi_tft_handle, &t); // transmit
assert(ret == ESP_OK); // should have no issues
TFT_DC_HIGH();
// if there is some data with command
if( len )
{
memset( &t, 0x00, sizeof(t) ); // zero out the transaction
t.length = len*8; // length is in bytes while transaction length is in bits
t.tx_buffer = data; // The data is command itself
ret = spi_device_polling_transmit(spi_tft_handle, &t); // transmit
TFT_CS_HIGH();
assert(ret == ESP_OK); // should have no issues
}
TFT_CS_HIGH();
}
void tft_send_data( const uint8_t *data, size_t len )
{
esp_err_t ret;
spi_transaction_t t;
if( len == 0 )
return; // no need to send anything
TFT_CS_LOW();
TFT_DC_HIGH();
memset( &t, 0x00, sizeof(t) ); // zero out the transaction
t.length = len*8; // length is in bytes while transaction length is in bits
t.tx_buffer = data; // Data
// Not used any more
// t.user = (void*)1; // transaction id, keep it 1 for data mode
// ret = spi_device_polling_transmit(spi_tft_handle, &t); // transmit
ret = spi_device_transmit(spi_tft_handle, &t); // transmit
TFT_CS_HIGH();
assert(ret == ESP_OK); // should have no issues
}
The following are logs when the system is working fine, but as can be seen, there are still some errors reported by the LVGL library, this is when I call lv_timer_handler
every 10ms.
I (0) cpu_start: App cpu up.
I (300) cpu_start: Pro cpu start user code
I (300) cpu_start: cpu freq: 160000000 Hz
I (300) cpu_start: Application information:
I (305) cpu_start: Project name: app-template
I (310) cpu_start: App version: a6c7024-dirty
I (315) cpu_start: Compile time: Jan 30 2024 06:53:43
I (322) cpu_start: ELF file SHA256: 8137eff5eba74545...
I (328) cpu_start: ESP-IDF: v5.1.2
I (332) cpu_start: Min chip rev: v0.0
I (337) cpu_start: Max chip rev: v3.99
I (342) cpu_start: Chip rev: v1.0
I (347) heap_init: Initializing. RAM available for dynamic allocation:
I (354) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (360) heap_init: At 3FFBB118 len 00024EE8 (147 KiB): DRAM
I (366) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (373) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (379) heap_init: At 4008DE74 len 0001218C (72 KiB): IRAM
I (387) spi_flash: detected chip: generic
I (390) spi_flash: flash io: dio
I (394) app_start: Starting scheduler on CPU0
I (399) app_start: Starting scheduler on CPU1
I (399) main_task: Started on CPU0
I (409) main_task: Calling app_main()
I (409) gpio: GPIO[0]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (419) gpio: GPIO[5]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
[Error] (0.004, +4) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.006, +2) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.012, +6) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.022, +10) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.030, +8) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.040, +10) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.048, +8) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.058, +10) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.084, +26) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.086, +2) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.096, +10) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.102, +6) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.108, +6) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
LVGL Demo Running
LVGL Demo Running
But if I increase the frequency to call lv_timer_handler
, then the following are the logs, and here system is crashing and facing a lot of troubles.
I (0) cpu_start: App cpu up.
I (300) cpu_start: Pro cpu start user code
I (300) cpu_start: cpu freq: 160000000 Hz
I (300) cpu_start: Application information:
I (305) cpu_start: Project name: app-template
I (310) cpu_start: App version: a6c7024-dirty
I (315) cpu_start: Compile time: Jan 30 2024 06:53:43
I (322) cpu_start: ELF file SHA256: 8ac5b7051afa6060...
I (328) cpu_start: ESP-IDF: v5.1.2
I (332) cpu_start: Min chip rev: v0.0
I (337) cpu_start: Max chip rev: v3.99
I (342) cpu_start: Chip rev: v1.0
I (347) heap_init: Initializing. RAM available for dynamic allocation:
I (354) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (360) heap_init: At 3FFBB118 len 00024EE8 (147 KiB): DRAM
I (366) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (373) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (379) heap_init: At 4008DE74 len 0001218C (72 KiB): IRAM
I (387) spi_flash: detected chip: generic
I (390) spi_flash: flash io: dio
I (394) app_start: Starting scheduler on CPU0
I (399) app_start: Starting scheduler on CPU1
I (399) main_task: Started on CPU0
I (409) main_task: Calling app_main()
I (409) gpio: GPIO[0]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (419) gpio: GPIO[5]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
[Error] (0.004, +4) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.006, +2) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.012, +6) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.022, +10) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.030, +8) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.040, +10) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.048, +8) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.058, +10) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.070, +12) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.078, +8) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.104, +26) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.108, +4) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.342, +234) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
[Error] (0.346, +4) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #213)
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400ddf72 PS : 0x00060c30 A0 : 0x800de061 A1 : 0x3ffc1b30
0x400ddf72: get_prop_core at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_obj_style.c:618
A2 : 0x3ffb4380 A3 : 0x00000000 A4 : 0x00000000 A5 : 0x00000000
A6 : 0x00000008 A7 : 0x00060023 A8 : 0x800ddf45 A9 : 0x3ffc1b10
A10 : 0x00000003 A11 : 0x00000000 A12 : 0x3ffc1d30 A13 : 0x00000000
A14 : 0x00000000 A15 : 0x00000009 SAR : 0x0000001d EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000004 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff
0x4000c2e0: memcpy in ROM
0x4000c2f6: memcpy in ROM
Backtrace: 0x400ddf6f:0x3ffc1b30 0x400de05e:0x3ffc1b80 0x400d94f5:0x3ffc1bb0 0x400d9faf:0x3ffc1c60 0x4011052d:0x3ffc1c90 0x400e7a0d:0x3ffc1cb0 0x4011052d:0x3ffc1cf0 0x400d7109:0x3ffc1d10 0x400d71f2:0x3ffc1d30 0x400df79a:0x3ffc1d70 0x400df845:0x3ffc1db0 0x400df7fb:0x3ffc1e00 0x400df845:0x3ffc1e40 0x400df7fb:0x3ffc1e90 0x400df845:0x3ffc1ed0 0x400dfad4:0x3ffc1f20 0x400dfcda:0x3ffc1fBacktrace: 0x400ddf6f:0x3ffc1b30 0x400de05e:0x3ffc1b80 0x400d94f5:0x3ffc1bb0 0x400d9faf:0x3ffc1c60 0x4011052d:0x3ffc1c90 0x400e7a0d:0x3ffc1cb0 0x4011052d:0x3ffc1cf0 0x400d7109:0x3ffc1d10 0x400d71f2:0x3ffc1d30 0x400df79a:0x3ffc1d70 0x400df845:0x3ffc1db0 0x400df7fb:0x3ffc1e00 0x400df845:0x3ffc1e40 0x400df7fb:0x3ffc1e90 0x400df845:0x3ffc1ed0 0x400dfad4:0x3ffc1f20 0x400dfcda:0x3ffc1f40 0x400dfe53:0x3ffc1fb0 0x400dff60:0x3ffc1fe0 0x400e012a:0x3ffc2000 0x400e54ed:0x3ffc2030 0x400e55ab:0x3ffc2050 0x400
d6783:0x3ffc2070 0x40088fb1:0x3ffc2090
0x400ddf6f: get_prop_core at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_obj_style.c:617
0x400de05e: lv_obj_get_style_prop at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_obj_style.c:229
0x400d94f5: lv_obj_get_style_border_post at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_obj_style_gen.h:267
(inlined by) lv_obj_draw at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_obj.c:529
0x400d9faf: lv_obj_event at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_obj.c:874
0x4011052d: lv_obj_event_base at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_event.c:98
0x400e7a0d: lv_label_event at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/widgets/lv_label.c:741
0x4011052d: lv_obj_event_base at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_event.c:98
0x400d7109: event_send_core at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_event.c:458
0x400d71f2: lv_event_send at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_event.c:75
0x400df79a: lv_obj_redraw at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:148 (discriminator 3)
0x400df845: refr_obj at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:974
0x400df7fb: lv_obj_redraw at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:182 (discriminator 3)
0x400df845: refr_obj at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:974
0x400df7fb: lv_obj_redraw at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:182 (discriminator 3)
0x400df845: refr_obj at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:974
0x400dfad4: refr_obj_and_children at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:856
0x400dfcda: refr_area_part at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:791
0x400dfe53: refr_area at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:680 (discriminator 2)
0x400dff60: refr_invalid_areas at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:618
0x400e012a: _lv_disp_refr_timer at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/core/lv_refr.c:325
0x400e54ed: lv_timer_exec at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/misc/lv_timer.c:313 (discriminator 2)
0x400e55ab: lv_timer_handler at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/managed_components/lvgl__lvgl/src/misc/lv_timer.c:109
0x400d6783: display_mng at D:/Projects/Embedded/ESP32/ESP-IDF/LVGL_TemperatureHumidity/main/display_mng.c:108 (discriminator 1)
0x40088fb1: vPortTaskWrapper at C:/Espressif/frameworks/esp-idf-v5.1.2/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:162
In case someone wants to build the project, I uploaded it on Drive.
Screenshot and/or video
Can anyone suggest what could be the problem?