sched/misc:add linux-like reboot notifier list

Signed-off-by: 田昕 <tianxin7@xiaomi.com>
This commit is contained in:
田昕 2022-12-29 15:38:13 +08:00 committed by Xiang Xiao
parent 5d643b3bef
commit 96a45e2c75
8 changed files with 344 additions and 1 deletions

View File

@ -23,3 +23,4 @@ in other header files.
paging.rst
led.rst
iob.rst
notifier.rst

View File

@ -0,0 +1,95 @@
===========
Notifier Chain
===========
NuttX provides a callback list mechanism called *Notifier Chain*.
Notifier chain is essentially a list of callbacks used at certain times,
such as system asserting, powering off and restarting.
**Notifier chain** is very much like the Linux notifier chains, except
for some implementation differences.
Classes of Notifier Chain
======================
There are currently two different classes of notifier.
Atomic notifier chains
-------------------------------
Atomic notifier chains: Chain callbacks run in interrupt/atomic context.
In Nuttx, callouts are allowed to block(In Linux, callouts in atomic
notifier chain are not allowed to block). One example of an Atomic notifier
chain is turning off FPU when asserting.
Blocking notifier chains:
------------------------------
Blocking notifier chains: Chain callbacks run in process context.
Callouts are allowed to block. One example of a blocking notifier chain
is when an orderly powering off is needed.
Common Notifier Chain Interfaces
============================
Notifier Block Types
--------------------------
- ``struct notifier_block``. Defines one notifier callback entry.
Notifier Chain Interfaces
---------------------
.. c:function:: void panic_notifier_chain_register(FAR struct notifier_block *nb)
Add notifier to the panic notifier chain.
The panic notifier chain is an atomic notifier chain. It will be called
when asserting.
:param nb: New entry in notifier chain.
.. c:function:: void panic_notifier_chain_unregister(FAR struct notifier_block *nb)
Remove notifier from the panic notifier chain.
The panic notifier chain is an atomic notifier chain. It will be called
when asserting.
:param nh: Entry to remove from notifier chain.
.. c:function:: void panic_notifier_call_chain(unsigned long action, FAR void *data)
Call functions in the panic notifier chain.
The panic notifier chain is an atomic notifier chain. It will be called
when asserting.
:param action: Value passed unmodified to notifier function.
:param data: Pointer passed unmodified to notifier function.
.. c:function:: void register_reboot_notifier(FAR struct notifier_block *nb)
Add notifier to the reboot notifier chain.
The reboot notifier chain is an atomic notifier chain.
:param nb: New entry in notifier chain.
.. c:function:: void unregister_reboot_notifier(FAR struct notifier_block *nb)
Remove notifier from the reboot notifier chain.
The reboot notifier chain is an atomic notifier chain.
:param nh: Entry to remove from notifier chain.
.. c:function:: void reboot_notifier_call_chain(unsigned long action, FAR void *data)
Call functions in the reboot notifier chain.
The reboot notifier chain is an atomic notifier chain.
:param action: Value passed unmodified to notifier function.
:param data: Pointer passed unmodified to notifier function.

View File

@ -34,6 +34,7 @@
#include <nuttx/lib/modlib.h>
#include <nuttx/binfmt/symtab.h>
#include <nuttx/drivers/ramdisk.h>
#include <nuttx/reboot_notifier.h>
#ifdef CONFIG_NX
# include <nuttx/nx/nxmu.h>
@ -361,6 +362,7 @@ int boardctl(unsigned int cmd, uintptr_t arg)
case BOARDIOC_POWEROFF:
{
reboot_notifier_call_chain(SYS_POWER_OFF, (FAR void *)arg);
ret = board_power_off((int)arg);
}
break;
@ -376,6 +378,7 @@ int boardctl(unsigned int cmd, uintptr_t arg)
case BOARDIOC_RESET:
{
reboot_notifier_call_chain(SYS_RESTART, (FAR void *)arg);
ret = board_reset((int)arg);
}
break;

View File

