From efd1b838e6d2606a0bfcd46d4b714c5bf801da73 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Wed, 21 Jun 2023 08:16:55 +0800 Subject: [PATCH] syslog: Add sc_write_force callback It is used to write the log message to the channel immediately when the log message is generated in the interrupt context, which is faster than the normal force callback. Signed-off-by: Xiang Xiao --- drivers/syslog/syslog_channel.c | 5 ++- drivers/syslog/syslog_device.c | 1 + drivers/syslog/syslog_flush.c | 8 +++-- drivers/syslog/syslog_putc.c | 34 +++++++++++++++----- drivers/syslog/syslog_stream.c | 28 ++--------------- drivers/syslog/syslog_write.c | 56 +++++++++++++++++++-------------- include/nuttx/syslog/syslog.h | 11 ++++--- 7 files changed, 75 insertions(+), 68 deletions(-) diff --git a/drivers/syslog/syslog_channel.c b/drivers/syslog/syslog_channel.c index 44a81a5d81e..88ee9b98f0c 100644 --- a/drivers/syslog/syslog_channel.c +++ b/drivers/syslog/syslog_channel.c @@ -91,6 +91,7 @@ static const struct syslog_channel_ops_s g_rpmsg_channel_ops = syslog_rpmsg_putc, syslog_rpmsg_putc, syslog_rpmsg_flush, + syslog_rpmsg_write, syslog_rpmsg_write }; @@ -106,6 +107,7 @@ static const struct syslog_channel_ops_s g_rtt_channel_ops = syslog_rtt_putc, syslog_rtt_putc, NULL, + syslog_rtt_write, syslog_rtt_write }; @@ -262,9 +264,6 @@ int syslog_channel(FAR struct syslog_channel_s *channel) if (channel != NULL) { - DEBUGASSERT(channel->sc_ops->sc_putc != NULL && - channel->sc_ops->sc_force != NULL); - #if (CONFIG_SYSLOG_MAX_CHANNELS == 1) g_syslog_channel[0] = channel; return OK; diff --git a/drivers/syslog/syslog_device.c b/drivers/syslog/syslog_device.c index e1057390ac5..2031ca136c5 100644 --- a/drivers/syslog/syslog_device.c +++ b/drivers/syslog/syslog_device.c @@ -106,6 +106,7 @@ static const struct syslog_channel_ops_s g_syslog_dev_ops = syslog_dev_force, syslog_dev_flush, syslog_dev_write, + NULL, syslog_dev_uninitialize }; diff --git a/drivers/syslog/syslog_flush.c b/drivers/syslog/syslog_flush.c index c63b4873fd1..0ff263d2a0f 100644 --- a/drivers/syslog/syslog_flush.c +++ b/drivers/syslog/syslog_flush.c @@ -76,16 +76,18 @@ int syslog_flush(void) for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) { - if (g_syslog_channel[i] == NULL) + FAR struct syslog_channel_s *channel = g_syslog_channel[i]; + + if (channel == NULL) { break; } /* Then flush all of the buffered output to the SYSLOG device */ - if (g_syslog_channel[i]->sc_ops->sc_flush != NULL) + if (channel->sc_ops->sc_flush != NULL) { - g_syslog_channel[i]->sc_ops->sc_flush(g_syslog_channel[i]); + channel->sc_ops->sc_flush(channel); } } diff --git a/drivers/syslog/syslog_putc.c b/drivers/syslog/syslog_putc.c index f5855e285c5..633a71c508c 100644 --- a/drivers/syslog/syslog_putc.c +++ b/drivers/syslog/syslog_putc.c @@ -83,15 +83,24 @@ int syslog_putc(int ch) for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) { - if (g_syslog_channel[i] == NULL) + FAR struct syslog_channel_s *channel = g_syslog_channel[i]; + + if (channel == NULL) { break; } - DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_force != NULL); + if (channel->sc_ops->sc_force != NULL) + { + channel->sc_ops->sc_force(channel, ch); + } + else + { + char tmp = ch; - g_syslog_channel[i]->sc_ops->sc_force(g_syslog_channel[i], - ch); + DEBUGASSERT(channel->sc_ops->sc_write_force != NULL); + channel->sc_ops->sc_write_force(channel, &tmp, 1); + } } } } @@ -107,14 +116,23 @@ int syslog_putc(int ch) for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) { - if (g_syslog_channel[i] == NULL) + FAR struct syslog_channel_s *channel = g_syslog_channel[i]; + + if (channel == NULL) { break; } - DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_putc != NULL); - - g_syslog_channel[i]->sc_ops->sc_putc(g_syslog_channel[i], ch); + if (channel->sc_ops->sc_putc != NULL) + { + channel->sc_ops->sc_putc(channel, ch); + } + else + { + char tmp = ch; + DEBUGASSERT(channel->sc_ops->sc_write != NULL); + channel->sc_ops->sc_write(channel, &tmp, 1); + } } } diff --git a/drivers/syslog/syslog_stream.c b/drivers/syslog/syslog_stream.c index 04e3d5f251f..6d20513807d 100644 --- a/drivers/syslog/syslog_stream.c +++ b/drivers/syslog/syslog_stream.c @@ -63,9 +63,10 @@ void syslog_stream_uninit(FAR struct syslog_channel_s *channel); static const struct syslog_channel_ops_s g_syslog_stream_ops = { syslog_stream_putc, - syslog_stream_force, + NULL, syslog_stream_flush, syslog_stream_write, + syslog_stream_write, syslog_stream_uninit }; @@ -135,31 +136,6 @@ static int syslog_stream_putc(FAR struct syslog_channel_s *channel, int ch) return OK; } -/**************************************************************************** - * Name: syslog_stream_force - * - * Description: - * Force output in interrupt context. - * - * Input Parameters: - * channel - Handle to syslog channel to be used. - * ch - The character to add to the SYSLOG (must be positive). - * - * Returned Value: - * On success, the character is echoed back to the caller. A negated - * errno value is returned on any failure. - * - ****************************************************************************/ - -static int syslog_stream_force(FAR struct syslog_channel_s *channel, int ch) -{ - FAR struct syslog_stream_s *chan = - (FAR struct syslog_stream_s *)channel; - - lib_stream_putc(chan->stream, ch); - return OK; -} - /**************************************************************************** * Name: syslog_stream_flush * diff --git a/drivers/syslog/syslog_write.c b/drivers/syslog/syslog_write.c index 9bc320fbbea..b7da658db83 100644 --- a/drivers/syslog/syslog_write.c +++ b/drivers/syslog/syslog_write.c @@ -57,31 +57,43 @@ static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen) { - int i; size_t nwritten = 0; + int i; if (up_interrupt_context() || sched_idletask()) { - for (nwritten = 0; nwritten < buflen; nwritten++) - { #ifdef CONFIG_SYSLOG_INTBUFFER - if (up_interrupt_context()) + if (up_interrupt_context()) + { + for (nwritten = 0; nwritten < buflen; nwritten++) { syslog_add_intbuffer(buffer[nwritten]); } - else + } + else #endif + { + for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) { - for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) - { - if (g_syslog_channel[i] == NULL) - { - break; - } + FAR struct syslog_channel_s *channel = g_syslog_channel[i]; - DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_force != NULL); - g_syslog_channel[i]->sc_ops->sc_force(g_syslog_channel[i], - buffer[nwritten]); + if (channel == NULL) + { + break; + } + + if (channel->sc_ops->sc_write_force != NULL) + { + nwritten = + channel->sc_ops->sc_write_force(channel, buffer, buflen); + } + else + { + DEBUGASSERT(channel->sc_ops->sc_force != NULL); + for (nwritten = 0; nwritten < buflen; nwritten++) + { + channel->sc_ops->sc_force(channel, buffer[nwritten]); + } } } } @@ -90,25 +102,23 @@ static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen) { for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) { - if (g_syslog_channel[i] == NULL) + FAR struct syslog_channel_s *channel = g_syslog_channel[i]; + + if (channel == NULL) { break; } - if (g_syslog_channel[i]->sc_ops->sc_write) + if (channel->sc_ops->sc_write != NULL) { - nwritten = - g_syslog_channel[i]->sc_ops->sc_write(g_syslog_channel[i], - buffer, buflen); + nwritten = channel->sc_ops->sc_write(channel, buffer, buflen); } else { - DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_putc != NULL); - + DEBUGASSERT(channel->sc_ops->sc_putc != NULL); for (nwritten = 0; nwritten < buflen; nwritten++) { - g_syslog_channel[i]->sc_ops->sc_putc(g_syslog_channel[i], - buffer[nwritten]); + channel->sc_ops->sc_putc(channel, buffer[nwritten]); } } } diff --git a/include/nuttx/syslog/syslog.h b/include/nuttx/syslog/syslog.h index eebd617da6f..5a5f7e02356 100644 --- a/include/nuttx/syslog/syslog.h +++ b/include/nuttx/syslog/syslog.h @@ -100,11 +100,12 @@ typedef CODE void (*syslog_close_t)(FAR struct syslog_channel_s *channel); struct syslog_channel_ops_s { - syslog_putc_t sc_putc; /* Normal buffered output */ - syslog_putc_t sc_force; /* Low-level output for interrupt handlers */ - syslog_flush_t sc_flush; /* Flush buffered output (on crash) */ - syslog_write_t sc_write; /* Write multiple bytes */ - syslog_close_t sc_close; /* Channel close callback */ + syslog_putc_t sc_putc; /* Normal buffered output */ + syslog_putc_t sc_force; /* Low-level output for interrupt handlers */ + syslog_flush_t sc_flush; /* Flush buffered output (on crash) */ + syslog_write_t sc_write; /* Write multiple bytes */ + syslog_write_t sc_write_force; /* Write multiple bytes for interrupt handlers */ + syslog_close_t sc_close; /* Channel close callback */ }; /* This structure provides the interface to a SYSLOG channel */