Compare commits

...

3 commits

Author SHA1 Message Date
Mike.
610348a38f
Merge 0f70c44b4a into 43797ea6cc 2025-01-12 11:15:45 +08:00
yaojiaqi
43797ea6cc drivers/timers/watchdog: add watchdog timer notifier chain
Add support for watchdog timer notifer chain so that users
can customize the callback function when the watchdog timer
times out which enabled by Auto-monitor

Signed-off-by: yaojiaqi <yaojiaqi@lixiang.com>
2025-01-12 11:15:42 +08:00
wangmingrong1
0f70c44b4a mm: Add pending configuration for mm node struct and precding
pending memory block node precding and the entire struct, after turning on this bit, the size of each memory block wil be aligned to MM_ALIGN

Signed-off-by: wangmingrong1 <wangmingrong1@xiaomi.com>
2025-01-10 11:50:47 +08:00
5 changed files with 185 additions and 3 deletions

View file

@ -439,6 +439,14 @@ menuconfig WATCHDOG_AUTOMONITOR
if WATCHDOG_AUTOMONITOR
config WATCHDOG_TIMEOUT_NOTIFIER
bool "Enable watchdog timeout notifier"
default n
---help---
The watchdog timeout notifier chain mechanism supports users registering
custom callback functions, which will be called when the watchdog timer
managed by Auto-monitor times out.
choice
prompt "Auto-monitor keepalive by"
default WATCHDOG_AUTOMONITOR_BY_WDOG

View file

