nRF5340DK ILI9341 Display Secure Fault for LVGL Draw Function

Hi DevZone Community

I'm trying to get a simple Hello World sample to run on an nRF5340DK board with a 2.8" ILI9341 based TFT display that has Arduino headers attached (https://www.buydisplay.com/arduino-ips-2-8-inch-tft-touch-shield-example-ili9341-for-mega-due-uno). I originally used this display with an Arduino Mega to get an LVGL example up and running and test the connections, now I want to get this up and running within the Nordic environment.

I'm using VS Code (nRF Connect Extenstion, nRF Connect SDK V3.0.2).

I managed to get the basic Hello World program to compile and I can see a grey block drawn on the display, but not the Hello World label and then I run into a Secure Fault, with addr2line indicating that the fault originates from /opt/nordic/ncs/v3.0.2/modules/lib/gui/lvgl/src/draw/lv_draw.c:94

I'm not sure what I'm missing or why the lv_draw function causes the secure fault error or if this could be caused by the wrong config in my project.

I will show the full error below and include my overlay file, project config and the main.c source code.

Any help would be greatly appreciated.

Kind regards,
Charl


*** Booting MCUboot v2.1.0-dev-ae1ee57f3906 ***
*** Using nRF Connect SDK v3.0.2-89ba1294ac9b ***
*** Using Zephyr OS v4.0.99-f791c49f492c ***
I: Starting bootloader
I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
I: Boot source: none
I: Image index: 0, Swap type: none
I: Bootloader chainload address offset: 0xc000
I: Image version: v3.0.2
�[00:00:00.011,749] <dbg> display_ili9xxx: ili9xxx_display_blanking_on: Turning display blanking on
[00:00:00.011,993] <dbg> display_ili9341: ili9341_regs_init: PWSEQCTRL
55 01 23 01 |U.#.
[00:00:00.012,145] <dbg> display_ili9341: ili9341_regs_init: TIMCTRLA
84 11 7a |..z
[00:00:00.012,268] <dbg> display_ili9341: ili9341_regs_init: TIMCTRLB
00 00 |..
[00:00:00.012,420] <dbg> display_ili9341: ili9341_regs_init: PUMPRATIOCTRL
10 |.
[00:00:00.012,542] <dbg> display_ili9341: ili9341_regs_init: PWCTRLA
39 2c 00 34 02 |9,.4.
[00:00:00.012,664] <dbg> display_ili9341: ili9341_regs_init: PWCTRLB
00 8b 30 |..0
[00:00:00.012,817] <dbg> display_ili9341: ili9341_regs_init: GAMSET
01 |.
[00:00:00.012,908] <dbg> display_ili9341: ili9341_regs_init: FRMCTR1
00 1b |..
[00:00:00.013,061] <dbg> display_ili9341: ili9341_regs_init: DISCTRL
0a 82 27 04 |..'.
[00:00:00.013,214] <dbg> display_ili9341: ili9341_regs_init: PWCTRL1
21 |!
[00:00:00.013,336] <dbg> display_ili9341: ili9341_regs_init: PWCTRL2
10 |.
[00:00:00.013,427] <dbg> display_ili9341: ili9341_regs_init: VMCTRL1
31 3c |1<
[00:00:00.013,580] <dbg> display_ili9341: ili9341_regs_init: VMCTRL2
c0 |.
[00:00:00.013,671] <dbg> display_ili9341: ili9341_regs_init: PGAMCTRL
0f 22 1f 0a 0e 06 4d 76 3b 03 0e 04 13 0e 0c |."....Mv ;......
[00:00:00.013,854] <dbg> di[00:00:00.014,038] <dbg> display_ili9341: ili9341_regs_init: ENABLE3G
02 |.
[00:00:00.014,129] <dbg> display_ili9341: ili9341_regs_init: IFMODE
40 |@
[00:00:00.014,221] <dbg> display_ili9341: ili9341_regs_init: IFCTL
01 00 00 |...
[00:00:00.014,373] <dbg> display_ili9341: ili9341_regs_init: ETMOD
06 |.
*** Booting My Application v3.0.2-ebefab8b5d15 ***
*** Using nRF Connect SDK v3.0.2-89ba1294ac9b ***
*** Using Zephyr OS v4.0.99-f791c49f492c ***
[00:00:00.135,620] <dbg> app: main: Display Hello World! nrf5340dk (3.0.2+0)
[00:00:00.135,650] <dbg> app: display_manager_init: Initializing display manager
[00:00:00.135,681] <dbg> app: display_manager_init: Display name: ili9341@0
[00:00:00.135,681] <dbg> display_ili9xxx: ili9xxx_display_blanking_off: Turning display blanking off
[00:00:00.138,916] <dbg> display_ili9xxx: ili9xxx_write: Writing 320x48 (w,h) @ 0x0 (x,y)
[00:00:00.201,232] <dbg> display_ili9xxx: ili9xxx_write: Writing 320x48 (w,h) @ 0x48 (x,y)
[00:00:00.266,021] <err> os: ***** SECURE FAULT *****
[00:00:00.266,021] <err> os: Address: 0x8
[00:00:00.266,052] <err> os: Attribution unit violation
[00:00:00.266,052] <err> os: r0/a1: 0x00000074 r1/a2: 0x00000074 r2/a3: 0x000000cb
[00:00:00.266,082] <err> os: r3/a4: 0x0000007c r12/ip: 0x20008e94 r14/lr: 0x00025229
[00:00:00.266,082] <err> os: xpsr: 0x01000000
[00:00:00.266,082] <err> os: Faulting instruction address (r15/pc): 0x0002c36a
[00:00:00.266,113] <err> os: >>> ZEPHYR FATAL ERROR 41: Unknown error on CPU 0
[00:00:00.266,143] <err> os: Current thread: 0x20008f80 (main)



