diff --git a/Kconfig b/Kconfig index 9e2c46091..bd532bdc0 100644 --- a/Kconfig +++ b/Kconfig @@ -1768,6 +1768,11 @@ menu "LVGL configuration" bool "Use Nuttx to open window and handle touchscreen" default n + config LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP + bool "Use independent image heap" + depends on LV_USE_NUTTX + default n + config LV_USE_NUTTX_LIBUV bool "Use uv loop to replace default timer loop and other fb/indev timers" depends on LV_USE_NUTTX diff --git a/docs/integration/os/nuttx.rst b/docs/integration/os/nuttx.rst index 089097ecc..2e3c65371 100644 --- a/docs/integration/os/nuttx.rst +++ b/docs/integration/os/nuttx.rst @@ -137,6 +137,14 @@ Reset the board and using the 'NSH>' terminal start the LVGL demo: nsh> lvgldemo +Configurations +-------------- +Here are some configurations that you can use to customize your NuttX and LVGL setup: + +- **LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP** - You can enable or disable the + LVGL image heap in NuttX. By default, it is disabled. If you enable + it, LVGL will use the NuttX heap instead. + Where can I find more information? ---------------------------------- diff --git a/lv_conf_template.h b/lv_conf_template.h index 66193d8f8..9b0424a46 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -1105,6 +1105,8 @@ #define LV_USE_NUTTX 0 #if LV_USE_NUTTX + #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP 0 + #define LV_USE_NUTTX_LIBUV 0 /** Use Nuttx custom init API to open window and handle touchscreen */ diff --git a/src/drivers/nuttx/lv_nuttx_entry.c b/src/drivers/nuttx/lv_nuttx_entry.c index 3f9283f07..078e3fe35 100644 --- a/src/drivers/nuttx/lv_nuttx_entry.c +++ b/src/drivers/nuttx/lv_nuttx_entry.c @@ -122,7 +122,7 @@ void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result) lv_nuttx_cache_init(); - lv_nuttx_image_cache_init(); + lv_nuttx_image_cache_init(LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP); #if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN lv_nuttx_profiler_init(); diff --git a/src/drivers/nuttx/lv_nuttx_image_cache.c b/src/drivers/nuttx/lv_nuttx_image_cache.c index 964c67849..842a1a227 100644 --- a/src/drivers/nuttx/lv_nuttx_image_cache.c +++ b/src/drivers/nuttx/lv_nuttx_image_cache.c @@ -40,6 +40,10 @@ typedef struct { uint32_t heap_size; bool initialized; + bool independent_image_heap; + + lv_draw_buf_malloc_cb malloc_cb; + lv_draw_buf_free_cb free_cb; } lv_nuttx_ctx_image_cache_t; /********************** * STATIC PROTOTYPES @@ -60,7 +64,7 @@ static void free_cb(void * draw_buf); * GLOBAL FUNCTIONS **********************/ -void lv_nuttx_image_cache_init(void) +void lv_nuttx_image_cache_init(bool use_independent_image_heap) { lv_draw_buf_handlers_t * handlers = image_cache_draw_buf_handlers; handlers->buf_malloc_cb = malloc_cb; @@ -69,17 +73,28 @@ void lv_nuttx_image_cache_init(void) ctx = lv_malloc_zeroed(sizeof(lv_nuttx_ctx_image_cache_t)); LV_ASSERT_MALLOC(ctx); + ctx->malloc_cb = handlers->buf_malloc_cb; + ctx->free_cb = handlers->buf_free_cb; + + handlers->buf_malloc_cb = malloc_cb; + handlers->buf_free_cb = free_cb; + ctx->initialized = false; + ctx->independent_image_heap = use_independent_image_heap; } void lv_nuttx_image_cache_deinit(void) { + if(ctx->independent_image_heap == false) goto FREE_CONTEXT; if(ctx->initialized == false) goto FREE_CONTEXT; mm_uninitialize(ctx->heap); free(ctx->mem); FREE_CONTEXT: + lv_draw_buf_handlers_t * handlers = image_cache_draw_buf_handlers; + handlers->buf_malloc_cb = ctx->malloc_cb; + handlers->buf_free_cb = ctx->free_cb; lv_free(ctx); ctx = NULL; @@ -152,8 +167,7 @@ static void heap_memdump(struct mm_heap_s * heap) static void * malloc_cb(size_t size_bytes, lv_color_format_t color_format) { LV_UNUSED(color_format); - - if(ctx->initialized == false) { + if(ctx->independent_image_heap == true && ctx->initialized == false) { if(defer_init() == false) return NULL; } @@ -161,7 +175,7 @@ static void * malloc_cb(size_t size_bytes, lv_color_format_t color_format) size_bytes += LV_DRAW_BUF_ALIGN - 1; uint32_t cache_max_size = lv_cache_get_max_size(img_cache_p, NULL); - if(size_bytes > cache_max_size) { + if(lv_cache_is_enabled(img_cache_p) && size_bytes > cache_max_size) { LV_LOG_ERROR("data size (%" LV_PRIu32 ") is larger than max size (%" LV_PRIu32 ")", (uint32_t)size_bytes, cache_max_size); @@ -169,7 +183,13 @@ static void * malloc_cb(size_t size_bytes, lv_color_format_t color_format) } while(1) { - void * mem = mm_malloc(ctx->heap, size_bytes); + void * mem = NULL; + if(ctx->independent_image_heap) { + mem = mm_malloc(ctx->heap, size_bytes); + } + else if((!lv_cache_is_enabled(img_cache_p)) || (lv_cache_get_size(img_cache_p, NULL) + size_bytes < cache_max_size)) { + mem = ctx->malloc_cb(size_bytes, color_format); + } if(mem) return mem; LV_LOG_INFO("appears to be out of memory. attempting to evict one cache entry. with allocated size %" LV_PRIu32, (uint32_t)size_bytes); @@ -184,7 +204,12 @@ static void * malloc_cb(size_t size_bytes, lv_color_format_t color_format) static void free_cb(void * draw_buf) { - mm_free(ctx->heap, draw_buf); + if(ctx->independent_image_heap == true) { + mm_free(ctx->heap, draw_buf); + } + else { + ctx->free_cb(draw_buf); + } } #endif /* LV_USE_NUTTX */ diff --git a/src/drivers/nuttx/lv_nuttx_image_cache.h b/src/drivers/nuttx/lv_nuttx_image_cache.h index 105779fa6..0e056b4ab 100644 --- a/src/drivers/nuttx/lv_nuttx_image_cache.h +++ b/src/drivers/nuttx/lv_nuttx_image_cache.h @@ -15,6 +15,7 @@ extern "C" { *********************/ #include "../../lv_conf_internal.h" +#include LV_STDBOOL_INCLUDE /********************* * DEFINES @@ -28,7 +29,7 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -void lv_nuttx_image_cache_init(void); +void lv_nuttx_image_cache_init(bool use_independent_image_heap); void lv_nuttx_image_cache_deinit(void); diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 1bbd365e5..89ffb7b12 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -3574,6 +3574,14 @@ #endif #if LV_USE_NUTTX + #ifndef LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP + #ifdef CONFIG_LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP + #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP CONFIG_LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP + #else + #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP 0 + #endif + #endif + #ifndef LV_USE_NUTTX_LIBUV #ifdef CONFIG_LV_USE_NUTTX_LIBUV #define LV_USE_NUTTX_LIBUV CONFIG_LV_USE_NUTTX_LIBUV