@ -71,6 +71,20 @@
# endif
#endif
#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_ONESHOT)
# define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_ONESHOT
#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
# define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_TIMER
#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
# define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_WDOG
#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WORKER)
# define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_WORKER
#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_CAPTURE)
# define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_CAPTURE
#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
# define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_IDLE
#endif
/****************************************************************************
* Private Type Definitions
****************************************************************************/
@ -135,6 +149,10 @@ static const struct file_operations g_wdogops =
wdog_ioctl, /* ioctl */
};
#ifdef CONFIG_WATCHDOG_TIMEOUT_NOTIFIER
static ATOMIC_NOTIFIER_HEAD(g_watchdog_notifier_list);
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
@ -699,6 +717,55 @@ static int wdog_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
* Public Functions
****************************************************************************/
#ifdef CONFIG_WATCHDOG_TIMEOUT_NOTIFIER
/****************************************************************************
* Name: watchdog_notifier_chain_register
*
* Description:
* Add notifier to the watchdog notifier chain
*
* Input Parameters:
* nb - New entry in notifier chain
*
****************************************************************************/
void watchdog_notifier_chain_register(FAR struct notifier_block *nb)
{
atomic_notifier_chain_register(&g_watchdog_notifier_list, nb);
}
/****************************************************************************
* Name: watchdog_notifier_chain_unregister
*
* Description:
* Remove notifier from the watchdog notifier chain
*
* Input Parameters:
* nb - Entry to remove from notifier chain
*
****************************************************************************/
void watchdog_notifier_chain_unregister(FAR struct notifier_block *nb)
{
atomic_notifier_chain_unregister(&g_watchdog_notifier_list, nb);
}
/****************************************************************************
* Name: watchdog_automonitor_timeout
*
* Description:
* This function can be called in the watchdog timeout interrupt handler.
* If so, callbacks on the watchdog timer notify chain are called when the
* watchdog timer times out.
*
****************************************************************************/
void watchdog_automonitor_timeout(void)
{
atomic_notifier_call_chain(&g_watchdog_notifier_list, action, data);
}
#endif /* CONFIG_WATCHDOG_TIMEOUT_NOTIFIER */
/****************************************************************************
* Name: watchdog_register
*

View file

@ -31,6 +31,7 @@
#include <nuttx/compiler.h>
#include <nuttx/irq.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/notifier.h>
#ifdef CONFIG_WATCHDOG
@ -88,6 +89,35 @@
#define WDFLAGS_CAPTURE (1 << 2) /* 1=Call the user function when the
* watchdog timer expires */
/* Keepalive Actions ********************************************************/
/* According to the keepalive action specified by the Auto-monitor, callback
* functions registered on the watchdog notifier chain may take corresponding
* actions.
*
* These are detected and handled by the "upper half" watchdog timer driver.
*
* WATCHDOG_KEEPALIVE_BY_ONESHOT - The watchdog timer is keepalive by
* oneshot timer.
* WATCHDOG_KEEPALIVE_BY_TIMER - The watchdog timer is keepalive by
* timer.
* WATCHDOG_KEEPALIVE_BY_WDOG - The watchdog timer is keepalive by
* wdog.
* WATCHDOG_KEEPALIVE_BY_WORKER - The watchdog timer is keepalive by
* worker queue.
* WATCHDOG_KEEPALIVE_BY_CAPTURE - The watchdog timer is keepalive by
* capture.
* WATCHDOG_KEEPALIVE_BY_IDLE - The watchdog timer is keepalive by
* idle task.
*/
#define WATCHDOG_KEEPALIVE_BY_ONESHOT 0
#define WATCHDOG_KEEPALIVE_BY_TIMER 1
#define WATCHDOG_KEEPALIVE_BY_WDOG 2
#define WATCHDOG_KEEPALIVE_BY_WORKER 3
#define WATCHDOG_KEEPALIVE_BY_CAPTURE 4
#define WATCHDOG_KEEPALIVE_BY_IDLE 5
/****************************************************************************
* Public Types
****************************************************************************/
@ -197,6 +227,47 @@ extern "C"
#define EXTERN extern
#endif
#ifdef CONFIG_WATCHDOG_TIMEOUT_NOTIFIER
/****************************************************************************
* Name: watchdog_notifier_chain_register
*
* Description:
* Add notifier to the watchdog notifier chain
*
* Input Parameters:
* nb - New entry in notifier chain
*
****************************************************************************/
void watchdog_notifier_chain_register(FAR struct notifier_block *nb);
/****************************************************************************
* Name: watchdog_notifier_chain_unregister
*
* Description:
* Remove notifier from the watchdog notifier chain
*
* Input Parameters:
* nb - Entry to remove from notifier chain
*
****************************************************************************/
void watchdog_notifier_chain_unregister(FAR struct notifier_block *nb);
/****************************************************************************
* Name: watchdog_automonitor_timeout
*
* Description:
* This function can be called in the watchdog timeout interrupt handler.
* If so, callbacks on the watchdog timer notify chain are called when the
* watchdog timer times out.
*
****************************************************************************/
void watchdog_automonitor_timeout(void);
#endif /* CONFIG_WATCHDOG_TIMEOUT_NOTIFIER */
/****************************************************************************
* Name: watchdog_register
*

View file

@ -69,6 +69,14 @@ config MM_DEFAULT_ALIGNMENT
memory default alignment is equal to sizoef(uintptr), if this value
is not 0, this value must be 2^n and at least sizeof(uintptr).
config MM_NODE_PENDING
bool "Enable pending memory node"
default n
---help---
Pending memory block node precding and the entire struct,
After turning on this bit, the size of each memory block
will be aligned to MM_ALIGN
config MM_SMALL
bool "Small memory model"
default n

View file

@ -143,7 +143,17 @@
* previous freenode
*/
#define MM_ALLOCNODE_OVERHEAD (MM_SIZEOF_ALLOCNODE - sizeof(mmsize_t))
#ifdef CONFIG_MM_NODE_PENDING
# define MM_NODE_STRUCT_PENDING aligned_data(MM_ALIGN)
#else
# define MM_NODE_STRUCT_PENDING
#endif
#ifdef CONFIG_MM_NODE_PENDING
# define MM_ALLOCNODE_OVERHEAD (MM_SIZEOF_ALLOCNODE - MM_ALIGN)
#else
# define MM_ALLOCNODE_OVERHEAD (MM_SIZEOF_ALLOCNODE - sizeof(mmsize_t))
#endif
/* Get the node size */
@ -173,7 +183,16 @@ typedef size_t mmsize_t;
struct mm_allocnode_s
{
#ifdef CONFIG_MM_NODE_PENDING
union
{
mmsize_t preceding; /* Physical preceding chunk size */
uint8_t align[MM_ALIGN];
};
#else
mmsize_t preceding; /* Physical preceding chunk size */
#endif
mmsize_t size; /* Size of this chunk */
#if CONFIG_MM_BACKTRACE >= 0
pid_t pid; /* The pid for caller */
@ -182,13 +201,22 @@ struct mm_allocnode_s
FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */
# endif
#endif
};
}MM_NODE_STRUCT_PENDING;
/* This describes a free chunk */
struct mm_freenode_s
{
#ifdef CONFIG_MM_NODE_PENDING
union
{
mmsize_t preceding; /* Physical preceding chunk size */
uint8_t align[MM_ALIGN];
};
#else
mmsize_t preceding; /* Physical preceding chunk size */
#endif
mmsize_t size; /* Size of this chunk */
#if CONFIG_MM_BACKTRACE >= 0
pid_t pid; /* The pid for caller */
@ -199,7 +227,7 @@ struct mm_freenode_s
#endif
FAR struct mm_freenode_s *flink; /* Supports a doubly linked list */
FAR struct mm_freenode_s *blink;
};
}MM_NODE_STRUCT_PENDING;
static_assert(MM_SIZEOF_ALLOCNODE <= MM_MIN_CHUNK,
"Error size for struct mm_allocnode_s\n");