mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge #18257
18257: drivers/wdt: add periph_wdt_auto_start for early watchdog r=benpicco a=benpicco Co-authored-by: Benjamin Valentin <benjamin.valentin@ml-pa.com>
This commit is contained in:
commit
1c55118bd8
@ -257,6 +257,10 @@ ifneq (,$(filter periph_timer_periodic,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_timer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_wdt_auto_start,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_wdt
|
||||
endif
|
||||
|
||||
ifneq (,$(filter-out netdev_default netdev_new_api netdev_legacy_api, $(filter netdev_%,$(USEMODULE))))
|
||||
USEMODULE += netdev
|
||||
# Don't register netdevs if there is only a single one of them
|
||||
|
@ -157,9 +157,42 @@
|
||||
* Makefile add:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
|
||||
* MODULE += periph_wdt_cb
|
||||
* USEMODULE += periph_wdt_cb
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* WDT Auto-Start
|
||||
* ==============
|
||||
*
|
||||
* It is possible to enable the Watchdog in early boot, before application startup:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
|
||||
* USEMODULE += periph_wdt_auto_start
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* The watchdog will automatically be initialized with the parameters
|
||||
* @ref CONFIG_PERIPH_WDT_WIN_MIN_MS and @ref CONFIG_PERIPH_WDT_WIN_MAX_MS
|
||||
*
|
||||
* It is also possible to automatically kick the watchdog.
|
||||
* This is a very non-invasive way of using the watchdog, but it is also very
|
||||
* weak as it can only detect situations where low-priority threads are
|
||||
* starved from execution and may even trigger wrongly in situations where the
|
||||
* system just experiences high load, but would otherwise have recovered on it's own.
|
||||
*
|
||||
* If you want to enable it anyway, select this module:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
|
||||
* USEMODULE += auto_init_wdt_thread
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* If you are using an event thread, you can also use the watchdog to ensure that events
|
||||
* are processed in time.
|
||||
* To do so, add
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
|
||||
* USEMODULE += auto_init_wdt_event
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file wdt.h
|
||||
@ -230,6 +263,23 @@ extern "C" {
|
||||
#define WDT_HAS_INIT (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief If `periph_wdt_auto_start` is used, this will be the lower bound
|
||||
* of when the WDT can be kicked.
|
||||
*/
|
||||
#ifndef CONFIG_PERIPH_WDT_WIN_MIN_MS
|
||||
#define CONFIG_PERIPH_WDT_WIN_MIN_MS (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief If `periph_wdt_auto_start` is used, this will be the max period
|
||||
* after which the WDT must be kicked or else it will reboot the
|
||||
* system.
|
||||
*/
|
||||
#ifndef CONFIG_PERIPH_WDT_WIN_MAX_MS
|
||||
#define CONFIG_PERIPH_WDT_WIN_MAX_MS (1024)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Start watchdog timer
|
||||
*/
|
||||
|
@ -102,6 +102,11 @@ void periph_init(void)
|
||||
|
||||
#if defined(MODULE_PERIPH_INIT_WDT) && WDT_HAS_INIT
|
||||
wdt_init();
|
||||
|
||||
if (IS_ACTIVE(MODULE_PERIPH_WDT_AUTO_START)) {
|
||||
wdt_setup_reboot(CONFIG_PERIPH_WDT_WIN_MIN_MS, CONFIG_PERIPH_WDT_WIN_MAX_MS);
|
||||
wdt_start();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MODULE_PERIPH_INIT_PTP)
|
||||
|
@ -591,6 +591,8 @@ NO_PSEUDOMODULES += auto_init_multimedia
|
||||
NO_PSEUDOMODULES += auto_init_security
|
||||
NO_PSEUDOMODULES += auto_init_usbus
|
||||
NO_PSEUDOMODULES += auto_init_screen
|
||||
NO_PSEUDOMODULES += auto_init_wdt_event
|
||||
NO_PSEUDOMODULES += auto_init_wdt_thread
|
||||
|
||||
# Packages and drivers may also add modules to PSEUDOMODULES in their `Makefile.include`.
|
||||
|
||||
|
@ -24,6 +24,23 @@ ifneq (,$(filter auto_init_gnrc_netif,$(USEMODULE)))
|
||||
USEMODULE += gnrc_netif_init_devs
|
||||
endif
|
||||
|
||||
ifneq (,$(filter auto_init_wdt_thread,$(USEMODULE)))
|
||||
USEMODULE += periph_wdt_auto_start
|
||||
USEMODULE += ztimer_msec
|
||||
|
||||
# we can only have either auto_init_wdt_event or auto_init_wdt_thread
|
||||
ifneq (,$(filter auto_init_wdt_event,$(USEMODULE)))
|
||||
$(error auto_init_wdt_event and auto_init_wdt_thread are mutually exclusive)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter auto_init_wdt_event,$(USEMODULE)))
|
||||
USEMODULE += event_periodic_callback
|
||||
USEMODULE += event_thread
|
||||
USEMODULE += periph_wdt_auto_start
|
||||
USEMODULE += ztimer_msec
|
||||
endif
|
||||
|
||||
ifneq (,$(filter auto_init_sock_dns,$(USEMODULE)))
|
||||
ifneq (,$(filter ipv4,$(USEMODULE)))
|
||||
USEMODULE += ipv4_addr
|
||||
|
@ -30,4 +30,12 @@ ifneq (,$(filter auto_init_screen,$(USEMODULE)))
|
||||
DIRS += screen
|
||||
endif
|
||||
|
||||
ifneq (,$(filter auto_init_wdt_event,$(USEMODULE)))
|
||||
DIRS += wdt_event
|
||||
endif
|
||||
|
||||
ifneq (,$(filter auto_init_wdt_thread,$(USEMODULE)))
|
||||
DIRS += wdt_thread
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
@ -41,6 +41,12 @@ extern "C" {
|
||||
*/
|
||||
#define AUTO_INIT_PRIO_MOD_XTIMER 1030
|
||||
#endif
|
||||
#ifndef AUTO_INIT_PRIO_WDT_THREAD
|
||||
/**
|
||||
* @brief WDT priority
|
||||
*/
|
||||
#define AUTO_INIT_PRIO_WDT_THREAD 1035
|
||||
#endif
|
||||
#ifndef AUTO_INIT_PRIO_MOD_RANDOM
|
||||
/**
|
||||
* @brief RNG priority
|
||||
@ -71,6 +77,12 @@ extern "C" {
|
||||
*/
|
||||
#define AUTO_INIT_PRIO_MOD_EVENT_THREAD 1080
|
||||
#endif
|
||||
#ifndef AUTO_INIT_PRIO_WDT_EVENT
|
||||
/**
|
||||
* @brief WDT event priority
|
||||
*/
|
||||
#define AUTO_INIT_PRIO_WDT_EVENT 1085
|
||||
#endif
|
||||
#ifndef AUTO_INIT_PRIO_MOD_SYS_BUS
|
||||
/**
|
||||
* @brief sys bus priority
|
||||
|
3
sys/auto_init/wdt_event/Makefile
Normal file
3
sys/auto_init/wdt_event/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = auto_init_wdt_event
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
47
sys/auto_init/wdt_event/wdt.c
Normal file
47
sys/auto_init/wdt_event/wdt.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ML!PA Consulting GmbH
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_auto_init
|
||||
* @{
|
||||
*
|
||||
* @file wdt.c
|
||||
* @brief Watchdog Event
|
||||
*
|
||||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "auto_init.h"
|
||||
#include "auto_init_utils.h"
|
||||
#include "auto_init_priorities.h"
|
||||
|
||||
#include "architecture.h"
|
||||
#include "event/periodic_callback.h"
|
||||
#include "event/thread.h"
|
||||
#include "periph/wdt.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
static void _wdt_event_cb(void *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
wdt_kick();
|
||||
}
|
||||
|
||||
static void auto_init_wdt_event(void)
|
||||
{
|
||||
static event_periodic_callback_t wdt_event;
|
||||
unsigned sleep_ms = (CONFIG_PERIPH_WDT_WIN_MIN_MS + CONFIG_PERIPH_WDT_WIN_MAX_MS)
|
||||
/ 2;
|
||||
|
||||
event_periodic_callback_init(&wdt_event, ZTIMER_MSEC, EVENT_PRIO_LOWEST, _wdt_event_cb, NULL);
|
||||
event_periodic_callback_start(&wdt_event, sleep_ms);
|
||||
}
|
||||
|
||||
AUTO_INIT(auto_init_wdt_event, AUTO_INIT_PRIO_WDT_EVENT);
|
3
sys/auto_init/wdt_thread/Makefile
Normal file
3
sys/auto_init/wdt_thread/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = auto_init_wdt_thread
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
58
sys/auto_init/wdt_thread/wdt.c
Normal file
58
sys/auto_init/wdt_thread/wdt.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ML!PA Consulting GmbH
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_auto_init
|
||||
* @{
|
||||
*
|
||||
* @file wdt.c
|
||||
* @brief Watchdog Thread
|
||||
*
|
||||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "auto_init.h"
|
||||
#include "auto_init_utils.h"
|
||||
#include "auto_init_priorities.h"
|
||||
|
||||
#include "architecture.h"
|
||||
#include "periph/wdt.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
#ifndef WDT_THREAD_STACKSIZE
|
||||
#if DEVELHELP
|
||||
#define WDT_THREAD_STACKSIZE THREAD_STACKSIZE_SMALL
|
||||
#else
|
||||
#define WDT_THREAD_STACKSIZE THREAD_STACKSIZE_TINY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static char WORD_ALIGNED wdt_stack[WDT_THREAD_STACKSIZE];
|
||||
|
||||
static void *_wdt_thread(void *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
unsigned sleep_ms = (CONFIG_PERIPH_WDT_WIN_MIN_MS + CONFIG_PERIPH_WDT_WIN_MAX_MS)
|
||||
/ 2;
|
||||
while (1) {
|
||||
ztimer_sleep(ZTIMER_MSEC, sleep_ms);
|
||||
wdt_kick();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void auto_init_wdt_thread(void)
|
||||
{
|
||||
thread_create(wdt_stack, sizeof(wdt_stack), THREAD_PRIORITY_MIN,
|
||||
THREAD_CREATE_STACKTEST, _wdt_thread, NULL, "watchdog");
|
||||
}
|
||||
|
||||
AUTO_INIT(auto_init_wdt_thread, AUTO_INIT_PRIO_WDT_THREAD);
|
Loading…
Reference in New Issue
Block a user