You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/02/25 19:23:26 UTC
[incubator-nuttx] 03/03: xtensa/esp32s2: Fix Scheduler CPU Load feature using Oneshot Timer
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/incubator-nuttx.git
commit 6a12befcd59c6e328da704cd3cc8afde72d6d3b6
Author: Gustavo Henrique Nihei <gu...@espressif.com>
AuthorDate: Fri Feb 25 10:10:15 2022 -0300
xtensa/esp32s2: Fix Scheduler CPU Load feature using Oneshot Timer
Signed-off-by: Gustavo Henrique Nihei <gu...@espressif.com>
---
arch/xtensa/src/esp32s2/esp32s2_oneshot.c | 32 +++++++++++-----------
.../xtensa/src/esp32s2/esp32s2_oneshot_lowerhalf.c | 16 +++++++----
2 files changed, 27 insertions(+), 21 deletions(-)
diff --git a/arch/xtensa/src/esp32s2/esp32s2_oneshot.c b/arch/xtensa/src/esp32s2/esp32s2_oneshot.c
index ced51d2..70c25968 100644
--- a/arch/xtensa/src/esp32s2/esp32s2_oneshot.c
+++ b/arch/xtensa/src/esp32s2/esp32s2_oneshot.c
@@ -85,20 +85,15 @@ static int esp32s2_oneshot_handler(int irq, void *context, void *arg);
static int esp32s2_oneshot_handler(int irq, void *context, void *arg)
{
int ret = OK;
- struct esp32s2_oneshot_s *oneshot =
- (struct esp32s2_oneshot_s *)arg;
+ struct esp32s2_oneshot_s *oneshot = (struct esp32s2_oneshot_s *)arg;
+ oneshot_handler_t handler;
+ void *handler_arg;
- DEBUGASSERT(oneshot != NULL && oneshot->handler != NULL);
+ DEBUGASSERT(oneshot != NULL);
+ DEBUGASSERT(oneshot->handler != NULL);
tmrinfo("Oneshot handler triggered\n");
- /* Stop timer
- * Note: It's not necessary to disable the alarm because
- * it automatically disables each time it expires.
- */
-
- ESP32S2_TIM_STOP(oneshot->tim);
-
/* Disable interrupts */
ESP32S2_TIM_DISABLEINT(oneshot->tim);
@@ -107,19 +102,24 @@ static int esp32s2_oneshot_handler(int irq, void *context, void *arg)
ret = ESP32S2_TIM_SETISR(oneshot->tim, NULL, NULL);
- /* Call the callback */
+ /* Clear the Interrupt */
- oneshot->handler((void *)oneshot->arg);
+ ESP32S2_TIM_ACKINT(oneshot->tim);
- /* Restore state */
+ /* The timer is no longer running */
oneshot->running = false;
+
+ /* Forward the event, clearing out any vestiges */
+
+ handler = (oneshot_handler_t)oneshot->handler;
oneshot->handler = NULL;
- oneshot->arg = NULL;
+ handler_arg = (void *)oneshot->arg;
+ oneshot->arg = NULL;
- /* Clear the Interrupt */
+ /* Call the callback */
- ESP32S2_TIM_ACKINT(oneshot->tim);
+ handler(handler_arg);
return ret;
}
diff --git a/arch/xtensa/src/esp32s2/esp32s2_oneshot_lowerhalf.c b/arch/xtensa/src/esp32s2/esp32s2_oneshot_lowerhalf.c
index 935779d..78954b1 100644
--- a/arch/xtensa/src/esp32s2/esp32s2_oneshot_lowerhalf.c
+++ b/arch/xtensa/src/esp32s2/esp32s2_oneshot_lowerhalf.c
@@ -114,20 +114,26 @@ static void esp32s2_oneshot_lh_handler(void *arg)
{
struct esp32s2_oneshot_lowerhalf_s *priv =
(struct esp32s2_oneshot_lowerhalf_s *)arg;
+ oneshot_callback_t callback;
+ FAR void *cb_arg;
DEBUGASSERT(priv != NULL);
DEBUGASSERT(priv->callback != NULL);
tmrinfo("Oneshot LH handler triggered\n");
- /* Call the callback */
+ /* Sample and nullify BEFORE executing callback (in case the callback
+ * restarts the oneshot).
+ */
- priv->callback(&priv->lh, priv->arg);
+ callback = priv->callback;
+ cb_arg = priv->arg;
+ priv->callback = NULL;
+ priv->arg = NULL;
- /* Restore state */
+ /* Then perform the callback */
- priv->callback = NULL;
- priv->arg = NULL;
+ callback(&priv->lh, cb_arg);
}
/****************************************************************************