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 */

Reply via email to