sched/misc:add linux-like reboot notifier list
Signed-off-by: 田昕 <tianxin7@xiaomi.com>
This commit is contained in:
parent
5d643b3bef
commit
96a45e2c75
@ -23,3 +23,4 @@ in other header files.
|
||||
paging.rst
|
||||
led.rst
|
||||
iob.rst
|
||||
notifier.rst
|
||||
|
95
Documentation/reference/os/notifier.rst
Normal file
95
Documentation/reference/os/notifier.rst
Normal 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.
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
}
|
||||
|
87
include/nuttx/reboot_notifier.h
Normal file
87
include/nuttx/reboot_notifier.h
Normal 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 */
|
||||
|
@ -18,7 +18,7 @@
|
||||
#
|
||||
############################################################################
|
||||
|
||||
CSRCS += assert.c panic_notifier.c
|
||||
CSRCS += assert.c panic_notifier.c reboot_notifier.c
|
||||
|
||||
# Include init build support
|
||||
|
||||
|
@ -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
|
||||
|
87
sched/misc/reboot_notifier.c
Normal file
87
sched/misc/reboot_notifier.c
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user