From 14c0869e685b85a5dcd874598387e2f305024aad Mon Sep 17 00:00:00 2001 From: bjsylvia Date: Wed, 11 Oct 2023 04:28:17 +0800 Subject: [PATCH] chore(demos): add common entry for lv_demos (#4610) Signed-off-by: XiaoweiYan Signed-off-by: YanXiaowei Co-authored-by: XiaoweiYan --- demos/README.md | 63 +++++++++++++++++ demos/lv_demos.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++ demos/lv_demos.h | 12 ++++ src/lv_init.c | 19 +++-- src/lv_init.h | 6 -- 5 files changed, 268 insertions(+), 13 deletions(-) create mode 100644 demos/lv_demos.c diff --git a/demos/README.md b/demos/README.md index 434eb1faf..230243cd3 100644 --- a/demos/README.md +++ b/demos/README.md @@ -35,6 +35,18 @@ # define LV_DEMO_MUSIC_LARGE 0 # define LV_DEMO_MUSIC_AUTO_PLAY 0 #endif + +/*Flex layout demo*/ +#define LV_USE_DEMO_FLEX_LAYOUT 0 + +/*Smart-phone like multi-language demo*/ +#define LV_USE_DEMO_MULTILANG 0 + +/*Widget transformation demo*/ +#define LV_USE_DEMO_TRANSFORM 0 + +/*Demonstrate scroll settings*/ +#define LV_USE_DEMO_SCROLL 0 ... ``` @@ -48,7 +60,58 @@ ... ``` +## Configure Demos Entry +"demos/lv_demos.c" provides `lv_demos_create` and `lv_demos_usage` to simplify the creation of demos. + +If you build your main program named `lv_demos`, then you can run the widgets demo by running `lv_demos widgets` and the benchmark demo by running `lv_demos benchmark 1`. + +For example: + +```c +//! main.c +#include "lvgl.h" +#include "demos/lv_demos.h" + +... +static lv_disp_t* hal_init(void) +{ + lv_disp_t* disp = NULL; + + ... + /* TODO: init display and indev */ + ... + + return disp; +} + +int main(int argc, char ** argv) +{ + lv_init(); + + lv_disp_t* disp = hal_init(); + if (disp == NULL) { + LV_LOG_ERROR("lv_demos initialization failure!"); + return 1; + } + + if (!lv_demos_create(&argv[1], argc - 1)) { + lv_demos_usage(); + goto demo_end; + } + + while (1) { + uint32_t delay = lv_timer_handler(); + if (delay < 1) delay = 1; + usleep(delay * 1000); + } + +demo_end: + lv_deinit(); + return 0; +} + +``` ## Demos diff --git a/demos/lv_demos.c b/demos/lv_demos.c new file mode 100644 index 000000000..d2b0a395e --- /dev/null +++ b/demos/lv_demos.c @@ -0,0 +1,181 @@ +/** + * @file lv_demos.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include +#include +#include + +#include "lv_demos.h" + +/********************* + * DEFINES + *********************/ +#define DEMO_BENCHMARK_NAME "benchmark" +#define DEMO_BENCHMARK_SCENE_NAME "benchmark_scene" +#define LV_DEMOS_COUNT (sizeof(demos_entry_info) / sizeof(demo_entry_info_t) - 1) + +/********************** + * TYPEDEFS + **********************/ + +typedef void (*demo_method_cb)(void); +#if LV_USE_DEMO_BENCHMARK + typedef void (*demo_method_benchmark_cb)(lv_demo_benchmark_mode_t); + typedef void (*demo_method_benchmark_scene_cb)(lv_demo_benchmark_mode_t, uint16_t); +#endif + +typedef struct { + const char * name; + union { + demo_method_cb entry_cb; +#if LV_USE_DEMO_BENCHMARK + demo_method_benchmark_cb entry_benchmark_cb; + demo_method_benchmark_scene_cb entry_benchmark_scene_cb; +#endif + }; + int arg_count : 8; +} demo_entry_info_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static inline bool demo_is_benchmark(const demo_entry_info_t * entry) +{ + return (entry) && entry->arg_count == 1 && strcmp(entry->name, DEMO_BENCHMARK_NAME) == 0 ? true : false; +} + +static inline bool demo_is_benchmark_scene(const demo_entry_info_t * entry) +{ + return (entry) && entry->arg_count == 2 && strcmp(entry->name, DEMO_BENCHMARK_SCENE_NAME) == 0 ? true : false; +} + +/********************** + * STATIC VARIABLES + **********************/ +static const demo_entry_info_t demos_entry_info[] = { +#if LV_USE_DEMO_WIDGETS + { "widgets", .entry_cb = lv_demo_widgets }, +#endif + +#if LV_USE_DEMO_MUSIC + { "music", .entry_cb = lv_demo_music }, +#endif +#if LV_USE_DEMO_MULTILANG + { "multilang", .entry_cb = lv_demo_multilang }, +#endif + +#if LV_USE_DEMO_STRESS + { "stress", .entry_cb = lv_demo_stress }, +#endif + +#if LV_USE_DEMO_KEYPAD_AND_ENCODER + { "keypad_encoder", .entry_cb = lv_demo_keypad_encoder }, +#endif + +#if LV_USE_DEMO_FLEX_LAYOUT + { "flex_layout", .entry_cb = lv_demo_flex_layout }, +#endif + +#if LV_USE_DEMO_TRANSFORM + { "transform", .entry_cb = lv_demo_transform }, +#endif + +#if LV_USE_DEMO_SCROLL + { "scroll", .entry_cb = lv_demo_scroll }, +#endif + +#if LV_USE_DEMO_BENCHMARK + { DEMO_BENCHMARK_NAME, .entry_benchmark_cb = lv_demo_benchmark, 1 }, + { DEMO_BENCHMARK_SCENE_NAME, .entry_benchmark_scene_cb = lv_demo_benchmark_run_scene, 2 }, +#endif + { "", .entry_cb = NULL } +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +bool lv_demos_create(char * info[], int size) +{ + const int demos_count = LV_DEMOS_COUNT; + + if(demos_count <= 0) { + LV_LOG_ERROR("Please enable some lv_demos firstly!"); + return false; + } + + const demo_entry_info_t * entry_info = NULL; + if(size <= 0) { /* default: first demo*/ + entry_info = &demos_entry_info[0]; + } + + if(entry_info == NULL && info) { + const char * name = info[0]; + for(int i = 0; i < demos_count; i++) { + if(strcmp(name, demos_entry_info[i].name) == 0 && size - 1 >= demos_entry_info[i].arg_count) { + entry_info = &demos_entry_info[i]; + } + } + } + + if(entry_info == NULL) { + LV_LOG_ERROR("lv_demos create(%s) failure!", size > 0 ? info[0] : ""); + return false; + } + + if(entry_info->arg_count == 0) { + if(entry_info->entry_cb) { + entry_info->entry_cb(); + return true; + } + } +#if LV_USE_DEMO_BENCHMARK + else if(demo_is_benchmark(entry_info) && entry_info->entry_benchmark_cb) { + entry_info->entry_benchmark_cb((lv_demo_benchmark_mode_t)atoi(info[1])); + return true; + } + else if(demo_is_benchmark_scene(entry_info) && entry_info->entry_benchmark_scene_cb) { + entry_info->entry_benchmark_scene_cb((lv_demo_benchmark_mode_t)atoi(info[1]), (uint16_t)atoi(info[2])); + return true; + } +#endif + + return false; +} + +void lv_demos_show_help(void) +{ + int i; + const int demos_count = LV_DEMOS_COUNT; + + if(demos_count == 0) { + LV_LOG("lv_demos: no demo available!\n"); + return; + } + + LV_LOG("\nUsage: lv_demos demo [parameters]\n"); + LV_LOG("\ndemo list:\n"); + + for(i = 0; i < demos_count; i++) { + if(demos_entry_info[i].arg_count == 0) { + LV_LOG(" %s \n", demos_entry_info[i].name); + } + else if(demo_is_benchmark(&demos_entry_info[i])) { + LV_LOG(" %s [0, 1, 2] \t\t\t(0 for Render&Driver, 1 for Real Render, 2 for Render Only)\n", + demos_entry_info[i].name); + } + else if(demo_is_benchmark_scene(&demos_entry_info[i])) { + LV_LOG(" %s [0, 1, 2] scene_no \t(0 for Render&Driver, 1 for Real Render, 2 for Render Only)\n", + demos_entry_info[i].name); + } + } +} diff --git a/demos/lv_demos.h b/demos/lv_demos.h index 4406ac773..9d45e6324 100644 --- a/demos/lv_demos.h +++ b/demos/lv_demos.h @@ -63,6 +63,18 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ +/** + * Call lv_demo_xxx. + * @param info the information which contains demo name and parameters + * needs by lv_demo_xxx. + * @size size of information. + */ +bool lv_demos_create(char * info[], int size); + +/** + * Show help for lv_demos. + */ +void lv_demos_show_help(void); /********************** * MACROS diff --git a/src/lv_init.c b/src/lv_init.c index 6636b60f3..983a0057f 100644 --- a/src/lv_init.c +++ b/src/lv_init.c @@ -267,10 +267,15 @@ void lv_init(void) LV_LOG_TRACE("finished"); } -#if LV_ENABLE_GLOBAL_CUSTOM || LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN - void lv_deinit(void) { + /*Do nothing if already deinit*/ + if(!lv_initialized) { + LV_LOG_WARN("lv_deinit: already deinit!"); + return; + } +#if LV_ENABLE_GLOBAL_CUSTOM || LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN + #if LV_USE_SYSMON _lv_sysmon_builtin_deinit(); #endif @@ -299,10 +304,6 @@ void lv_deinit(void) lv_mem_deinit(); - lv_initialized = false; - - LV_LOG_INFO("lv_deinit done"); - #if LV_USE_LOG lv_log_register_print_cb(NULL); #endif @@ -310,9 +311,13 @@ void lv_deinit(void) #if LV_USE_OBJ_ID_BUILTIN lv_objid_builtin_destroy(); #endif -} #endif + lv_initialized = false; + + LV_LOG_INFO("lv_deinit done"); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_init.h b/src/lv_init.h index 7359e989c..8ac69702c 100644 --- a/src/lv_init.h +++ b/src/lv_init.h @@ -35,17 +35,11 @@ extern "C" { void lv_init(void); -#if LV_ENABLE_GLOBAL_CUSTOM || LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN - /** * Deinit the 'lv' library - * Currently only implemented when not using custom allocators, - * or using custom 'lv_global'. */ void lv_deinit(void); -#endif - /** * Returns whether the 'lv' library is currently initialized */