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:44 UTC

[incubator-nuttx] 02/05: watchdog: Support auto monitor keep alive from timer 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 1eefec4db3876305860eb57b91f454322d44a74a
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Sun Sep 18 10:47:19 2022 +0800

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

diff --git a/drivers/timers/Kconfig b/drivers/timers/Kconfig
index 8988d052b6..0bf0133b0d 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_TIMER
+	bool "Timer callback"
+	depends on TIMER
+
 config WATCHDOG_AUTOMONITOR_BY_WDOG
 	bool "Wdog callback"
 
@@ -388,7 +392,7 @@ config WATCHDOG_AUTOMONITOR_TIMEOUT
 	int "Auto-monitor reset timeout(second)"
 	default 60
 
-if WATCHDOG_AUTOMONITOR_BY_WDOG || WATCHDOG_AUTOMONITOR_BY_WORKER
+if !WATCHDOG_AUTOMONITOR_BY_CAPTURE && !WATCHDOG_AUTOMONITOR_BY_IDLE
 
 config WATCHDOG_AUTOMONITOR_PING_INTERVAL
 	int "Auto-monitor keep a live interval"
@@ -400,7 +404,7 @@ config WATCHDOG_AUTOMONITOR_PING_INTERVAL
 		This interval will only be used by auto-monitor by Worker callback
 		or by Timer callback.
 
-endif # WATCHDOG_AUTOMONITOR_BY_WDOG || WATCHDOG_AUTOMONITOR_BY_WORKER
+endif # !WATCHDOG_AUTOMONITOR_BY_CAPTURE && !WATCHDOG_AUTOMONITOR_BY_IDLE
 
 endif # WATCHDOG_AUTOMONITOR
 
diff --git a/drivers/timers/watchdog.c b/drivers/timers/watchdog.c
index c81a3c4ad0..10b932d67c 100644
--- a/drivers/timers/watchdog.c
+++ b/drivers/timers/watchdog.c
@@ -40,31 +40,31 @@
 #include <nuttx/semaphore.h>
 #include <nuttx/wdog.h>
 #include <nuttx/wqueue.h>
+#include <nuttx/timers/timer.h>
 #include <nuttx/timers/watchdog.h>
 
-#ifdef CONFIG_WATCHDOG
-
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
 #ifdef CONFIG_WATCHDOG_AUTOMONITOR
-
-#define WATCHDOG_AUTOMONITOR_TIMEOUT_MSEC \
-  (1000 * CONFIG_WATCHDOG_AUTOMONITOR_TIMEOUT)
-
-#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG) || \
-    defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WORKER)
-#if (CONFIG_WATCHDOG_AUTOMONITOR_TIMEOUT == \
-    CONFIG_WATCHDOG_AUTOMONITOR_PING_INTERVAL)
-#define WATCHDOG_AUTOMONITOR_PING_INTERVAL \
-  SEC2TICK(CONFIG_WATCHDOG_AUTOMONITOR_TIMEOUT / 2)
-#else
-#define WATCHDOG_AUTOMONITOR_PING_INTERVAL \
-  SEC2TICK(CONFIG_WATCHDOG_AUTOMONITOR_PING_INTERVAL)
-#endif
-#endif
-
+#  define WATCHDOG_AUTOMONITOR_TIMEOUT_MSEC \
+     (CONFIG_WATCHDOG_AUTOMONITOR_TIMEOUT * MSEC_PER_SEC)
+#  if !defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_CAPTURE) && \
+      !defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
+#    if CONFIG_WATCHDOG_AUTOMONITOR_TIMEOUT == \
+        CONFIG_WATCHDOG_AUTOMONITOR_PING_INTERVAL
+#      define WATCHDOG_AUTOMONITOR_PING_INTERVAL \
+         (CONFIG_WATCHDOG_AUTOMONITOR_PING_INTERVAL / 2)
+#    else
+#      define WATCHDOG_AUTOMONITOR_PING_INTERVAL \
+         CONFIG_WATCHDOG_AUTOMONITOR_PING_INTERVAL
+#    endif
+#    define WATCHDOG_AUTOMONITOR_PING_INTERVAL_MSEC \
+       (WATCHDOG_AUTOMONITOR_PING_INTERVAL * MSEC_PER_SEC)
+#    define WATCHDOG_AUTOMONITOR_PING_INTERVAL_TICK \
+       SEC2TICK(WATCHDOG_AUTOMONITOR_PING_INTERVAL)
+#  endif
 #endif
 
 /****************************************************************************
@@ -76,14 +76,16 @@
 struct watchdog_upperhalf_s
 {
 #ifdef CONFIG_WATCHDOG_AUTOMONITOR
-#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
-  struct wdog_s        wdog;
-#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WORKER)
-  struct work_s        work;
-#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
-  struct pm_callback_s idle;
-#endif
-  bool                 monitor;
+#  if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+  FAR struct timer_lowerhalf_s *timer;
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
+  struct wdog_s                 wdog;
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WORKER)
+  struct work_s                 work;
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
+  struct pm_callback_s          idle;
+#  endif
+  bool                          monitor;
 #endif
 
   uint8_t   crefs;    /* The number of times the device has been opened */
@@ -144,6 +146,20 @@ static int watchdog_automonitor_capture(int irq, FAR void *context,
 
   return 0;
 }