@ -27,6 +27,7 @@
#include <nuttx/config.h>
#include <nuttx/irq.h>
#include <nuttx/mutex.h>
#include <debug.h>
#include <errno.h>
@ -42,6 +43,14 @@
#define ATOMIC_NOTIFIER_HEAD(name) \
struct atomic_notifier_head name = ATOMIC_NOTIFIER_INIT(name)
#define BLOCKING_NOTIFIER_INIT(name) { \
NXMUTEX_INITIALIZER, \
NULL \
}
#define BLOCKING_NOTIFIER_HEAD(name) \
struct blocking_notifier_head name = BLOCKING_NOTIFIER_INIT(name)
/****************************************************************************
* Public Type Definitions
****************************************************************************/
@ -63,6 +72,12 @@ struct atomic_notifier_head
FAR struct notifier_block *head;
};
struct blocking_notifier_head
{
mutex_t mutex;
FAR struct notifier_block *head;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@ -192,6 +207,58 @@ extern "C"
} \
while(0)
#define blocking_notifier_chain_register(nhead, nb) \
do \
{ \
FAR struct blocking_notifier_head *nh = (nhead); \
if (nxmutex_lock(&nh->mutex) < 0) \
{ \
break; \
} \
notifier_chain_register(nh->head, (nb), false); \
nxmutex_unlock(&nh->mutex);\
} \
while(0)
#define blocking_notifier_chain_register_uniqueprio(nhead, nb) \
do \
{ \
FAR struct blocking_notifier_head *nh = (nhead); \
if (nxmutex_lock(&nh->mutex) < 0) \
{ \
break; \
} \
notifier_chain_register(nh->head, (nb), true); \
nxmutex_unlock(&nh->mutex);\
} \
while(0)
#define blocking_notifier_chain_unregister(nhead, nb) \
do \
{ \
FAR struct blocking_notifier_head *nh = (nhead); \
if (nxmutex_lock(&nh->mutex) < 0) \
{ \
break; \
} \
notifier_chain_unregister(nh->head, (nb)); \
nxmutex_unlock(&nh->mutex);\
} \
while(0)
#define blocking_notifier_call_chain(nhead, val, v) \
do \
{ \
FAR struct blocking_notifier_head *nh = (nhead); \
if (nxmutex_lock(&nh->mutex) < 0) \
{ \
break; \
} \
notifier_call_chain(nh->head, (val), (v), -1, NULL); \
nxmutex_unlock(&nh->mutex);\
} \
while(0)
#undef EXTERN
#if defined(__cplusplus)
}

View File

@ -0,0 +1,87 @@
/****************************************************************************
* include/nuttx/reboot_notifier.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_REBOOT_NOTIFIER_H
#define __INCLUDE_NUTTX_REBOOT_NOTIFIER_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/notifier.h>
#include <sys/types.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define SYS_DOWN 0x0001 /* Notify of system down */
#define SYS_RESTART SYS_DOWN
#define SYS_HALT 0x0002 /* Notify of system halt */
#define SYS_POWER_OFF 0x0003 /* Notify of system power off */
/****************************************************************************
* Public Function
****************************************************************************/
/****************************************************************************
* Name: register_reboot_notifier
*
* Description:
* Add notifier to the reboot notifier chain
*
* Input Parameters:
* nb - New entry in notifier chain
*
****************************************************************************/
void register_reboot_notifier(FAR struct notifier_block *nb);
/****************************************************************************
* Name: unregister_reboot_notifier
*
* Description:
* Remove notifier from the reboot notifier chain
*
* Input Parameters:
* nb - Entry to remove from notifier chain
*
****************************************************************************/
void unregister_reboot_notifier(FAR struct notifier_block *nb);
/****************************************************************************
* Name: reboot_notifier_call_chain
*
* Description:
* Call functions in the reboot notifier chain.
*
* Input Parameters:
* action - Value passed unmodified to notifier function
* data - Pointer passed unmodified to notifier function
*
****************************************************************************/
void reboot_notifier_call_chain(unsigned long action, FAR void *data);
#endif /* __INCLUDE_NUTTX_REBOOT_NOTIFIER_H */

View File

@ -18,7 +18,7 @@
#
############################################################################
CSRCS += assert.c panic_notifier.c
CSRCS += assert.c panic_notifier.c reboot_notifier.c
# Include init build support

View File

@ -30,6 +30,7 @@
#include <nuttx/tls.h>
#include <nuttx/panic_notifier.h>
#include <nuttx/reboot_notifier.h>
#include <nuttx/syslog/syslog.h>
#include <nuttx/usb/usbdev_trace.h>
@ -518,6 +519,8 @@ void _assert(FAR const char *filename, int linenum)
syslog_flush();
reboot_notifier_call_chain(SYS_HALT, NULL);
#if CONFIG_BOARD_RESET_ON_ASSERT >= 1
board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE);
#else

View File

@ -0,0 +1,87 @@
/****************************************************************************
* sched/misc/reboot_notifier.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/arch.h>
#include <nuttx/notifier.h>
#include <sys/types.h>
/****************************************************************************
* Private Data
****************************************************************************/
static ATOMIC_NOTIFIER_HEAD(g_reboot_notifier_list);
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: register_reboot_notifier
*
* Description:
* Add notifier to the reboot notifier chain
*
* Input Parameters:
* nb - New entry in notifier chain
*
****************************************************************************/
void register_reboot_notifier(FAR struct notifier_block *nb)
{
atomic_notifier_chain_register(&g_reboot_notifier_list, nb);
}
/****************************************************************************
* Name: unregister_reboot_notifier
*
* Description:
* Remove notifier from the reboot notifier chain
*
* Input Parameters:
* nb - Entry to remove from notifier chain
*
****************************************************************************/
void unregister_reboot_notifier(FAR struct notifier_block *nb)
{
atomic_notifier_chain_unregister(&g_reboot_notifier_list, nb);
}
/****************************************************************************
* Name: reboot_notifier_call_chain
*
* Description:
* Call functions in the reboot notifier chain.
*
* Input Parameters:
* action - Value passed unmodified to notifier function
* data - Pointer passed unmodified to notifier function
*
****************************************************************************/
void reboot_notifier_call_chain(unsigned long action, FAR void *data)
{
atomic_notifier_call_chain(&g_reboot_notifier_list, action, data);
}