daniel-p-carvalho opened a new pull request, #20782:
URL: https://github.com/apache/nuttx/pull/20782

   ## Summary
   
   Add a task watchdog supervisor (`CONFIG_TASKWDT`): one hardware watchdog 
shared
   among any number of tasks, each with its own time-out. It is the kind of
   service Zephyr calls `task_wdt`, but its interface is the Linux watchdog API
   instead of a new set of functions.
   
   Each task opens `/dev/taskwdt` (`CONFIG_TASKWDT_DEVPATH`) and gets a channel:
   
   - `write()` or `WDIOC_KEEPALIVE` feeds it, `WDIOC_SETTIMEOUT` sets its
     time-out in milliseconds, `WDIOC_GETSTATUS` reports it.
   - a `'V'` in a `write()` (or `WDIOC_STOP`) disarms it, `WDIOC_START` arms it
     again.
   - `close()` frees the channel only if it is disarmed. A channel closed while
     armed is never fed again, so a task that exits or is killed without
     disarming it ends in a reset, as it would on Linux.
   
   The supervisor sits on top of any watchdog registered with
   `watchdog_register()` and feeds it from the low priority work queue only 
while
   every armed channel is within its time-out. When one is late it logs the pid
   and the name of the task that opened it and stops feeding, so the hardware
   resets the system (or panics at once with `CONFIG_TASKWDT_PANIC`, to get a
   crash dump). With `CONFIG_TASKWDT_AUTOSTART` the hardware watchdog is armed 
at
   initialization and fed even with no channel open, which also covers a hang of
   the whole system (scheduler, work queue, interrupts) before any task has
   registered. It replaces `WATCHDOG_AUTOMONITOR`, which feeds unconditionally, 
so
   the two exclude each other.
   
   Why a separate driver and not an extension of `drivers/timers/watchdog.c`: 
the
   upper half exposes one lower half to one user, the supervisor needs per-open
   state (one channel per `open()`) and a policy on top of the existing
   hardware, and it must not depend on which lower half is used.
   
   Commits:
   
   1. `drivers/timers: add a task watchdog supervisor.` The driver, its header,
      Kconfig, Make.defs/CMake, and the documentation page.
   2. `boards/sim: add a simulated watchdog timer.` `CONFIG_SIM_WATCHDOG`: a
      software watchdog at `CONFIG_WATCHDOG_DEVPATH`. The simulator cannot 
reset,
      so when it expires the simulator exits with
      `CONFIG_SIM_WATCHDOG_EXITCODE` (77).
   3. `boards/sim: add a taskwdt configuration.` `sim:taskwdt`, which builds the
      supervisor in CI and enables the `taskwdt_test` application
      (apache/nuttx-apps#3874, to be merged first).
   
   ## Impact
   
   New option, off by default; nothing changes for existing configurations.
   `TASKWDT` depends on `WATCHDOG` and `SCHED_LPWORK` and excludes
   `WATCHDOG_AUTOMONITOR`. Each channel costs one small allocation plus the
   name of the task. New documentation page
   `os/drivers/character/timers/taskwdt`, and a `taskwdt` section on the sim
   board page. No change to the existing watchdog upper half or to any other
   board.
   
   ## Testing
   
   Host: Linux x86_64 (Ubuntu), gcc for the sim, Microchip XC32 v6.00 for the
   board. The application used is `taskwdt_test` from the companion nuttx-apps 
PR;
   run it without arguments for the list of cases. A `PASS`/`FAIL` line is 
printed
   by the cases that must not reset the system. The others stop feeding on 
purpose
   and expect a reset.
   
   **Simulator** (`./tools/configure.sh sim:taskwdt && make`, then
   `taskwdt_test <case>` in NSH; a "reset" is the exit status 77):
   
   | Case | Result |
   |------|--------|
   | `idle` (no channel, 30 s), `feed`, `write`, `disarm`, `stop`, `status`, 
`errors`, `multi`, `leak` (1000 open/close, heap unchanged) | PASS |
   | `starve`, `exit` (closed while armed), `kill` (task deleted), `two` (one 
of two threads starves), `late` (feeding resumes after the time-out), `hog` 
(scheduler locked) | exit status 77 in 5 to 8 s |
   | `CONFIG_TASKWDT_PANIC=y`, `starve` | time-out report, then the panic dump |
   | `CONFIG_TASKWDT_AUTOSTART=n`: `starve` resets (first `open()` arms the 
hardware); `hog` with no channel does not | as expected |
   
   **Board**: EV49N51A (WFI32E01PE, PIC32MZ-W1) with the watchdog of #20776 as
   `/dev/watchdog0` (time-out 8.2 s nominal, LPRC based, so 6.7 to 9.3 s), and 
the
   supervisor started from the board bring-up (a board configuration for it is 
not
   part of this PR). Same cases, times are seconds after the command, "boot" is
   the `Last reset was caused by the watchdog` line of the next boot:
   
   | Case | Result | Report | Boot |
   |------|--------|--------|------|
   | `idle 30`, `feed 20`, `write 20`, `disarm 12`, `stop 12`, `status`, 
`errors`, `multi 15`, `leak 1000` | PASS (heap 10648 before and after) | | |
   | `starve 2000` | reset | 2.06 | 9.59 |
   | `exit 2000` | reset | 2.56 | 10.09 |
   | `kill 2000` | reset, names `victim` | 3.06 | 10.59 |
   | `two 2000` | reset, names `starver` | 2.56 | 10.09 |
   | `late 1000` | reset | 1.51 | 9.09 |
   | `hog` (scheduler locked) | reset | | 8.04 |
   | `hang` (interrupts disabled) | reset | | 8.08 |
   | `TASKWDT_PANIC=y`, `starve 2000` | report, panic dump, reset | 2.11 | 9.64 
|
   | `TASKWDT_AUTOSTART=n`: `idle 30` PASS, `starve 2000` | reset | 2.11 | 9.64 
|
   | `TASKWDT_AUTOSTART=n`: `hog` with no channel | no reset in 25 s (hardware 
not armed) | | |
   
   The reset comes about 7.5 s after the report: the last feed was at most one
   `CONFIG_TASKWDT_INTERVAL` (500 ms) before it, plus the hardware time-out.
   
   ```
   nsh> taskwdt_test starve 2000
   channel of 2000 ms never fed
   expect: system reset
   taskwdt_worker: Task watchdog timeout: pid 14 (taskwdt_test), 2000 ms
   Last reset was caused by the watchdog
   
   NuttShell (NSH) NuttX-13.1.0
   ```
   
   ```
   nsh> taskwdt_test kill 2000
   deleting pid 5 that feeds a channel of 2000 ms
   expect: system reset
   taskwdt_worker: Task watchdog timeout: pid 5 (victim), 2000 ms
   Last reset was caused by the watchdog
   ```
   
   Documentation: `make html` builds the new page and the changed ones without
   warnings; the 32 existing warnings of the tree are not related.
   `tools/checkpatch.sh -c -u -m -g` is clean for all the commits.
   


-- 
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