You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/09/20 20:04:45 UTC

[incubator-nuttx] 03/05: watchdog: Support auto monitor keep alive from oneshot lowerhalf

This is an automated email from the ASF dual-hosted git repository.

pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 03f45a124ae309bce148a2728584db4de0f0a1fd
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Sun Sep 18 12:08:13 2022 +0800

    watchdog: Support auto monitor keep alive from oneshot lowerhalf
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 drivers/timers/Kconfig          |  4 +++
 drivers/timers/watchdog.c       | 64 ++++++++++++++++++++++++++++++++++-------
 include/nuttx/timers/watchdog.h |  7 ++++-
 3 files changed, 63 insertions(+), 12 deletions(-)

diff --git a/drivers/timers/Kconfig b/drivers/timers/Kconfig
index 0bf0133b0d..877827baf8 100644
--- a/drivers/timers/Kconfig
+++ b/drivers/timers/Kconfig
@@ -371,6 +371,10 @@ choice
 config WATCHDOG_AUTOMONITOR_BY_CAPTURE
 	bool "Capture callback"
 
+config WATCHDOG_AUTOMONITOR_BY_ONESHOT
+	bool "Oneshot callback"
+	depends on ONESHOT
+
 config WATCHDOG_AUTOMONITOR_BY_TIMER
 	bool "Timer callback"
 	depends on TIMER
diff --git a/drivers/timers/watchdog.c b/drivers/timers/watchdog.c
index 10b932d67c..d8e69d172f 100644
--- a/drivers/timers/watchdog.c
+++ b/drivers/timers/watchdog.c
@@ -40,6 +40,7 @@
 #include <nuttx/semaphore.h>
 #include <nuttx/wdog.h>
 #include <nuttx/wqueue.h>
+#include <nuttx/timers/oneshot.h>
 #include <nuttx/timers/timer.h>
 #include <nuttx/timers/watchdog.h>
 
@@ -76,16 +77,18 @@
 struct watchdog_upperhalf_s
 {
 #ifdef CONFIG_WATCHDOG_AUTOMONITOR
-#  if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
-  FAR struct timer_lowerhalf_s *timer;
+#  if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_ONESHOT)
+  FAR struct oneshot_lowerhalf_s *oneshot;
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+  FAR struct timer_lowerhalf_s   *timer;
 #  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
-  struct wdog_s                 wdog;
+  struct wdog_s                   wdog;
 #  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WORKER)
-  struct work_s                 work;
+  struct work_s                   work;
 #  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
-  struct pm_callback_s          idle;
+  struct pm_callback_s            idle;
 #  endif
-  bool                          monitor;
+  bool                            monitor;
 #endif
 
   uint8_t   crefs;    /* The number of times the device has been opened */
@@ -146,6 +149,25 @@ static int watchdog_automonitor_capture(int irq, FAR void *context,
 
   return 0;
 }
+#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_ONESHOT)
+static void
+watchdog_automonitor_oneshot(FAR struct oneshot_lowerhalf_s *oneshot,
+                             FAR void *arg)
+{
+  FAR struct watchdog_upperhalf_s *upper = arg;
+  FAR struct watchdog_lowerhalf_s *lower = upper->lower;
+
+  if (upper->monitor)
+    {
+      struct timespec ts =
+      {
+        WATCHDOG_AUTOMONITOR_PING_INTERVAL, 0
+      };
+
+      lower->ops->keepalive(lower);
+      ONESHOT_START(oneshot, watchdog_automonitor_oneshot, upper, &ts);
+    }
+}
 #elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
 static bool watchdog_automonitor_timer(FAR uint32_t *next_interval_us,
                                        FAR void *arg)
@@ -202,7 +224,11 @@ static void watchdog_automonitor_idle(FAR struct pm_callback_s *cb,
 #endif
 
 #ifdef CONFIG_WATCHDOG_AUTOMONITOR
-#  if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+#  if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_ONESHOT)
+static void
+watchdog_automonitor_start(FAR struct watchdog_upperhalf_s *upper,
+                           FAR struct oneshot_lowerhalf_s *oneshot)
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
 static void
 watchdog_automonitor_start(FAR struct watchdog_upperhalf_s *upper,
                            FAR struct timer_lowerhalf_s *timer)
@@ -215,10 +241,17 @@ watchdog_automonitor_start(FAR struct watchdog_upperhalf_s *upper)
 
   if (!upper->monitor)
     {
-      upper->monitor = true;
 #  if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_CAPTURE)
       lower->ops->capture(lower, watchdog_automonitor_capture);
-#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_ONESHOT)
+      struct timespec ts =
+      {
+        WATCHDOG_AUTOMONITOR_PING_INTERVAL, 0
+      };
+
+      upper->oneshot = oneshot;
+      ONESHOT_START(oneshot, watchdog_automonitor_oneshot, upper, &ts);
+#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
       upper->timer = timer;
       timer->ops->setcallback(timer, watchdog_automonitor_timer, upper);
       timer->ops->settimeout(timer, WATCHDOG_AUTOMONITOR_PING_INTERVAL_MSEC);
@@ -233,6 +266,7 @@ watchdog_automonitor_start(FAR struct watchdog_upperhalf_s *upper)
       upper->idle.notify = watchdog_automonitor_idle;
       pm_register(&upper->idle);
 #  endif
+      upper->monitor = true;
       if (lower->ops->settimeout)
         {
           lower->ops->settimeout(lower, WATCHDOG_AUTOMONITOR_TIMEOUT_MSEC);
@@ -252,6 +286,8 @@ static void watchdog_automonitor_stop(FAR struct watchdog_upperhalf_s *upper)
       lower->ops->stop(lower);
 #  if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_CAPTURE)
       lower->ops->capture(lower, NULL);
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_ONESHOT)
+      ONESHOT_CANCEL(upper->oneshot, NULL);
 #  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
       upper->timer->ops->stop(upper->timer);
 #  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
@@ -622,7 +658,11 @@ static int wdog_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
  *
  ****************************************************************************/
 
-#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_ONESHOT)
+FAR void *watchdog_register(FAR const char *path,
+                            FAR struct watchdog_lowerhalf_s *lower,
+                            FAR struct oneshot_lowerhalf_s *oneshot)
+#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
 FAR void *watchdog_register(FAR const char *path,
                             FAR struct watchdog_lowerhalf_s *lower,
                             FAR struct timer_lowerhalf_s *timer)
@@ -672,7 +712,9 @@ FAR void *watchdog_register(FAR const char *path,
       goto errout_with_path;
     }
 
-#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_ONESHOT)
+  watchdog_automonitor_start(upper, oneshot);
+#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
   watchdog_automonitor_start(upper, timer);
 #elif defined(CONFIG_WATCHDOG_AUTOMONITOR)
   watchdog_automonitor_start(upper);
diff --git a/include/nuttx/timers/watchdog.h b/include/nuttx/timers/watchdog.h
index 3b93d53134..2e001177f1 100644
--- a/include/nuttx/timers/watchdog.h
+++ b/include/nuttx/timers/watchdog.h
@@ -224,7 +224,12 @@ extern "C"
  *
  ****************************************************************************/
 
-#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_ONESHOT)
+struct oneshot_lowerhalf_s;
+FAR void *watchdog_register(FAR const char *path,
+                            FAR struct watchdog_lowerhalf_s *lower,
+                            FAR struct oneshot_lowerhalf_s *oneshot);
+#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
 struct timer_lowerhalf_s;
 FAR void *watchdog_register(FAR const char *path,
                             FAR struct watchdog_lowerhalf_s *lower,