From 8a2c670be45ffc74802b54cfe8c16d5e6a893695 Mon Sep 17 00:00:00 2001 From: _VIFEXTech Date: Tue, 14 Dec 2021 11:55:45 -0800 Subject: [PATCH] feat(others) add monkey test (#2885) * fix(Kconfig) remove duplicate LV_BUILD_EXAMPLES configuration * feat(refr) add reset of FPS statistics * fix(conf) mismatched macro judgment * feat(others) add monkey test Signed-off-by: FASTSHIFT Signed-off-by: pengyiqiang * fix(monkey) use lv_memset_00 to initialize monkey config * fix(monkey) random upper limit value Signed-off-by: pengyiqiang * feat(examples) add monkey test example * feat(docs) add monkey test description * feat(monkey) add user_data Signed-off-by: pengyiqiang * docs(monkey) add instructions Signed-off-by: pengyiqiang * fix(monkey) EX -> EXAMPLE Signed-off-by: pengyiqiang * feat(monkey) add comments to monkey config * docs(monkey) update usage * feat(Kconfig) add monkey test configuration * fix(monkey) rand() -> lv_rand() * feat(example) add button monkey test * docs(monkey) add button introduction Signed-off-by: FASTSHIFT * fix(monkey) obj -> monkey Signed-off-by: FASTSHIFT Co-authored-by: pengyiqiang --- Kconfig | 4 + docs/others/monkey.md | 39 ++++ examples/others/lv_example_others.h | 2 + examples/others/monkey/index.rst | 18 ++ examples/others/monkey/lv_example_monkey.h | 40 ++++ examples/others/monkey/lv_example_monkey_1.c | 18 ++ examples/others/monkey/lv_example_monkey_2.c | 25 +++ examples/others/monkey/lv_example_monkey_3.c | 33 ++++ lv_conf_template.h | 2 + src/extra/others/lv_others.h | 1 + src/extra/others/monkey/lv_monkey.c | 187 +++++++++++++++++++ src/extra/others/monkey/lv_monkey.h | 118 ++++++++++++ src/lv_conf_internal.h | 8 + 13 files changed, 495 insertions(+) create mode 100644 docs/others/monkey.md create mode 100644 examples/others/monkey/index.rst create mode 100644 examples/others/monkey/lv_example_monkey.h create mode 100644 examples/others/monkey/lv_example_monkey_1.c create mode 100644 examples/others/monkey/lv_example_monkey_2.c create mode 100644 examples/others/monkey/lv_example_monkey_3.c create mode 100755 src/extra/others/monkey/lv_monkey.c create mode 100755 src/extra/others/monkey/lv_monkey.h diff --git a/Kconfig b/Kconfig index cb3f26c86..129945847 100644 --- a/Kconfig +++ b/Kconfig @@ -914,6 +914,10 @@ menu "LVGL configuration" config LV_USE_SNAPSHOT bool "Enable API to take snapshot" default y if !LV_CONF_MINIMAL + + config LV_USE_MONKEY + bool "Enable Monkey test" + default n endmenu menu "Examples" diff --git a/docs/others/monkey.md b/docs/others/monkey.md new file mode 100644 index 000000000..fdde96d8f --- /dev/null +++ b/docs/others/monkey.md @@ -0,0 +1,39 @@ +```eval_rst +.. include:: /header.rst +:github_url: |github_link_base|/others/monkey.md +``` +# Monkey + +A simple monkey test. Use random input to stress test the application. + +## Usage + +Enable `LV_USE_MONKEY` in `lv_conf.h`. + +First configure monkey, use `lv_monkey_config_t` to define the configuration structure, set the `type` (check [input devices](/overview/indev) for the supported types), and then set the range of `period_range` and `input_range`, the monkey will output random operations at random times within this range. Call `lv_monkey_create` to create monkey. Finally call `lv_monkey_set_enable(monkey, true)` to enable monkey. + +If you want to pause the monkey, call `lv_monkey_set_enable(monkey, false)`. To delete the monkey, call `lv_monkey_del(monkey)`. + +Note that `input_range` has different meanings in different `type`: + +- `LV_INDEV_TYPE_POINTER` No effect, click randomly within the pixels of the screen resolution. +- `LV_INDEV_TYPE_ENCODER` The minimum and maximum values ​​of `enc_diff`. +- `LV_INDEV_TYPE_BUTTON` The minimum and maximum values ​​of `btn_id`. Use `lv_monkey_get_indev()` to get the input device, and use `lv_indev_set_button_points()` to map the key ID to the coordinates. +- `LV_INDEV_TYPE_KEYPAD` No effect, Send random [Keys](/overview/indev). + +## Example + +```eval_rst + +.. include:: ../../examples/others/monkey/index.rst + +``` +## API + + +```eval_rst + +.. doxygenfile:: lv_monkey.h + :project: lvgl + +``` diff --git a/examples/others/lv_example_others.h b/examples/others/lv_example_others.h index bec23c5fb..808b4c6da 100644 --- a/examples/others/lv_example_others.h +++ b/examples/others/lv_example_others.h @@ -14,6 +14,8 @@ extern "C" { * INCLUDES *********************/ #include "snapshot/lv_example_snapshot.h" +#include "monkey/lv_example_monkey.h" + /********************* * DEFINES *********************/ diff --git a/examples/others/monkey/index.rst b/examples/others/monkey/index.rst new file mode 100644 index 000000000..603df81ce --- /dev/null +++ b/examples/others/monkey/index.rst @@ -0,0 +1,18 @@ + +Touchpad monkey example +""""""""""""""""""" + +.. lv_example:: others/monkey/lv_example_monkey_1 + :language: c + +Encoder monkey example +""""""""""""""""""" + +.. lv_example:: others/monkey/lv_example_monkey_2 + :language: c + +Button monkey example +""""""""""""""""""" + +.. lv_example:: others/monkey/lv_example_monkey_3 + :language: c diff --git a/examples/others/monkey/lv_example_monkey.h b/examples/others/monkey/lv_example_monkey.h new file mode 100644 index 000000000..8475f2ede --- /dev/null +++ b/examples/others/monkey/lv_example_monkey.h @@ -0,0 +1,40 @@ +/** + * @file lv_example_monkey.h + * + */ + +#ifndef LV_EXAMPLE_MONKEY_H +#define LV_EXAMPLE_MONKEY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void lv_example_monkey_1(void); +void lv_example_monkey_2(void); +void lv_example_monkey_3(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_EXAMPLE_MONKEY_H*/ diff --git a/examples/others/monkey/lv_example_monkey_1.c b/examples/others/monkey/lv_example_monkey_1.c new file mode 100644 index 000000000..a38c6b4fa --- /dev/null +++ b/examples/others/monkey/lv_example_monkey_1.c @@ -0,0 +1,18 @@ +#include "../../lv_examples.h" +#if LV_USE_MONKEY && LV_BUILD_EXAMPLES + +void lv_example_monkey_1(void) +{ + /*Create pointer monkey test*/ + lv_monkey_config_t config; + lv_monkey_config_init(&config); + config.type = LV_INDEV_TYPE_POINTER; + config.period_range.min = 10; + config.period_range.max = 100; + lv_monkey_t * monkey = lv_monkey_create(&config); + + /*Start monkey test*/ + lv_monkey_set_enable(monkey, true); +} + +#endif diff --git a/examples/others/monkey/lv_example_monkey_2.c b/examples/others/monkey/lv_example_monkey_2.c new file mode 100644 index 000000000..c86411413 --- /dev/null +++ b/examples/others/monkey/lv_example_monkey_2.c @@ -0,0 +1,25 @@ +#include "../../lv_examples.h" +#if LV_USE_MONKEY && LV_BUILD_EXAMPLES + +void lv_example_monkey_2(void) +{ + /*Create encoder monkey test*/ + lv_monkey_config_t config; + lv_monkey_config_init(&config); + config.type = LV_INDEV_TYPE_ENCODER; + config.period_range.min = 50; + config.period_range.max = 500; + config.input_range.min = -5; + config.input_range.max = 5; + lv_monkey_t * monkey = lv_monkey_create(&config); + + /*Set the default group*/ + lv_group_t * group = lv_group_create(); + lv_indev_set_group(lv_monkey_get_indev(monkey), group); + lv_group_set_default(group); + + /*Start monkey test*/ + lv_monkey_set_enable(monkey, true); +} + +#endif diff --git a/examples/others/monkey/lv_example_monkey_3.c b/examples/others/monkey/lv_example_monkey_3.c new file mode 100644 index 000000000..c5298cc8c --- /dev/null +++ b/examples/others/monkey/lv_example_monkey_3.c @@ -0,0 +1,33 @@ +#include "../../lv_examples.h" +#if LV_USE_MONKEY && LV_BUILD_EXAMPLES + +void lv_example_monkey_3(void) +{ + static lv_point_t btn_points[3]; + lv_coord_t hor_res = LV_HOR_RES; + + /*Create button monkey test*/ + lv_monkey_config_t config; + lv_monkey_config_init(&config); + config.type = LV_INDEV_TYPE_BUTTON; + config.period_range.min = 50; + config.period_range.max = 500; + config.input_range.min = 0; + config.input_range.max = sizeof(btn_points) / sizeof(lv_point_t) - 1; + lv_monkey_t * monkey = lv_monkey_create(&config); + + /*Set the coordinates bound to the button*/ + btn_points[0].x = hor_res / 4; + btn_points[0].y = 10; + btn_points[1].x = hor_res / 2; + btn_points[1].y = 10; + btn_points[2].x = hor_res * 3 / 4; + btn_points[2].y = 10; + + lv_indev_set_button_points(lv_monkey_get_indev(monkey), btn_points); + + /*Start monkey test*/ + lv_monkey_set_enable(monkey, true); +} + +#endif diff --git a/lv_conf_template.h b/lv_conf_template.h index a19600a4e..2e0237c4b 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -608,6 +608,8 @@ /*1: Enable API to take snapshot for object*/ #define LV_USE_SNAPSHOT 1 +/*1: Enable Monkey test*/ +#define LV_USE_MONKEY 0 /*================== * EXAMPLES diff --git a/src/extra/others/lv_others.h b/src/extra/others/lv_others.h index a95727146..370ed7d45 100644 --- a/src/extra/others/lv_others.h +++ b/src/extra/others/lv_others.h @@ -14,6 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "snapshot/lv_snapshot.h" +#include "monkey/lv_monkey.h" /********************* * DEFINES diff --git a/src/extra/others/monkey/lv_monkey.c b/src/extra/others/monkey/lv_monkey.c new file mode 100755 index 000000000..6ec45e22b --- /dev/null +++ b/src/extra/others/monkey/lv_monkey.c @@ -0,0 +1,187 @@ +/** + * @file lv_monkey.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_monkey.h" + +#if LV_USE_MONKEY != 0 + +/********************* + * DEFINES + *********************/ +#define MONKEY_PERIOD_RANGE_MIN_DEF 100 +#define MONKEY_PERIOD_RANGE_MAX_DEF 1000 + +/********************** + * TYPEDEFS + **********************/ +typedef struct _lv_monkey { + lv_monkey_config_t config; + lv_indev_drv_t indev_drv; + lv_indev_data_t indev_data; + lv_indev_t * indev; + lv_timer_t * timer; +#if LV_USE_USER_DATA + void * user_data; +#endif +} lv_monkey_t; + +static const lv_key_t lv_key_map[] = { + LV_KEY_UP, + LV_KEY_DOWN, + LV_KEY_RIGHT, + LV_KEY_LEFT, + LV_KEY_ESC, + LV_KEY_DEL, + LV_KEY_BACKSPACE, + LV_KEY_ENTER, + LV_KEY_NEXT, + LV_KEY_PREV, + LV_KEY_HOME, + LV_KEY_END, +}; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_monkey_read_cb(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); +static int32_t lv_monkey_random(int32_t howsmall, int32_t howbig); +static void lv_monkey_timer_cb(lv_timer_t * timer); + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_monkey_config_init(lv_monkey_config_t * config) +{ + lv_memset_00(config, sizeof(lv_monkey_config_t)); + config->type = LV_INDEV_TYPE_POINTER; + config->period_range.min = MONKEY_PERIOD_RANGE_MIN_DEF; + config->period_range.max = MONKEY_PERIOD_RANGE_MAX_DEF; +} + +lv_monkey_t * lv_monkey_create(const lv_monkey_config_t * config) +{ + lv_monkey_t * monkey = lv_mem_alloc(sizeof(lv_monkey_t)); + LV_ASSERT_MALLOC(monkey); + + lv_memset_00(monkey, sizeof(lv_monkey_t)); + + monkey->config = *config; + + lv_indev_drv_t * drv = &monkey->indev_drv; + lv_indev_drv_init(drv); + drv->type = config->type; + drv->read_cb = lv_monkey_read_cb; + drv->user_data = monkey; + + monkey->timer = lv_timer_create(lv_monkey_timer_cb, monkey->config.period_range.min, monkey); + lv_timer_pause(monkey->timer); + + monkey->indev = lv_indev_drv_register(drv); + + return monkey; +} + +lv_indev_t * lv_monkey_get_indev(lv_monkey_t * monkey) +{ + LV_ASSERT_NULL(monkey); + return monkey->indev; +} + +void lv_monkey_set_enable(lv_monkey_t * monkey, bool en) +{ + LV_ASSERT_NULL(monkey); + en ? lv_timer_resume(monkey->timer) : lv_timer_pause(monkey->timer); +} + +bool lv_monkey_get_enable(lv_monkey_t * monkey) +{ + LV_ASSERT_NULL(monkey); + return !monkey->timer->paused; +} + +#if LV_USE_USER_DATA + +void lv_monkey_set_user_data(lv_monkey_t * monkey, void * user_data) +{ + LV_ASSERT_NULL(monkey); + monkey->user_data = user_data; +} + +void * lv_monkey_get_user_data(lv_monkey_t * monkey) +{ + LV_ASSERT_NULL(monkey); + return monkey->user_data; +} + +#endif + +void lv_monkey_del(lv_monkey_t * monkey) +{ + LV_ASSERT_NULL(monkey); + + lv_timer_del(monkey->timer); + lv_indev_delete(monkey->indev); + lv_mem_free(monkey); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_monkey_read_cb(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) +{ + lv_monkey_t * monkey = indev_drv->user_data; + + data->btn_id = monkey->indev_data.btn_id; + data->point = monkey->indev_data.point; + data->enc_diff = monkey->indev_data.enc_diff; + data->state = monkey->indev_data.state; +} + +static int32_t lv_monkey_random(int32_t howsmall, int32_t howbig) +{ + if(howsmall >= howbig) { + return howsmall; + } + int32_t diff = howbig - howsmall; + return (int32_t)lv_rand(0, diff) + howsmall; +} + +static void lv_monkey_timer_cb(lv_timer_t * timer) +{ + lv_monkey_t * monkey = timer->user_data; + lv_indev_data_t * data = &monkey->indev_data; + + switch(monkey->indev_drv.type) { + case LV_INDEV_TYPE_POINTER: + data->point.x = (lv_coord_t)lv_monkey_random(0, LV_HOR_RES - 1); + data->point.y = (lv_coord_t)lv_monkey_random(0, LV_VER_RES - 1); + break; + case LV_INDEV_TYPE_ENCODER: + data->enc_diff = (int16_t)lv_monkey_random(monkey->config.input_range.min, monkey->config.input_range.max); + break; + case LV_INDEV_TYPE_BUTTON: + data->btn_id = (uint32_t)lv_monkey_random(monkey->config.input_range.min, monkey->config.input_range.max); + break; + case LV_INDEV_TYPE_KEYPAD: { + int32_t index = lv_monkey_random(0, sizeof(lv_key_map) / sizeof(lv_key_map[0]) - 1); + data->key = lv_key_map[index]; + break; + } + default: + break; + } + + data->state = lv_monkey_random(0, 100) < 50 ? LV_INDEV_STATE_RELEASED : LV_INDEV_STATE_PRESSED; + + lv_timer_set_period(monkey->timer, lv_monkey_random(monkey->config.period_range.min, monkey->config.period_range.max)); +} + +#endif /*LV_USE_MONKEY*/ diff --git a/src/extra/others/monkey/lv_monkey.h b/src/extra/others/monkey/lv_monkey.h new file mode 100755 index 000000000..bf5e13c62 --- /dev/null +++ b/src/extra/others/monkey/lv_monkey.h @@ -0,0 +1,118 @@ +/** + * @file lv_monkey.h + * + */ +#ifndef LV_MONKEY_H +#define LV_MONKEY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lvgl.h" + +#if LV_USE_MONKEY != 0 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +struct _lv_monkey; +typedef struct _lv_monkey lv_monkey_t; + +typedef struct { + /**< Input device type*/ + lv_indev_type_t type; + + /**< Monkey execution period*/ + struct { + uint32_t min; + uint32_t max; + } period_range; + + /**< The range of input value*/ + struct { + int32_t min; + int32_t max; + } input_range; +} lv_monkey_config_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a monkey config with default values + * @param config pointer to 'lv_monkey_config_t' variable to initialize + */ +void lv_monkey_config_init(lv_monkey_config_t * config); + +/** + * Create monkey for test + * @param config pointer to 'lv_monkey_config_t' variable + * @return pointer to the created monkey + */ +lv_monkey_t * lv_monkey_create(const lv_monkey_config_t * config); + +/** + * Get monkey input device + * @param monkey pointer to a monkey + * @return pointer to the input device + */ +lv_indev_t * lv_monkey_get_indev(lv_monkey_t * monkey); + +/** + * Enable monkey + * @param monkey pointer to a monkey + * @param en set to true to enable + */ +void lv_monkey_set_enable(lv_monkey_t * monkey, bool en); + +/** + * Get whether monkey is enabled + * @param monkey pointer to a monkey + * @return return true if monkey enabled + */ +bool lv_monkey_get_enable(lv_monkey_t * monkey); + +#if LV_USE_USER_DATA + +/** + * Set the user_data field of the monkey + * @param monkey pointer to a monkey + * @param user_data pointer to the new user_data. + */ +void lv_monkey_set_user_data(lv_monkey_t * monkey, void * user_data); + +/** + * Get the user_data field of the monkey + * @param monkey pointer to a monkey + * @return the pointer to the user_data of the monkey + */ +void * lv_monkey_get_user_data(lv_monkey_t * monkey); + +#endif/*LV_USE_USER_DATA*/ + +/** + * Delete monkey + * @param monkey pointer to monkey + */ +void lv_monkey_del(lv_monkey_t * monkey); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_MONKEY*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MONKEY_H*/ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 00a122df4..8956c2bf8 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -1955,6 +1955,14 @@ #endif #endif +/*1: Enable Monkey test*/ +#ifndef LV_USE_MONKEY + #ifdef CONFIG_LV_USE_MONKEY + #define LV_USE_MONKEY CONFIG_LV_USE_MONKEY + #else + #define LV_USE_MONKEY 0 + #endif +#endif /*================== * EXAMPLES