This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit beeec27afda9df6b37b7827a4ff2d8d8563607a4 Author: raiden00pl <raide...@railab.me> AuthorDate: Fri Sep 20 18:46:43 2024 +0200 examples/foc: improve perf monitor improve FOC perf monitor: - add options to choose when perf result should be printed - measure the controller thread call period --- examples/foc/Kconfig | 18 +++++++ examples/foc/foc_device.c | 6 +++ examples/foc/foc_fixed16_thr.c | 13 +++-- examples/foc/foc_float_thr.c | 13 +++-- examples/foc/foc_perf.c | 110 ++++++++++++++++++++++++++++++++++++++--- examples/foc/foc_perf.h | 41 +++++++++++---- 6 files changed, 172 insertions(+), 29 deletions(-) diff --git a/examples/foc/Kconfig b/examples/foc/Kconfig index c2bc7e07f..285870259 100644 --- a/examples/foc/Kconfig +++ b/examples/foc/Kconfig @@ -47,6 +47,24 @@ config EXAMPLES_FOC_PERF bool "Enable performance meassurements" default n +if EXAMPLES_FOC_PERF + +config EXAMPLES_FOC_PERF_LIVE + bool "Print FOC perf results on each max value change" + default n + ---help--- + With this option perf results are printed every time the maximum value + changes. The disadvantage of this method is that printing can directly + affect the pref result but it gives results in real time. + +config EXAMPLES_FOC_PERF_EXIT + bool "Print FOC perf results on thread exit" + default y + ---help--- + With this option perf results are printed on control thread exit. + +endif # EXAMPLES_FOC_PERF + choice prompt "FOC modulation selection" default EXAMPLES_FOC_MODULATION_SVM3 diff --git a/examples/foc/foc_device.c b/examples/foc/foc_device.c index 5c39315be..e4075f1c4 100644 --- a/examples/foc/foc_device.c +++ b/examples/foc/foc_device.c @@ -209,6 +209,12 @@ int foc_dev_params_set(FAR struct foc_device_s *dev) foc_perf_end(&dev->perf); #endif +#ifdef CONFIG_EXAMPLES_FOC_PERF_LIVE + /* Print perf live stats */ + + foc_perf_live(&dev->perf); +#endif + errout: return ret; } diff --git a/examples/foc/foc_fixed16_thr.c b/examples/foc/foc_fixed16_thr.c index 6c5efe6a4..716cee3ff 100644 --- a/examples/foc/foc_fixed16_thr.c +++ b/examples/foc/foc_fixed16_thr.c @@ -503,13 +503,6 @@ int foc_fixed16_thr(FAR struct foc_ctrl_env_s *envp) /* Increase counter */ motor.time += 1; - -#ifdef CONFIG_EXAMPLES_FOC_PERF - if (dev.perf.max_changed) - { - PRINTF_PERF("max=%" PRId32 "\n", dev.perf.max); - } -#endif } errout: @@ -532,6 +525,12 @@ errout: PRINTF("ERROR: foc_device_deinit %d failed %d\n", envp->id, ret); } +#ifdef CONFIG_EXAMPLES_FOC_PERF_EXIT + /* Print final perf stats */ + + foc_perf_exit(&dev.perf); +#endif + PRINTF("foc_fixed16_thr %d exit\n", envp->id); return ret; diff --git a/examples/foc/foc_float_thr.c b/examples/foc/foc_float_thr.c index 05b4201ff..4fae5ba76 100644 --- a/examples/foc/foc_float_thr.c +++ b/examples/foc/foc_float_thr.c @@ -516,13 +516,6 @@ int foc_float_thr(FAR struct foc_ctrl_env_s *envp) /* Increase counter */ motor.time += 1; - -#ifdef CONFIG_EXAMPLES_FOC_PERF - if (dev.perf.max_changed) - { - PRINTF_PERF("max=%" PRId32 "\n", dev.perf.max); - } -#endif } errout: @@ -545,6 +538,12 @@ errout: PRINTF("ERROR: foc_device_deinit %d failed %d\n", envp->id, ret); } +#ifdef CONFIG_EXAMPLES_FOC_PERF_EXIT + /* Print final perf stats */ + + foc_perf_exit(&dev.perf); +#endif + PRINTF("foc_float_thr %d exit\n", envp->id); return ret; diff --git a/examples/foc/foc_perf.c b/examples/foc/foc_perf.c index 74e378f2c..3c64d3816 100644 --- a/examples/foc/foc_perf.c +++ b/examples/foc/foc_perf.c @@ -27,11 +27,50 @@ #include <assert.h> #include <stdbool.h> #include <string.h> +#include <stdio.h> #include <nuttx/clock.h> #include "foc_perf.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define PRINTF_PERF(format, ...) printf(format, ##__VA_ARGS__) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: foc_perf_exec + ****************************************************************************/ + +static bool foc_perf_exec(struct foc_perf_s *p, FAR uint32_t *exec) +{ + bool tmp = p->exec_max_changed; + + *exec = p->exec_max; + p->exec_max_changed = false; + + return tmp; +} + +/**************************************************************************** + * Name: foc_perf_per + ****************************************************************************/ + +static bool foc_perf_per(struct foc_perf_s *p, FAR uint32_t *per) +{ + bool tmp = p->per_max_changed; + + *per = p->per_max; + p->per_max_changed = false; + + return tmp; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -53,7 +92,7 @@ int foc_perf_init(struct foc_perf_s *p) void foc_perf_start(struct foc_perf_s *p) { - p->now = perf_gettime(); + p->exec = perf_gettime(); } /**************************************************************************** @@ -62,13 +101,72 @@ void foc_perf_start(struct foc_perf_s *p) void foc_perf_end(struct foc_perf_s *p) { - p->now = perf_gettime() - p->now; + uint32_t now = perf_gettime(); + uint32_t tmp = 0; + + if (p->per > 0) + { + tmp = now - p->per; + } + + p->per = now; + p->exec = now - p->exec; + + p->exec_max_changed = false; + p->per_max_changed = false; + + if (p->exec > p->exec_max) + { + p->exec_max = p->exec; + p->exec_max_changed = true; + } + + if (tmp > p->per_max) + { + p->per_max = tmp; + p->per_max_changed = true; + } +} + +/**************************************************************************** + * Name: foc_perf_live + ****************************************************************************/ + +void foc_perf_live(struct foc_perf_s *p) +{ + uint32_t perf = 0; - p->max_changed = false; + if (foc_perf_exec(p, &perf)) + { + PRINTF_PERF("exec ticks=%" PRId32 "\n", perf); + } - if (p->now > p->max) + if (foc_perf_per(p, &perf)) { - p->max = p->now; - p->max_changed = true; + PRINTF_PERF("per ticks=%" PRId32 "\n", perf); } } + +/**************************************************************************** + * Name: foc_perf_exit + ****************************************************************************/ + +void foc_perf_exit(struct foc_perf_s *p) +{ + struct timespec ts; + uint32_t max = 0; + + PRINTF_PERF("===============================\n"); + + foc_perf_exec(p, &max); + perf_convert(max, &ts); + PRINTF_PERF("exec ticks=%" PRId32 "\n", max); + PRINTF_PERF(" nsec=%" PRId32 "\n", ts.tv_nsec); + + foc_perf_per(p, &max); + perf_convert(max, &ts); + PRINTF_PERF("per ticks=%" PRId32 "\n", max); + PRINTF_PERF(" nsec=%" PRId32 "\n", ts.tv_nsec); + + PRINTF_PERF("===============================\n"); +} diff --git a/examples/foc/foc_perf.h b/examples/foc/foc_perf.h index 9303c2b9f..9409e1057 100644 --- a/examples/foc/foc_perf.h +++ b/examples/foc/foc_perf.h @@ -27,21 +27,42 @@ #include <nuttx/config.h> -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define PRINTF_PERF(format, ...) printf(format, ##__VA_ARGS__) - /**************************************************************************** * Public Type Definition ****************************************************************************/ +/* The diagram below illustrates the operation of a simple FOC ocntroller + * performance measurement tool: + * + * | notify | notify | notify + * v v v + * ctrl ctrl + * |------| |------| |--- + * | BUSY | wait | BUSY | wait | + * ____| |------| |------| + * + * ^ ^ ^ + * | exec | | + * |<---->| | + * | | + * | per | + * |<----------->| + * + * + * exec - FOC control loop execution time + * per - FOC control loop period + * notify - notification event from FOC device, + * called with CONFIG_EXAMPLES_FOC_NOTIFIER_FREQ frequency + */ + struct foc_perf_s { - bool max_changed; - uint32_t max; - uint32_t now; + bool exec_max_changed; /* Max execution time changed */ + bool per_max_changed; /* Max period changed */ + uint32_t exec_max; /* Control loop execution max */ + uint32_t per_max; /* Control loop period max */ + uint32_t exec; /* Temporary storage */ + uint32_t per; /* Temporary storage */ }; /**************************************************************************** @@ -51,5 +72,7 @@ struct foc_perf_s int foc_perf_init(struct foc_perf_s *p); void foc_perf_start(struct foc_perf_s *p); void foc_perf_end(struct foc_perf_s *p); +void foc_perf_live(struct foc_perf_s *p); +void foc_perf_exit(struct foc_perf_s *p); #endif /* __APPS_EXAMPLES_FOC_FOC_PERF_H */