[nRF52840 DK] MPU FAULT: Stacking error with lvgl on lv_task_handler()

Hi,

When I'm trying to use LVGL along with Zephyr, I get the following:

[00:00:00.294,952] <err> os: ***** MPU FAULT *****
[00:00:00.294,952] <err> os:   Stacking error (context area might be not valid)
[00:00:00.294,982] <err> os:   Data Access Violation
[00:00:00.294,982] <err> os:   MMFAR Address: 0x2001c2ec
[00:00:00.295,013] <err> os: r0/a1:  0xede3fca2  r1/a2:  0xa80f657f  r2/a3:  0xc7352ee7
[00:00:00.295,013] <err> os: r3/a4:  0xa86a4f81 r12/ip:  0x24be55dd r14/lr:  0x260300df
[00:00:00.295,043] <err> os:  xpsr:  0x41000000
[00:00:00.295,043] <err> os: Faulting instruction address (r15/pc): 0x000273f6
[00:00:00.295,074] <err> os: >>> ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0
[00:00:00.295,074] <err> os: Current thread: 0x20000438 (unknown)
[00:00:01.488,098] <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 test the display

#include <lvgl.h>

void view_lvgl() { // Runs in a dedicated k_thread
    uint32_t count = 0U;
  char count_str[11] = {0};
  const struct device *display_dev;
  lv_obj_t *hello_world_label;
  lv_obj_t *count_label;

  display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
  if (!device_is_ready(display_dev)) {
    printk("Device not ready, aborting test");
    return;
  }

  if (IS_ENABLED(CONFIG_LV_Z_POINTER_KSCAN)) {
    lv_obj_t *hello_world_button;

    hello_world_button = lv_btn_create(lv_scr_act());
    lv_obj_align(hello_world_button, LV_ALIGN_CENTER, 0, 0);
    hello_world_label = lv_label_create(hello_world_button);
  } else {
    hello_world_label = lv_label_create(lv_scr_act());
  }

  lv_label_set_text(hello_world_label, "Hello world!");
  lv_obj_align(hello_world_label, LV_ALIGN_CENTER, 0, 0);

  count_label = lv_label_create(lv_scr_act());
  lv_obj_align(count_label, LV_ALIGN_BOTTOM_MID, 0, 0);

  lv_task_handler();   // <------------ Crashes here !
  display_blanking_off(display_dev);

  while (1) {
    if ((count % 100) == 0U) {
      sprintf(count_str, "%d", count/100U);
      lv_label_set_text(count_label, count_str);
    }
    lv_task_handler();
    k_sleep(K_MSEC(10));
    ++count;
  }
}

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

# USB
#CONFIG_USB=y
#CONFIG_USB_DEVICE_STACK=y
#CONFIG_USB_DEVICE_PRODUCT="DFKI zephyr SPI sample"
#CONFIG_USB_UART_CONSOLE=y
#CONFIG_USB_UART_DTR_WAIT=y

# I2C
CONFIG_I2C=n

# SPI
CONFIG_SPI=y

CONFIG_SSD1333=y

CONFIG_DISPLAY=y

CONFIG_LOG=y
CONFIG_DISPLAY_LOG_LEVEL_DBG=y

CONFIG_LVGL=y
CONFIG_LV_MEM_CUSTOM=y
CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS=8
CONFIG_LV_USE_LOG=y
CONFIG_LV_USE_LABEL=y
CONFIG_LV_USE_BTN=y
CONFIG_LV_USE_IMG=y

Please note that using the display driver alone (without LVGL) is working fine.

Any idea ?

Thanks !

Related