diff --git a/drivers/syslog/Kconfig b/drivers/syslog/Kconfig index 718c857c1a..ba00c0f83c 100644 --- a/drivers/syslog/Kconfig +++ b/drivers/syslog/Kconfig @@ -288,6 +288,10 @@ config SYSLOG_RPMSG_SERVER ---help--- Use rpmsg to receive message from remote proc. +config SYSLOG_RPMSG_SERVER_CHARDEV + bool "SYSLOG rpmsg server character device" + default n + menuconfig SYSLOG_FILE bool "Syslog file output" default n diff --git a/drivers/syslog/syslog_rpmsg.c b/drivers/syslog/syslog_rpmsg.c index 55912ab0fd..b97b7218a2 100644 --- a/drivers/syslog/syslog_rpmsg.c +++ b/drivers/syslog/syslog_rpmsg.c @@ -290,6 +290,11 @@ static int syslog_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept, priv->suspend = false; work_queue(HPWORK, &priv->work, syslog_rpmsg_work, priv, 0); } + else if (header->command == SYSLOG_RPMSG_SYNC) + { + syslog_rpmsg_transfer(priv, true); + rpmsg_send(ept, data, len); + } return 0; } diff --git a/drivers/syslog/syslog_rpmsg.h b/drivers/syslog/syslog_rpmsg.h index 93b464a029..b410a8d7db 100644 --- a/drivers/syslog/syslog_rpmsg.h +++ b/drivers/syslog/syslog_rpmsg.h @@ -30,6 +30,7 @@ #define SYSLOG_RPMSG_TRANSFER 0 #define SYSLOG_RPMSG_SUSPEND 1 #define SYSLOG_RPMSG_RESUME 2 +#define SYSLOG_RPMSG_SYNC 3 /**************************************************************************** * Public Types @@ -48,4 +49,10 @@ begin_packed_struct struct syslog_rpmsg_transfer_s char data[0]; } end_packed_struct; +begin_packed_struct struct syslog_rpmsg_sync_s +{ + struct syslog_rpmsg_header_s header; + uint64_t cookie; +} end_packed_struct; + #endif /* __DRIVERS_SYSLOG_SYSLOG_RPMSG_H */ diff --git a/drivers/syslog/syslog_rpmsg_server.c b/drivers/syslog/syslog_rpmsg_server.c index bac0edb193..bef35833d8 100644 --- a/drivers/syslog/syslog_rpmsg_server.c +++ b/drivers/syslog/syslog_rpmsg_server.c @@ -26,7 +26,10 @@ #include +#include #include +#include +#include #include #include @@ -45,6 +48,9 @@ struct syslog_rpmsg_server_s { +#ifdef CONFIG_SYSLOG_RPMSG_SERVER_CHARDEV + struct list_node node; +#endif struct rpmsg_endpoint ept; FAR char *tmpbuf; unsigned int nextpos; @@ -64,11 +70,69 @@ static void syslog_rpmsg_ns_unbind(FAR struct rpmsg_endpoint *ept); static int syslog_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv_); +#ifdef CONFIG_SYSLOG_RPMSG_SERVER_CHARDEV +static int syslog_rpmsg_file_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_SYSLOG_RPMSG_SERVER_CHARDEV +static struct list_node g_list = LIST_INITIAL_VALUE(g_list); +static mutex_t g_lock = NXMUTEX_INITIALIZER; + +static const struct file_operations g_syslog_rpmsg_fops = +{ + NULL, /* open */ + NULL, /* close */ + NULL, /* read */ + NULL, /* write */ + NULL, /* seek */ + syslog_rpmsg_file_ioctl, /* ioctl */ + NULL /* poll */ +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL /* unlink */ +#endif +}; /**************************************************************************** * Private Functions ****************************************************************************/ +static int syslog_rpmsg_file_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + FAR struct syslog_rpmsg_server_s *priv; + struct syslog_rpmsg_sync_s msg; + sem_t sem; + + if (cmd != FIOC_DUMP) + { + return -ENOTTY; + } + + nxsem_init(&sem, 0, 0); + nxsem_set_protocol(&sem, SEM_PRIO_NONE); + + nxmutex_lock(&g_lock); + list_for_every_entry(&g_list, priv, struct syslog_rpmsg_server_s, node) + { + msg.cookie = (uint64_t)(uintptr_t)&sem; + msg.header.command = SYSLOG_RPMSG_SYNC; + if (rpmsg_send(&priv->ept, &msg, sizeof(msg)) >= 0) + { + rpmsg_wait(&priv->ept, &sem); + } + } + + nxmutex_unlock(&g_lock); + nxsem_destroy(&sem); + return OK; +} +#endif + static void syslog_rpmsg_write(FAR const char *buf1, size_t len1, FAR const char *buf2, size_t len2) { @@ -123,6 +187,12 @@ static void syslog_rpmsg_ns_bind(FAR struct rpmsg_device *rdev, priv->ept.priv = priv; +#ifdef CONFIG_SYSLOG_RPMSG_SERVER_CHARDEV + nxmutex_lock(&g_lock); + list_add_tail(&g_list, &priv->node); + nxmutex_unlock(&g_lock); +#endif + ret = rpmsg_create_ept(&priv->ept, rdev, SYSLOG_RPMSG_EPT_NAME, RPMSG_ADDR_ANY, dest, syslog_rpmsg_ept_cb, syslog_rpmsg_ns_unbind); @@ -143,6 +213,12 @@ static void syslog_rpmsg_ns_unbind(FAR struct rpmsg_endpoint *ept) rpmsg_destroy_ept(ept); +#ifdef CONFIG_SYSLOG_RPMSG_SERVER_CHARDEV + nxmutex_lock(&g_lock); + list_delete(&priv->node); + nxmutex_unlock(&g_lock); +#endif + kmm_free(priv->tmpbuf); kmm_free(priv); } @@ -200,6 +276,15 @@ static int syslog_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept, priv->nextpos += copied; } } +#ifdef CONFIG_SYSLOG_RPMSG_SERVER_CHARDEV + else if (header->command == SYSLOG_RPMSG_SYNC) + { + FAR struct syslog_rpmsg_sync_s *msg = data; + FAR sem_t *sem = (FAR sem_t *)(uintptr_t)msg->cookie; + + rpmsg_post(ept, sem); + } +#endif return 0; } @@ -210,6 +295,16 @@ static int syslog_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept, int syslog_rpmsg_server_init(void) { +#ifdef CONFIG_SYSLOG_RPMSG_SERVER_CHARDEV + int ret; + + ret = register_driver("/dev/logrpmsg", &g_syslog_rpmsg_fops, 0666, NULL); + if (ret < 0) + { + return ret; + } +#endif + return rpmsg_register_callback(NULL, NULL, NULL,