#include <zephyr/dt-bindings/mipi_dbi/mipi_dbi.h>
#include <zephyr/dt-bindings/display/ili9xxx.h>

/ {
	chosen {
		zephyr,display = &ili9341;
	};

    mipi_dbi {
        compatible = "zephyr,mipi-dbi-spi";
        spi-dev = <&arduino_spi>;
		dc-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
		reset-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
        #address-cells = <1>;
        #size-cells = <0>;
        write-only;

        ili9341: ili9341@0 {
            status = "okay";
            compatible = "ilitek,ili9341";
            mipi-max-frequency = <5625000>;
            reg = <0>;
            width = <240>;
            height = <320>;
            rotation = <270>;
            pixel-format = <ILI9XXX_PIXEL_FORMAT_RGB565>;
            mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE";
        };
    };
};

&arduino_spi {
	status = "okay";
	cs-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};

# Increased heap for LVGL and display driver stability
CONFIG_HEAP_MEM_POOL_SIZE=131072
CONFIG_MAIN_STACK_SIZE=16384

# Enable logging
CONFIG_LOG=y

# Display stack
CONFIG_DISPLAY=y
CONFIG_DISPLAY_LOG_LEVEL_DBG=y
CONFIG_SPI=y
CONFIG_GPIO=y
CONFIG_MIPI_DBI=y
CONFIG_MIPI_DBI_SPI=y
CONFIG_ILI9341=y

# LVGL integration
CONFIG_LVGL=y
CONFIG_LV_CONF_SKIP=y
CONFIG_LV_CONF_MINIMAL=y
CONFIG_LV_USE_BUILTIN_MALLOC=y

# LVGL Feature Configuration
CONFIG_LV_COLOR_DEPTH_16=y
CONFIG_LV_FONT_MONTSERRAT_16=y
CONFIG_LV_USE_LABEL=y

# LVGL Logging
CONFIG_LV_USE_LOG=y
CONFIG_LV_LOG_LEVEL_ERROR=y

# Coredump configuration for debugging faults
CONFIG_DEBUG_COREDUMP=y
CONFIG_DEBUG_COREDUMP_BACKEND_LOGGING=y
CONFIG_RESET_ON_FATAL_ERROR=n
CONFIG_ASSERT=y
CONFIG_SYS_HEAP_VALIDATE=y
CONFIG_SYS_HEAP_RUNTIME_STATS=y
CONFIG_THREAD_NAME=y

/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/gpio.h>
#include <soc.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/spi.h>
#include <lvgl.h>
#include <app_version.h>
#include <zephyr/drivers/display.h>
#include <zephyr/debug/coredump.h>

LOG_MODULE_REGISTER(app, LOG_LEVEL_DBG);

static const struct device *display_dev  = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));

static int display_manager_init(void) 
{
    LOG_DBG("Initializing display manager");

	if (!device_is_ready(display_dev)) {
		LOG_ERR("Device not ready, aborting test");
		return -1;
	}

	LOG_DBG("Display name: %s", display_dev->name);

    display_blanking_off(display_dev);
    
    return 0;
}

int main(void)
{
	LOG_DBG("Display Hello World! %s (%s)", CONFIG_BOARD, APP_VERSION_EXTENDED_STRING);

	display_manager_init();

	lv_init();

    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello World");
    lv_obj_center(label);

	for (;;) {
		lv_timer_handler();
		k_msleep(10);
	}
}

Parents
  • Hi Charl,

    secure fault in the main thread context could be a stack overflow in main. Could be as simple as increasing the CONFIG_MAIN_STACK_SIZE.

    Could be as hard as trying to find that instruction in main that might be doing illegal instruction like dereferencing a null pointer or diving something by zero.

    First try increasing the stack sizes and see if that helps, if it does not help, we need to look into the faulting instruction at (r15/pc): 0x0002c36a and see what context was executing.

Reply
  • Hi Charl,

    secure fault in the main thread context could be a stack overflow in main. Could be as simple as increasing the CONFIG_MAIN_STACK_SIZE.

    Could be as hard as trying to find that instruction in main that might be doing illegal instruction like dereferencing a null pointer or diving something by zero.

    First try increasing the stack sizes and see if that helps, if it does not help, we need to look into the faulting instruction at (r15/pc): 0x0002c36a and see what context was executing.

Children
  • Hi!

    I already increased the CONFIG_MAIN_STACK_SIZE from 8196 to the 16384 in the attached prj.conf file and it made no difference to the error.

    The addr2line tool revealed that the error stemmed from line 94 in the lv_draw.c file as mentioned above.

    I added the following to the prj.conf and the error is gone now as it seems like it was memory related in terms of the LVGL library. I will still try to figure out why it was an issue, but at least the error is gone now.

    CONFIG_LV_Z_MEM_POOL_SIZE=16384

     

  • Hardfault due to smaller than needed CONFIG_LV_Z_MEM_POOL_SIZE means two things

    1. The application is using more mem pool than it thinks it does.
    2. The application/lv_library is not handling the error from functions that replies with an error code saying that the required memory cannot be allocated from the mem pool as it is already being fully used.

    You have fixed 1. 

    But review your code to check for errors as mentioned in 2. 

Related