Skip to content

Fix/esp32s2 memory allocation #259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,16 @@ For more information see: [platformio with espidf framework compability](https:/

# ESP32-S2 Support

Support for ESP32-S2 variant isn't tested, the current drivers implementation
would needs to be improved because this target available memory is less than
ESP32 targets. The menuconfig interface also would need to be improved to take
this into account.
Support for ESP32-S2 variant is Work In Progress.
Smaller displays (e.g. 320x240) work fine, but larger ones need testing.

## Background

ESP32-S2 has less on-chip SRAM than its predecessor ESP32 (520kB vs. 320kB).
This causes problems with memory allocation with large LVGL display buffers as they don't fit into the on-chip memory
and external PSRAM is not accessible by DMA.

Moreover, static allocation to external PSRAM is not yet supported
(see [GitHub issue](https://github.com/espressif/esp-idf/issues/6162)).

At this momement, the buffers are dynamicaly allocated with DMA capabilty and memory allocator handles the rest.
28 changes: 17 additions & 11 deletions main/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* LVGL Example project
*
*
* Basic project to test LVGL on ESP32 based projects.
*
* This example code is in the Public Domain (or CC0 licensed, at your option.)
Expand Down Expand Up @@ -60,7 +60,7 @@ static void create_demo_application(void);
* APPLICATION MAIN
**********************/
void app_main() {

/* If you want to use a task to create the graphic, you NEED to create a Pinned task
* Otherwise there can be problem such as memory corruption and so on.
* NOTE: When not using Wi-Fi nor Bluetooth you can pin the guiTask to core 0 */
Expand All @@ -73,20 +73,22 @@ void app_main() {
SemaphoreHandle_t xGuiSemaphore;

static void guiTask(void *pvParameter) {

(void) pvParameter;
xGuiSemaphore = xSemaphoreCreateMutex();

lv_init();

/* Initialize SPI or I2C bus used by the drivers */
lvgl_driver_init();

static lv_color_t buf1[DISP_BUF_SIZE];
lv_color_t* buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf1 != NULL);

/* Use double buffered when not working with monochrome displays */
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
static lv_color_t buf2[DISP_BUF_SIZE];
lv_color_t* buf2 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf2 != NULL);
#else
static lv_color_t *buf2 = NULL;
#endif
Expand All @@ -98,7 +100,7 @@ static void guiTask(void *pvParameter) {
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820 \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A \
|| defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D

/* Actual size in pixels, not bytes. */
size_in_px *= 8;
#endif
Expand Down Expand Up @@ -130,7 +132,7 @@ static void guiTask(void *pvParameter) {
indev_drv.type = LV_INDEV_TYPE_POINTER;
lv_indev_drv_register(&indev_drv);
#endif

/* Create and start a periodic timer interrupt to call lv_tick_inc */
const esp_timer_create_args_t periodic_timer_args = {
.callback = &lv_tick_task,
Expand All @@ -142,7 +144,7 @@ static void guiTask(void *pvParameter) {

/* Create the demo application */
create_demo_application();

while (1) {
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
vTaskDelay(pdMS_TO_TICKS(10));
Expand All @@ -155,16 +157,20 @@ static void guiTask(void *pvParameter) {
}

/* A task should NEVER return */
free(buf1);
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
free(buf2);
#endif
vTaskDelete(NULL);
}

static void create_demo_application(void)
{
/* When using a monochrome display we only show "Hello World" centered on the
/* When using a monochrome display we only show "Hello World" centered on the
* screen */
#if defined CONFIG_LV_TFT_DISPLAY_MONOCHROME || \
defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S

/* use a pretty small demo for monochrome displays */
/* Get the current screen */
lv_obj_t * scr = lv_disp_get_scr_act(NULL);
Expand Down