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

Most upvoted comments

@pdgendt I tested my driver from the nordic/ncs/v2.0.2/zephyr/samples/drivers/display/src/main.c and was able to print the expected screen

I’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_SIZE as 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 😃