zephyr: MPU FAULT: Stacking error with lvgl on lv_timer_handler()
When I’m trying to use lvgl along with Zephyr, I get the following:
<err> os: ***** MPU FAULT ***** [00:00:00.433,258] <err> os: Stacking error (context area might be not valid) [00:00:00.433,258] <err> os: Data Access Violation [00:00:00.433,258] <err> os: MMFAR Address: 0x2001bd0c [00:00:00.433,288] <err> os: r0/a1: 0xe3151dd6 r1/a2: 0xc4cde9b8 r2/a3: 0x4b3693f9 [00:00:00.433,288] <err> os: r3/a4: 0x8c8fc445 r12/ip: 0xa6146c42 r14/lr: 0x1b1f6087 [00:00:00.433,319] <err> os: xpsr: 0x37422400 [00:00:00.433,319] <err> os: Faulting instruction address (r15/pc): 0xb51f27a3 [00:00:00.433,349] <err> os: >>> ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0 [00:00:00.433,380] <err> os: Current thread: 0x200004d0 (unknown) [00:00:01.606,811] <err> os: Halting system
I already tried to “play” with different CONFIG_MAIN_STACK_SIZE and CONFIG_IDLE_STACK_SIZE values with no success.
Here is the code I use to init and test the display
void view_lvgl() { // Runs in a dedicated k_thread
/* Init LVGL */
lv_init();
/* A static or global variable to store the buffers */
static lv_disp_draw_buf_t disp_buf;
/* Note: it's recommended to choose the size of the draw buffer(s) to be at least 1/10 screen sized */
static lv_color_t buf_1[SSD1333_MAX_COL * 10];
static lv_color_t buf_2[SSD1333_MAX_COL * 10];
/* Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2 */
lv_disp_draw_buf_init(&disp_buf, buf_1, buf_2, SSD1333_MAX_COL*10);
static lv_disp_drv_t disp_drv; /* A variable to hold the drivers. Must be static or global. */
lv_disp_drv_init(&disp_drv); /* Basic initialization */
disp_drv.draw_buf = &disp_buf; /* Set an initialized buffer */
disp_drv.flush_cb = lvgl_flush_cb; /* Set a flush callback to draw to the display */
disp_drv.hor_res = SSD1333_MAX_COL; /* Set the horizontal resolution in pixels */
disp_drv.ver_res = SSD1333_MAX_ROW; /* Set the vertical resolution in pixels */
lv_disp_t * disp;
disp = lv_disp_drv_register(&disp_drv); /* Register the driver and save the created display objects*/
lv_obj_t * ta = lv_textarea_create(lv_scr_act());
lv_textarea_set_one_line(ta, true);
lv_obj_align(ta, LV_ALIGN_TOP_MID, 0, 10);
lv_obj_add_state(ta, LV_STATE_FOCUSED); /*To be sure the cursor is visible*/
static const char * btnm_map[] = {"1", "2", "3", "\n",
"4", "5", "6", "\n",
"7", "8", "9", "\n",
LV_SYMBOL_BACKSPACE, "0", LV_SYMBOL_NEW_LINE, ""
};
lv_obj_t * btnm = lv_btnmatrix_create(lv_scr_act());
lv_obj_set_size(btnm, 150, 130);
lv_obj_align(btnm, LV_ALIGN_BOTTOM_MID, 0, -10);
lv_obj_clear_flag(btnm, LV_OBJ_FLAG_CLICK_FOCUSABLE); /*To keep the text area focused on button clicks */
lv_btnmatrix_set_map(btnm, btnm_map);
uint32_t x = 5;
while(1) {
// lv_tick_inc(x);
lv_timer_handler(); // <--------- Crashes here !
k_msleep(x);
}
And the vars:
CONFIG_GPIO=y
CONFIG_DEBUG_OPTIMIZATIONS=y
CONFIG_NEWLIB_LIBC=y
CONFIG_DEBUG_THREAD_INFO=y
CONFIG_THREAD_STACK_INFO=y
CONFIG_HEAP_MEM_POOL_SIZE=50512
CONFIG_IDLE_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_PRINTK=y
CONFIG_CONSOLE=y
CONFIG_RESET_ON_FATAL_ERROR=n
CONFIG_THREAD_NAME=y
# I2C
CONFIG_I2C=y
# SPI
CONFIG_SPI=y
CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS=8
CONFIG_DISPLAY=y
CONFIG_DISPLAY_LOG_LEVEL_ERR=y
CONFIG_LOG=y
CONFIG_LVGL=y
CONFIG_LV_MEM_CUSTOM=y
CONFIG_LV_USE_LOG=y
CONFIG_LV_USE_LABEL=y
CONFIG_LV_USE_BTN=y
CONFIG_LV_USE_IMG=y
CONFIG_LV_FONT_MONTSERRAT_14=y
Environment:
- OS: MacOS Monterey
- Platform: nRF52840 DK
- Toolchain nrf-connect.toolchain:2.0.2
- Zephyr hash be360e7db2
Additional context Unfortunately, there is not much about documentation on LVGL/Zephyr (https://docs.lvgl.io/master/get-started/os/zephyr.html) but I’ve seen some use case/examples without direct init call of the lvgl library but would like to use it “as is” (init on my own).
Thanks for your time !
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 15
@pdgendt I tested my driver from the
nordic/ncs/v2.0.2/zephyr/samples/drivers/display/src/main.cand was able to print the expected screenI’ll fork the zephyr repo so I can show you, meanwhile, init of the display is done before the OS as expected (init/write/…), then no further call to any of the driver’s function are done.
It seems lvgl crashes before soliciting the driver layer.
I just realized the stack size limit wasn’t enough and independent from
CONFIG_MAIN_STACK_SIZEas it runs in a k_thread… Defining the value to 4096 did the job. Can’t believe I didn’t look at this before…Thanks anyway ! Will do a PR for the driver when it’s clear and clean 😃