daniel-p-carvalho commented on code in PR #20782:
URL: https://github.com/apache/nuttx/pull/20782#discussion_r4371842999


##########
drivers/timers/Kconfig:
##########
@@ -622,6 +622,54 @@ endif # !WATCHDOG_AUTOMONITOR_BY_CAPTURE && 
!WATCHDOG_AUTOMONITOR_BY_IDLE
 
 endif # WATCHDOG_AUTOMONITOR
 
+config WATCHDOG_TASKMONITOR

Review Comment:
   Done. WATCHDOG_NONEMONITOR (default), WATCHDOG_AUTOMONITOR and 
WATCHDOG_TASKMONITOR are now a choice.



##########
drivers/timers/Kconfig:
##########
@@ -622,6 +622,54 @@ endif # !WATCHDOG_AUTOMONITOR_BY_CAPTURE && 
!WATCHDOG_AUTOMONITOR_BY_IDLE
 
 endif # WATCHDOG_AUTOMONITOR
 
+config WATCHDOG_TASKMONITOR
+       bool "Task monitor"
+       default n
+       depends on !WATCHDOG_AUTOMONITOR && WATCHDOG_MAGIC_V && SCHED_LPWORK

Review Comment:
   Done, TASKMONITOR no longer depends on WATCHDOG_MAGIC_V. The write() of the 
monitor still honors it, as wdog_write() does: with it, a 'V' disarms the 
channel, without it any write just feeds. Tell me if you want the 'V' to always 
work.



##########
drivers/timers/Kconfig:
##########
@@ -622,6 +622,54 @@ endif # !WATCHDOG_AUTOMONITOR_BY_CAPTURE && 
!WATCHDOG_AUTOMONITOR_BY_IDLE
 
 endif # WATCHDOG_AUTOMONITOR
 
+config WATCHDOG_TASKMONITOR
+       bool "Task monitor"
+       default n
+       depends on !WATCHDOG_AUTOMONITOR && WATCHDOG_MAGIC_V && SCHED_LPWORK
+       ---help---
+               Supervise the tasks that use the watchdog devices. Each open() 
of a
+               device creates a channel with its own timeout, which the task 
feeds
+               with write() or WDIOC_KEEPALIVE. The hardware watchdog is fed 
by the
+               monitor only while all the armed channels are within their 
timeouts,
+               so a task that hangs, exits or crashes makes the system reset. 
This
+               replaces the Auto-monitor, which feeds the watchdog 
unconditionally.
+
+if WATCHDOG_TASKMONITOR
+
+config WATCHDOG_TASKMONITOR_AUTOSTART
+       bool "Arm the hardware watchdog when it is registered"
+       default y
+       ---help---
+               Arm the hardware watchdog in watchdog_register() and feed it 
from the
+               low priority work queue even if no task opened the device, so 
that the
+               system resets if that queue stops. If not set, the first open() 
arms it.
+
+config WATCHDOG_TASKMONITOR_HWTIMEOUT
+       int "Hardware watchdog timeout (millisecond)"
+       default 5000
+
+config WATCHDOG_TASKMONITOR_INTERVAL
+       int "Supervision interval (millisecond)"
+       default 500

Review Comment:
   Done. The default is 0, which means WATCHDOG_TASKMONITOR_HWTIMEOUT / 2, like 
WATCHDOG_AUTOMONITOR_PING_INTERVAL (Kconfig cannot compute a default). While 
testing this on the board I found that a channel which was late by less than 
the interval could be fed back before the worker noticed it, and escape. feed() 
now keeps an expired channel expired, so the interval only changes how late the 
timeout is detected. Retested on the simulator and on the ev49n51a.



##########
drivers/timers/watchdog.c:
##########
@@ -127,8 +144,15 @@ struct watchdog_upperhalf_s
   bool                            monitor;
 #endif
 
-  FAR char *path;     /* Registration path */
+#ifdef CONFIG_WATCHDOG_TASKMONITOR
+  struct work_s    work;    /* Checks the channels, feeds the hardware */
+  struct list_node users;   /* All the channels (struct watchdog_user_s) */
+  bool             started; /* The hardware watchdog is armed */
+#endif
+
+  uint8_t   crefs;    /* The number of times the device has been opened */

Review Comment:
   users is empty in two valid cases with the hardware running: with AUTOSTART 
the hardware is armed in watchdog_register() before any open(), and after the 
last disarmed channel is closed the worker keeps feeding it, which is the 
global monitor. So 'started' tells whether the hardware is armed and the worker 
is queued, and users only tells which channels exist. I can drop it if you 
prefer another way.



##########
drivers/timers/watchdog.c:
##########
@@ -1087,6 +1406,15 @@ void watchdog_unregister(FAR void *handle)
   watchdog_automonitor_stop(upper);
 #endif
 
+#ifdef CONFIG_WATCHDOG_TASKMONITOR
+  work_cancel(LPWORK, &upper->work);

Review Comment:
   Done, work_cancel_sync().



##########
drivers/timers/watchdog.c:
##########


Review Comment:
   Done, wdog_read() is before the task monitor block.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to