+#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+static bool watchdog_automonitor_timer(FAR uint32_t *next_interval_us,
+                                       FAR void *arg)
+{
+  FAR struct watchdog_upperhalf_s *upper = arg;
+  FAR struct watchdog_lowerhalf_s *lower = upper->lower;
+
+  if (upper->monitor)
+    {
+      lower->ops->keepalive(lower);
+    }
+
+  return upper->monitor;
+}
 #elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
 static void watchdog_automonitor_wdog(wdparm_t arg)
 {
@@ -153,7 +169,7 @@ static void watchdog_automonitor_wdog(wdparm_t arg)
   if (upper->monitor)
     {
       lower->ops->keepalive(lower);
-      wd_start(&upper->wdog, WATCHDOG_AUTOMONITOR_PING_INTERVAL,
+      wd_start(&upper->wdog, WATCHDOG_AUTOMONITOR_PING_INTERVAL_TICK,
                watchdog_automonitor_wdog, (wdparm_t)upper);
     }
 }
@@ -167,7 +183,7 @@ static void watchdog_automonitor_worker(FAR void *arg)
     {
       lower->ops->keepalive(lower);
       work_queue(LPWORK, &upper->work, watchdog_automonitor_worker,
-                 upper, WATCHDOG_AUTOMONITOR_PING_INTERVAL);
+                 upper, WATCHDOG_AUTOMONITOR_PING_INTERVAL_TICK);
     }
 }
 #elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
@@ -186,26 +202,37 @@ static void watchdog_automonitor_idle(FAR struct pm_callback_s *cb,
 #endif
 
 #ifdef CONFIG_WATCHDOG_AUTOMONITOR
-static void watchdog_automonitor_start(FAR struct watchdog_upperhalf_s
-                                       *upper)
+#  if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+static void
+watchdog_automonitor_start(FAR struct watchdog_upperhalf_s *upper,
+                           FAR struct timer_lowerhalf_s *timer)
+#  else
+static void
+watchdog_automonitor_start(FAR struct watchdog_upperhalf_s *upper)
+#  endif
 {
   FAR struct watchdog_lowerhalf_s *lower = upper->lower;
 
   if (!upper->monitor)
     {
       upper->monitor = true;
-#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_CAPTURE)
+#  if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_CAPTURE)
       lower->ops->capture(lower, watchdog_automonitor_capture);
-#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
-      wd_start(&upper->wdog, WATCHDOG_AUTOMONITOR_PING_INTERVAL,
+#  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);
+      timer->ops->start(timer);
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
+      wd_start(&upper->wdog, WATCHDOG_AUTOMONITOR_PING_INTERVAL_TICK,
                watchdog_automonitor_wdog, (wdparm_t)upper);
-#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WORKER)
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WORKER)
       work_queue(LPWORK, &upper->work, watchdog_automonitor_worker,
-                 upper, WATCHDOG_AUTOMONITOR_PING_INTERVAL);
-#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
+                 upper, WATCHDOG_AUTOMONITOR_PING_INTERVAL_TICK);
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
       upper->idle.notify = watchdog_automonitor_idle;
       pm_register(&upper->idle);
-#endif
+#  endif
       if (lower->ops->settimeout)
         {
           lower->ops->settimeout(lower, WATCHDOG_AUTOMONITOR_TIMEOUT_MSEC);
@@ -223,15 +250,17 @@ static void watchdog_automonitor_stop(FAR struct watchdog_upperhalf_s *upper)
     {
       upper->monitor = false;
       lower->ops->stop(lower);
-#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_CAPTURE)
+#  if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_CAPTURE)
       lower->ops->capture(lower, NULL);
-#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+      upper->timer->ops->stop(upper->timer);
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
       wd_cancel(&upper->wdog);
-#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WORKER)
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WORKER)
       work_cancel(LPWORK, &upper->work);
-#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
+#  elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
       pm_unregister(&upper->idle);
-#endif
+#  endif
     }
 }
 #endif
@@ -593,8 +622,14 @@ static int wdog_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
  *
  ****************************************************************************/
 
+#if 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)
+#else
 FAR void *watchdog_register(FAR const char *path,
                             FAR struct watchdog_lowerhalf_s *lower)
+#endif
 {
   FAR struct watchdog_upperhalf_s *upper;
   int ret;
@@ -637,7 +672,9 @@ FAR void *watchdog_register(FAR const char *path,
       goto errout_with_path;
     }
 
-#ifdef CONFIG_WATCHDOG_AUTOMONITOR
+#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+  watchdog_automonitor_start(upper, timer);
+#elif defined(CONFIG_WATCHDOG_AUTOMONITOR)
   watchdog_automonitor_start(upper);
 #endif
 
@@ -702,5 +739,3 @@ void watchdog_unregister(FAR void *handle)
   nxsem_destroy(&upper->exclsem);
   kmm_free(upper);
 }
-
-#endif /* CONFIG_WATCHDOG */
diff --git a/include/nuttx/timers/watchdog.h b/include/nuttx/timers/watchdog.h
index 41aef68c3c..3b93d53134 100644
--- a/include/nuttx/timers/watchdog.h
+++ b/include/nuttx/timers/watchdog.h
@@ -224,8 +224,15 @@ extern "C"
  *
  ****************************************************************************/
 
+#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
+struct timer_lowerhalf_s;
+FAR void *watchdog_register(FAR const char *path,
+                            FAR struct watchdog_lowerhalf_s *lower,
+                            FAR struct timer_lowerhalf_s *timer);
+#else
 FAR void *watchdog_register(FAR const char *path,
                             FAR struct watchdog_lowerhalf_s *lower);
+#endif
 
 /****************************************************************************
  * Name: watchdog_unregister