diff --git a/drivers/syslog/Kconfig b/drivers/syslog/Kconfig index 912ad2c6fbc..ce1d2f8fb43 100644 --- a/drivers/syslog/Kconfig +++ b/drivers/syslog/Kconfig @@ -223,6 +223,14 @@ config SYSLOG_RPMSG ---help--- Use the rpmsg as a SYSLOG output device, send message to remote proc. +config SYSLOG_STREAM + bool "Log to stream" + default n + ---help--- + Enables support to use stream as syslog backend, such as block out stream. + It is recommended to implement the backend stream in a way that syslog + works in interrupt context. + config SYSLOG_CONSOLE bool "Log to /dev/console" default !ARCH_LOWPUTC && !SYSLOG_CHAR && !RAMLOG_SYSLOG && !SYSLOG_RPMSG && !SYSLOG_RTT diff --git a/drivers/syslog/Make.defs b/drivers/syslog/Make.defs index 0fbb977c143..44406eea4f7 100644 --- a/drivers/syslog/Make.defs +++ b/drivers/syslog/Make.defs @@ -77,6 +77,10 @@ ifeq ($(CONFIG_CONSOLE_SYSLOG),y) CSRCS += syslog_console.c endif +ifeq ($(CONFIG_SYSLOG_STREAM),y) + CSRCS += syslog_stream.c +endif + # (Add other SYSLOG drivers here) # Include SYSLOG build support diff --git a/drivers/syslog/syslog_stream.c b/drivers/syslog/syslog_stream.c new file mode 100644 index 00000000000..47986d0da17 --- /dev/null +++ b/drivers/syslog/syslog_stream.c @@ -0,0 +1,267 @@ +/**************************************************************************** + * drivers/syslog/syslog_stream.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 + +#include +#include + +#include +#include +#include + +#ifdef CONFIG_SYSLOG_STREAM + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure contains all SYSLOGing state information */ + +struct syslog_stream_s +{ + struct syslog_channel_s channel; + FAR struct lib_outstream_s *stream; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static ssize_t syslog_stream_write(FAR struct syslog_channel_s *channel, + FAR const char *buffer, size_t buflen); +static int syslog_stream_putc(FAR struct syslog_channel_s *channel, int ch); +static int syslog_stream_force(FAR struct syslog_channel_s *channel, int ch); +static int syslog_stream_flush(FAR struct syslog_channel_s *channel); +void syslog_stream_uninit(FAR struct syslog_channel_s *channel); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct syslog_channel_ops_s g_syslog_stream_ops = +{ + syslog_stream_putc, + syslog_stream_force, + syslog_stream_flush, + syslog_stream_write, + syslog_stream_uninit +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: syslog_stream_write + * + * Description: + * This is the low-level, multiple byte, system logging interface provided + * for the driver interface. + * + * Input Parameters: + * channel - Handle to syslog channel to be used. + * buffer - The buffer containing the data to be output. + * buflen - The number of bytes in the buffer. + * + * Returned Value: + * On success, the number of characters written is returned. A negated + * errno value is returned on any failure. + * + ****************************************************************************/ + +static ssize_t syslog_stream_write(FAR struct syslog_channel_s *channel, + FAR const char *buffer, size_t buflen) +{ + FAR struct syslog_stream_s *chan = + (FAR struct syslog_stream_s *)channel; + ssize_t nwritten; + irqstate_t flags; + + flags = enter_critical_section(); + nwritten = lib_stream_puts(chan->stream, buffer, buflen); + leave_critical_section(flags); + return nwritten; +} + +/**************************************************************************** + * Name: syslog_stream_putc + * + * Description: + * This is the low-level, single character, system logging interface + * provided for the driver interface. + * + * 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_putc(FAR struct syslog_channel_s *channel, int ch) +{ + FAR struct syslog_stream_s *chan = + (FAR struct syslog_stream_s *)channel; + irqstate_t flags; + + flags = enter_critical_section(); + lib_stream_put(chan->stream, ch); + leave_critical_section(flags); + + 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_put(chan->stream, ch); + return OK; +} + +/**************************************************************************** + * Name: syslog_stream_flush + * + * Description: + * Flush any buffer data in the file system to media. + * + * Input Parameters: + * channel - Handle to syslog channel to be used. + * + * Returned Value: + * Zero (OK) on success; a negated errno value is returned on any failure. + * + ****************************************************************************/ + +static int syslog_stream_flush(FAR struct syslog_channel_s *channel) +{ + FAR struct syslog_stream_s *chan = + (FAR struct syslog_stream_s *)channel; + irqstate_t flags; + + flags = enter_critical_section(); + lib_stream_flush(chan->stream); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: syslog_stream_uninit + * + * Description: + * Disable the channel in preparation to use a different + * SYSLOG device. + * + * Input Parameters: + * channel - Handle to syslog channel to be used. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + * Assumptions: + * The caller has already switched the SYSLOG source to some safe channel + * (the default channel). + * + ****************************************************************************/ + +void syslog_stream_uninit(FAR struct syslog_channel_s *channel) +{ + FAR struct syslog_stream_s *chan = + (FAR struct syslog_stream_s *)channel; + + /* Attempt to flush any buffered data. */ + + syslog_stream_flush(channel); + + /* Free the channel structure */ + + kmm_free(chan); +} + +/**************************************************************************** + * Name: syslog_stream_channel + * + * Description: + * Initialize to use the device stream as the SYSLOG sink. + * + * On power up, the SYSLOG facility is non-existent or limited to very + * low-level output. This function may be called later in the + * initialization sequence after full driver support has been initialized. + * (via syslog_initialize()) It installs the configured SYSLOG drivers + * and enables full SYSLOGing capability. + * + * Input Parameters: + * stream - The stream device to be used. + * + * Returned Value: + * Returns a newly created SYSLOG channel, or NULL in case of any failure. + * + ****************************************************************************/ + +FAR struct syslog_channel_s * +syslog_stream_channel(FAR struct lib_outstream_s *stream) +{ + FAR struct syslog_stream_s *chan; + + DEBUGASSERT(stream != NULL); + + chan = (FAR struct syslog_stream_s *) + kmm_zalloc(sizeof(struct syslog_stream_s)); + + if (chan == NULL) + { + return NULL; + } + + chan->stream = stream; + chan->channel.sc_ops = &g_syslog_stream_ops; + return (FAR struct syslog_channel_s *)chan; +} + +#endif /* CONFIG_SYSLOG_STREAM */ diff --git a/include/nuttx/syslog/syslog.h b/include/nuttx/syslog/syslog.h index 81866d897de..b0b480e3a47 100644 --- a/include/nuttx/syslog/syslog.h +++ b/include/nuttx/syslog/syslog.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -243,6 +244,31 @@ int syslog_initialize(void); FAR struct syslog_channel_s *syslog_file_channel(FAR const char *devpath); #endif +/**************************************************************************** + * Name: syslog_stream_channel + * + * Description: + * Initialize to use the device stream as the SYSLOG sink. + * + * On power up, the SYSLOG facility is non-existent or limited to very + * low-level output. This function may be called later in the + * initialization sequence after full driver support has been initialized. + * (via syslog_initialize()) It installs the configured SYSLOG drivers + * and enables full SYSLOGing capability. + * + * Input Parameters: + * stream - The stream device to be used. + * + * Returned Value: + * Returns a newly created SYSLOG channel, or NULL in case of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_SYSLOG_STREAM +FAR struct syslog_channel_s * +syslog_stream_channel(FAR struct lib_outstream_s *stream); +#endif + /**************************************************************************** * Name: syslog_putc *