mirror of
https://github.com/apache/nuttx.git
synced 2025-01-12 22:08:35 +08:00
Compare commits
3 commits
e60c8e254a
...
02244947e8
Author | SHA1 | Date | |
---|---|---|---|
|
02244947e8 | ||
|
43797ea6cc | ||
|
1c1ef6908d |
7 changed files with 308 additions and 0 deletions
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -56,6 +57,12 @@
|
|||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct rptun_trace_s
|
||||
{
|
||||
FAR void *hdr;
|
||||
FAR void *backtrace[16];
|
||||
};
|
||||
|
||||
struct rptun_priv_s
|
||||
{
|
||||
struct rpmsg_s rpmsg;
|
||||
|
@ -64,6 +71,7 @@ struct rptun_priv_s
|
|||
struct remoteproc rproc;
|
||||
struct rpmsg_virtio_shm_pool pool[2];
|
||||
sem_t semtx;
|
||||
FAR struct rptun_trace_s *traces;
|
||||
sem_t semrx;
|
||||
pid_t tid;
|
||||
uint16_t headrx;
|
||||
|
@ -128,6 +136,20 @@ static void rptun_panic(FAR struct rpmsg_s *rpmsg);
|
|||
static void rptun_dump(FAR struct rpmsg_s *rpmsg);
|
||||
static FAR const char *rptun_get_local_cpuname(FAR struct rpmsg_s *rpmsg);
|
||||
static FAR const char *rptun_get_cpuname(FAR struct rpmsg_s *rpmsg);
|
||||
#ifdef CONFIG_OPENAMP_RPMSG_TRACE
|
||||
static void rptun_trace_init(FAR struct rptun_priv_s *priv);
|
||||
static void rptun_trace_uninit(FAR struct rptun_priv_s *priv);
|
||||
static void rptun_trace_get_tx_buffer(FAR struct rpmsg_device *rdev,
|
||||
FAR void *hdr);
|
||||
static void rptun_trace_release_tx_buffer(FAR struct rpmsg_device *rdev,
|
||||
FAR void *hdr);
|
||||
static void rptun_dump_trace(FAR struct rpmsg_virtio_device *rvdev);
|
||||
|
||||
#else
|
||||
# define rptun_trace_init(priv)
|
||||
# define rptun_trace_uninit(priv)
|
||||
# define rptun_dump_trace(rvdev);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
@ -722,6 +744,8 @@ static void rptun_dump(FAR struct rpmsg_s *rpmsg)
|
|||
metal_mutex_acquire(&rdev->lock);
|
||||
}
|
||||
|
||||
rptun_dump_trace(rvdev);
|
||||
|
||||
metal_log(METAL_LOG_EMERGENCY,
|
||||
"Dump rpmsg info between cpu (master: %s)%s <==> %s:\n",
|
||||
rpmsg_virtio_get_role(rvdev) == RPMSG_HOST ? "yes" : "no",
|
||||
|
@ -918,6 +942,7 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
|
|||
return ret;
|
||||
}
|
||||
|
||||
rptun_trace_init(priv);
|
||||
priv->rvdev.rdev.ns_unbind_cb = rpmsg_ns_unbind;
|
||||
priv->rvdev.notify_wait_cb = rptun_notify_wait;
|
||||
|
||||
|
@ -981,6 +1006,7 @@ static int rptun_dev_stop(FAR struct remoteproc *rproc, bool stop_ns)
|
|||
/* Remote proc stop and shutdown */
|
||||
|
||||
remoteproc_shutdown(rproc);
|
||||
rptun_trace_uninit(priv);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -1113,6 +1139,130 @@ static metal_phys_addr_t rptun_da_to_pa(FAR struct rptun_dev_s *dev,
|
|||
return da;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OPENAMP_RPMSG_TRACE
|
||||
static void *rptun_get_priv_by_rdev(FAR struct rpmsg_device *rdev)
|
||||
{
|
||||
FAR struct rpmsg_virtio_device *rvdev;
|
||||
FAR struct virtio_device *vdev;
|
||||
FAR struct remoteproc_virtio *rpvdev;
|
||||
FAR struct remoteproc *rproc;
|
||||
|
||||
if (!rdev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rvdev = metal_container_of(rdev, struct rpmsg_virtio_device, rdev);
|
||||
vdev = rvdev->vdev;
|
||||
if (!vdev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev);
|
||||
rproc = rpvdev->priv;
|
||||
if (!rproc)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rproc->priv;
|
||||
}
|
||||
|
||||
static void rptun_trace_init(FAR struct rptun_priv_s *priv)
|
||||
{
|
||||
int txnum = priv->rvdev.svq->vq_nentries;
|
||||
|
||||
priv->traces = kmm_zalloc(sizeof(*priv->traces) * txnum);
|
||||
DEBUGASSERT(priv->traces != NULL);
|
||||
|
||||
priv->rvdev.rdev.trace.get_tx_buffer = rptun_trace_get_tx_buffer;
|
||||
priv->rvdev.rdev.trace.release_tx_buffer = rptun_trace_release_tx_buffer;
|
||||
}
|
||||
|
||||
static void rptun_trace_uninit(FAR struct rptun_priv_s *priv)
|
||||
{
|
||||
priv->rvdev.rdev.trace.get_tx_buffer = NULL;
|
||||
priv->rvdev.rdev.trace.release_tx_buffer = NULL;
|
||||
|
||||
kmm_free(priv->traces);
|
||||
}
|
||||
|
||||
static void rptun_trace_get_tx_buffer(FAR struct rpmsg_device *rdev,
|
||||
FAR void *hdr)
|
||||
{
|
||||
FAR struct rptun_priv_s *priv = rptun_get_priv_by_rdev(rdev);
|
||||
int txnum = priv->rvdev.svq->vq_nentries;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < txnum; i++)
|
||||
{
|
||||
if (priv->traces[i].hdr == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= txnum)
|
||||
{
|
||||
metal_log(METAL_LOG_EMERGENCY, "Not find empty buffer i=%d num=%d\n",
|
||||
i, txnum);
|
||||
PANIC();
|
||||
}
|
||||
|
||||
priv->traces[i].hdr = hdr;
|
||||
backtrace(priv->traces[i].backtrace, 16);
|
||||
}
|
||||
|
||||
static void rptun_trace_release_tx_buffer(FAR struct rpmsg_device *rdev,
|
||||
FAR void *hdr)
|
||||
{
|
||||
FAR struct rptun_priv_s *priv = rptun_get_priv_by_rdev(rdev);
|
||||
int txnum = priv->rvdev.svq->vq_nentries;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < txnum; i++)
|
||||
{
|
||||
if (priv->traces[i].hdr == hdr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= txnum)
|
||||
{
|
||||
metal_log(METAL_LOG_EMERGENCY, "Not find tx buffer i=%d num=%d\n",
|
||||
i, txnum);
|
||||
PANIC();
|
||||
}
|
||||
|
||||
priv->traces[i].hdr = NULL;
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
priv->traces[i].backtrace[j] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void rptun_dump_trace(FAR struct rpmsg_virtio_device *rvdev)
|
||||
{
|
||||
FAR struct rptun_priv_s *priv = rptun_get_priv_by_rdev(&rvdev->rdev);
|
||||
char backtrace[256];
|
||||
int txnum = rvdev->svq->vq_nentries;
|
||||
int i;
|
||||
|
||||
metal_log(METAL_LOG_EMERGENCY, "Dump not released tx buffer:\n");
|
||||
for (i = 0; i < txnum; i++)
|
||||
{
|
||||
backtrace_format(backtrace, sizeof(backtrace),
|
||||
priv->traces[i].backtrace, 16);
|
||||
metal_log(METAL_LOG_EMERGENCY, "hdr: %p backtrace: %s\n",
|
||||
priv->traces[i].hdr, backtrace);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -30,4 +30,8 @@ config OPENAMP_VIRTIO_DRIVER_SUPPORT
|
|||
bool "Enable VIRTIO_DRIVER_SUPPORT"
|
||||
default y
|
||||
|
||||
config OPENAMP_RPMSG_TRACE
|
||||
bool "Enable OpenAMP Rpmsg Trace"
|
||||
default n
|
||||
|
||||
endif # OPENAMP
|
||||
|
|
|
@ -113,3 +113,7 @@ target_include_directories(
|
|||
open_amp-static PRIVATE $<TARGET_PROPERTY:metal-static,INCLUDE_DIRECTORIES>)
|
||||
|
||||
nuttx_add_external_library(open_amp-static MODE KERNEL)
|
||||
|
||||
if(CONFIG_OPENAMP_RPMSG_TRACE)
|
||||
target_compile_options(openamp PRIVATE -DRPMSG_TRACE)
|
||||
endif()
|
||||
|
|
|
@ -44,6 +44,10 @@ else
|
|||
CFLAGS += -DVIRTIO_DRIVER_SUPPORT=0
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_OPENAMP_RPMSG_TRACE),y)
|
||||
CFLAGS += -DRPMSG_TRACE
|
||||
endif
|
||||
|
||||
CSRCS += open-amp/lib/remoteproc/elf_loader.c
|
||||
CSRCS += open-amp/lib/remoteproc/remoteproc.c
|
||||
CSRCS += open-amp/lib/remoteproc/remoteproc_virtio.c
|
||||
|
|
Loading…
Reference in a new issue