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 a7024aea896dd4cec7be209959efd5a5ac570ab0
Author: raiden00pl <raide...@railab.me>
AuthorDate: Tue Oct 31 19:03:41 2023 +0100

    examples/foc: protect control loop with critical section
    
    If the controller frequency is high, system timer interrupts will
    eventually interrupt the controller function, thereby increasing the
    execution time. This may lead to skipping the control cycle, which
    negatively affects the control algorithm.
    
    With this option enabled, interrupts are disabled for the duration
    of the controller function execution.
    
    Here example results from CONFIG_EXAMPLES_FOC_PERF output
    for b-g431b-esc1 board with CONFIG_EXAMPLES_FOC_NOTIFIER_FREQ=10000:
    
    1. CONFIG_EXAMPLES_FOC_CONTROL_CRITSEC=n
    
      exec ticks=5258
        nsec=30929
      per ticks=21268
        nsec=125105
    
    2. CONFIG_EXAMPLES_FOC_CONTROL_CRITSEC=y
    
      exec ticks=3428
        nsec=20164
      per ticks=19203
        nsec=112958
    
    The difference is ~12us!
---
 examples/foc/Kconfig           | 18 ++++++++++++++++++
 examples/foc/foc_fixed16_thr.c | 16 ++++++++++++++++
 examples/foc/foc_float_thr.c   | 16 ++++++++++++++++
 3 files changed, 50 insertions(+)

diff --git a/examples/foc/Kconfig b/examples/foc/Kconfig
index 02a8188ec..0c066575f 100644
--- a/examples/foc/Kconfig
+++ b/examples/foc/Kconfig
@@ -47,6 +47,24 @@ config EXAMPLES_FOC_PERF
        bool "Enable performance meassurements"
        default n
 
+config EXAMPLES_FOC_CONTROL_CRITSEC
+       bool "Protect controller thread with critical section"
+       default y
+       depends on BUILD_FLAT
+       ---help---
+               Protect controller thread with critical section.
+
+               If the controller frequency is high, system timer interrupts 
will
+               eventually interrupt the controller function, thereby 
increasing the
+               execution time. This may lead to skipping the control cycle, 
which
+               negatively affects the control algorithm.
+
+               With this option enabled, interrupts are disabled for the 
duration
+               of the controller function execution.
+
+               This option uses the kernel internal API directly, which means
+               it won't work outside of FLAT build.
+
 if EXAMPLES_FOC_PERF
 
 config EXAMPLES_FOC_PERF_LIVE
diff --git a/examples/foc/foc_fixed16_thr.c b/examples/foc/foc_fixed16_thr.c
index 716cee3ff..47a979d41 100644
--- a/examples/foc/foc_fixed16_thr.c
+++ b/examples/foc/foc_fixed16_thr.c
@@ -50,6 +50,16 @@
 #  error
 #endif
 
+/* Critical section */
+
+#ifdef CONFIG_EXAMPLES_FOC_CONTROL_CRITSEC
+#  define foc_enter_critical() irqstate_t intflags = enter_critical_section()
+#  define foc_leave_critical() leave_critical_section(intflags)
+#else
+#  define foc_enter_critical()
+#  define foc_leave_critical()
+#endif
+
 /****************************************************************************
  * Private Type Definition
  ****************************************************************************/
@@ -340,6 +350,8 @@ int foc_fixed16_thr(FAR struct foc_ctrl_env_s *envp)
 
   while (motor.mq.quit == false)
     {
+      foc_enter_critical();
+
       if (motor.mq.start == true)
         {
           /* Get FOC device state */
@@ -390,6 +402,7 @@ int foc_fixed16_thr(FAR struct foc_ctrl_env_s *envp)
 
           /* Start from the beginning of the control loop */
 
+          foc_leave_critical();
           continue;
         }
 
@@ -397,6 +410,7 @@ int foc_fixed16_thr(FAR struct foc_ctrl_env_s *envp)
 
       if (motor.mq.start == false)
         {
+          foc_leave_critical();
           usleep(1000);
           continue;
         }
@@ -503,6 +517,8 @@ int foc_fixed16_thr(FAR struct foc_ctrl_env_s *envp)
       /* Increase counter */
 
       motor.time += 1;
+
+      foc_leave_critical();
     }
 
 errout:
diff --git a/examples/foc/foc_float_thr.c b/examples/foc/foc_float_thr.c
index 4fae5ba76..44bde00e6 100644
--- a/examples/foc/foc_float_thr.c
+++ b/examples/foc/foc_float_thr.c
@@ -50,6 +50,16 @@
 #  error
 #endif
 
+/* Critical section */
+
+#ifdef CONFIG_EXAMPLES_FOC_CONTROL_CRITSEC
+#  define foc_enter_critical() irqstate_t intflags = enter_critical_section()
+#  define foc_leave_critical() leave_critical_section(intflags)
+#else
+#  define foc_enter_critical()
+#  define foc_leave_critical()
+#endif
+
 /****************************************************************************
  * Private Type Definition
  ****************************************************************************/
@@ -353,6 +363,8 @@ int foc_float_thr(FAR struct foc_ctrl_env_s *envp)
 
   while (motor.mq.quit == false)
     {
+      foc_enter_critical();
+
       if (motor.mq.start == true)
         {
           /* Get FOC device state */
@@ -403,6 +415,7 @@ int foc_float_thr(FAR struct foc_ctrl_env_s *envp)
 
           /* Start from the beginning of the control loop */
 
+          foc_leave_critical();
           continue;
         }
 
@@ -410,6 +423,7 @@ int foc_float_thr(FAR struct foc_ctrl_env_s *envp)
 
       if (motor.mq.start == false)
         {
+          foc_leave_critical();
           usleep(1000);
           continue;
         }
@@ -516,6 +530,8 @@ int foc_float_thr(FAR struct foc_ctrl_env_s *envp)
       /* Increase counter */
 
       motor.time += 1;
+
+      foc_leave_critical();
     }
 
 errout:

Reply via email to