I have been running the project code on my device quite successfully using TFT_eSPI and freeRTOS.
Simple code for this:
#include <Arduino.h> // include freeRTOS also
#include <TFT_eSPI.h> // Library for TFT display
TFT_eSPI tft = TFT_eSPI(); // Create object for the display
const int SCREEN_WIDTH = 360;
const int SCREEN_HEIGHT = 360;
float angle = 0.0; // Global variable for the rotation angle
// Function to draw the line
void drawLine(void *pvParameters) {
while (true) {
tft.fillScreen(TFT_BROWN); // Brown background
// Center and length of the line
int centerX = SCREEN_WIDTH / 2;
int centerY = SCREEN_HEIGHT / 2;
int length = 100;
// Coordinates of the line's endpoints
int x1 = centerX + cos(angle) * length / 2;
int y1 = centerY + sin(angle) * length / 2;
int x2 = centerX - cos(angle) * length / 2;
int y2 = centerY - sin(angle) * length / 2;
tft.drawLine(x1, y1, x2, y2, TFT_WHITE); // Draw the line
vTaskDelay(20 / portTICK_PERIOD_MS); // Delay for frame rate
}
}
// Function to rotate the line
void rotateLine(void *pvParameters) {
while (true) {
angle += 0.05; // Update angle
if (angle >= 2 * PI) angle -= 2 * PI; // Limit angle
vTaskDelay(20 / portTICK_PERIOD_MS); // Delay for update rate
}
}
void setup() {
tft.init();
tft.setRotation(1); // Set display orientation
tft.fillScreen(TFT_BROWN); // Brown background
// Create tasks for drawing and rotating
xTaskCreate(drawLine, "Draw Line", 2048, NULL, 1, NULL);
// xTaskCreate(rotateLine, "Rotate Line", 2048, NULL, 1, NULL);
xTaskCreatePinnedToCore(rotateLine, "Rotate Line", 2048, NULL, 1, &rotateTask, 0); // Pin to core 0
}
void loop() {
// Main loop is empty
}
As you can see from this simple code, you can run two tasks on two cores that is assigned to esp32s3 by default, using the flag
"extra_flags": [
"-DARDUINO_RUNNING_CORE=1",
],
in the board settings file
board = esp32-s3-devkitc-1-n16r8
Now I want to do a similar procedure with the library LVGL 9.3, the code for a simple example in this case is:
#include "Arduino.h"
#include <lvgl.h>
#include <Arduino_GFX_Library.h>
Arduino_DataBus *bus = new Arduino_ESP32QSPI(
10 /* CS */, 9 /* SCK */, 11 /* D0 - mosi */, 12 /* D1 - miso */, 13 /* D2 - quadwp */, 14 /* D3 - quadhd */);
Arduino_GFX *gfx = new Arduino_ST77916(bus, 47 /* RST */, 0 /* rotation */, true /* IPS */, 360 /* width */, 360 /* height */);
// Global variables for angle and display settings
float angle = 0.0;
const int SCREEN_WIDTH = 480;
const int SCREEN_HEIGHT = 320;
// Backlight PIN
#define GFX_BL 15
uint32_t screenWidth;
uint32_t screenHeight;
uint32_t drawBufSize;
lv_display_t *disp;
lv_obj_t * canvas;
uint32_t millis_cb(void)
{
return millis();
}
void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) // LVGL 9.3
{
uint32_t w = lv_area_get_width(area);
uint32_t h = lv_area_get_height(area);
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)px_map, w, h); // LVGL 9.3
/*Call it to tell LVGL you are ready*/
lv_disp_flush_ready(disp);
}
#define CANVAS_WIDTH 50
#define CANVAS_HEIGHT 50
// Function to create a rotating line
void drawLine(lv_obj_t *canvas) {
/*Create a buffer for the canvas*/
LV_DRAW_BUF_DEFINE_STATIC(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);
LV_DRAW_BUF_INIT_STATIC(draw_buf);
/*Create a canvas and initialize its palette*/
canvas = lv_canvas_create(lv_screen_active());
lv_canvas_set_draw_buf(canvas, &draw_buf);
lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);
lv_obj_center(canvas);
lv_layer_t layer;
lv_canvas_init_layer(canvas, &layer);
lv_draw_line_dsc_t dsc;
lv_draw_line_dsc_init(&dsc);
dsc.color = lv_palette_main(LV_PALETTE_RED);
dsc.width = 4;
dsc.round_end = 1;
dsc.round_start = 1;
dsc.p1.x = 15;
dsc.p1.y = 15;
dsc.p2.x = 35;
dsc.p2.y = 10;
lv_draw_line(&layer, &dsc);
lv_canvas_finish_layer(canvas, &layer);
}
// Task to update the rotation angle
void rotateLine(void *pvParameters) {
// lv_obj_t *canvas = (lv_obj_t *)pvParameters; // Get the canvas object
while (true) {
angle += 0.05; // Increment the angle
if (angle >= 2 * M_PI) angle -= 2 * M_PI; // Wrap around angle
drawLine(canvas); // Call function to draw the line
vTaskDelay(20 / portTICK_PERIOD_MS); // Delay for update rate
}
}
void setup() {
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_YELLOW);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
lv_init(); // Initialize LVGL
/*Set a tick source so that LVGL will know how much time elapsed. */
lv_tick_set_cb(millis_cb);
screenWidth = gfx->width();
screenHeight = gfx->height();
drawBufSize = screenWidth * screenHeight;
disp = lv_display_create(screenWidth, screenHeight);
lv_display_set_flush_cb(disp, my_disp_flush);
static void* buf1 = (lv_color_t*)heap_caps_malloc(drawBufSize, MALLOC_CAP_SPIRAM);
static void* buf2 = (lv_color_t*)heap_caps_malloc(drawBufSize, MALLOC_CAP_SPIRAM);
lv_display_set_buffers(disp, buf1, buf2, drawBufSize, LV_DISPLAY_RENDER_MODE_PARTIAL);
// Create a canvas object for drawing
// lv_obj_t *canvas = lv_canvas_create(lv_scr_act()); // No work
lv_obj_t *canvas = lv_canvas_create( lv_screen_active()); // Work
lv_obj_set_size(canvas, SCREEN_WIDTH, SCREEN_HEIGHT); // Set canvas size
lv_obj_align(canvas, LV_ALIGN_CENTER, 0, 0); // Center the canvas
// Create task for rotating line
xTaskCreatePinnedToCore(rotateLine, "Rotate Line", 4096, NULL, 1, NULL, 0); // Pin to core 0
}
void loop() {
lv_task_handler(); // Handle LVGL tasks
vTaskDelay(5 / portTICK_PERIOD_MS); // Small delay
}
Platformio.ini here
build_flags =
-D LV_CONF_SKIP
-D LV_CONF_INCLUDE_SIMPLE
-D LV_USE_SYSMON=1
-D LV_USE_PERF_MONITOR=1
-D LV_USE_PERF_MONITOR_POS="LV_ALIGN_BOTTOM_MID"
-D LV_USE_LOG=1
-D LV_MEM_SIZE="(128U * 1024U)"
-D LV_USE_FREERTOS_TASK_NOTIFY=1
-D LV_DEF_REFR_PERIOD=5
The code compiles and loads into the device fine, but the result is only a yellow screen:
gfx->fillScreen(RGB565_YELLOW);
If I uncomment the line from the Setup section:
lv_obj_t *canvas = lv_canvas_create(lv_screen_active()); // Create canvas
The device will load the image, but there are no rotations and the device will reboot.
ELF file SHA256: 23b901996f8eec9f
Rebooting…
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0xb (SPI_FAST_FLASH_BOOT)
Saved PC:0x40377834
#0 0x40377834 in esp_restart_noos at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/port/soc/esp32s3/system_internal.c:151 (discriminator 1)SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x4bc
load:0x403c9700,len:0xbd8
load:0x403cc700,len:0x2a0c
entry 0x403c98d0
E (11933) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (11933) task_wdt: - IDLE0 (CPU 0)
E (11933) task_wdt: Tasks currently running:
E (11933) task_wdt: CPU 0: Rotate Line
E (11933) task_wdt: CPU 1: loopTask
E (11933) task_wdt: Aborting.abort() was called at PC 0x4204463c on core 0
#0 0x4204463c in task_wdt_isr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/task_wdt.c:176 (discriminator 3)Backtrace: 0x40377bfe:0x3fc94c50 0x4037b339:0x3fc94c70 0x40381a45:0x3fc94c90 0x4204463c:0x3fc94d10 0x40378e41:0x3fc94d30 0x4205d8b8:0x3fced190 0x4201274f:0x3fced1b0 0x4201293e:0x3fced1e0 0x42011aa8:0x3fced200 0x42012b2e:0x3fced220 0x42023e50:0x3fced240 0x42018419:0x3fced270 0x420019a1:0x3fced290 0x42001a81:0x3fced360
#0 0x40377bfe in panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c:408
#1 0x3fc94c50 in port_IntStack at ??:?
#2 0x4037b339 in esp_system_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/esp_system.c:137
#3 0x3fc94c70 in port_IntStack at ??:?
#4 0x40381a45 in abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/abort.c:46
#5 0x3fc94c90 in port_IntStack at ??:?
#6 0x4204463c in task_wdt_isr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/task_wdt.c:176 (discriminator 3)
#7 0x3fc94d10 in port_IntStack at ??:?
#8 0x40378e41 in _xt_lowint1 at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port/xtensa/xtensa_vectors.S:1118
#9 0x3fc94d30 in port_IntStack at ??:?
#10 0x4205d8b8 in lv_assert_handler at lib/lvgl/src/misc/lv_assert.c:37
#11 0x4201274f in block_locate_free at lib/lvgl/src/stdlib/builtin/lv_tlsf.c:774
(inlined by) block_locate_free at lib/lvgl/src/stdlib/builtin/lv_tlsf.c:754
#12 0x4201293e in lv_tlsf_malloc at lib/lvgl/src/stdlib/builtin/lv_tlsf.c:1101
#13 0x42011aa8 in lv_malloc_core at lib/lvgl/src/stdlib/builtin/lv_mem_core_builtin.c:144
#14 0x42012b2e in lv_malloc_zeroed at lib/lvgl/src/stdlib/lv_mem.c:100
(inlined by) lv_malloc_zeroed at lib/lvgl/src/stdlib/lv_mem.c:92
#15 0x42023e50 in lv_obj_class_create_obj at lib/lvgl/src/core/lv_obj_class.c:51
#16 0x42018419 in lv_canvas_create at lib/lvgl/src/widgets/canvas/lv_canvas.c:62
#17 0x420019a1 in drawLine(_lv_obj_t*) at src/RTOS_LVGL_9_simple.cpp:59
#18 0x42001a81 in rotateLine(void*) at src/RTOS_LVGL_9_simple.cpp:90
Unfortunately, I didn’t see any examples of lvgl + freeRTOS in the repository
or any working examples on the Internet ![]()

