diff --git a/drivers/syslog/Make.defs b/drivers/syslog/Make.defs index f573217d6d..4b9a303355 100644 --- a/drivers/syslog/Make.defs +++ b/drivers/syslog/Make.defs @@ -35,60 +35,42 @@ ############################################################################ ############################################################################ -# Include SYSLOG drivers (only one should be enabled) +# Include SYSLOG Infrastructure -ifeq ($(CONFIG_SYSLOG),y) +CSRCS += syslog_channel.c -# If no special loggin devices are implemented, then the default SYSLOG -# logic at fs/fs_syslog.c will be used - -# (Add other SYSLOG drivers here) - -ifeq ($(CONFIG_RAMLOG),y) - CSRCS += ramlog.c +ifeq ($(CONFIG_SYSLOG_INTBUFFER),y) + CSRCS += syslog_intbuffer.c endif +# The note driver is hosted in this directory, but is not associated with +# SYSLOGging + ifeq ($(CONFIG_DRIVER_NOTE),y) CSRCS += note_driver.c endif -# (Add other SYSLOG_CONSOLE drivers here) +############################################################################ +# Include SYSLOG drivers (only one should be enabled) + +ifeq ($(CONFIG_RAMLOG),y) + CSRCS += ramlog.c +else ifeq ($(CONFIG_SYSLOG),y) + +# If no special logging devices are implemented, then the default SYSLOG +# logic at fs/fs_syslog.c will be used + +# (Add other SYSLOG drivers here) ifeq ($(CONFIG_SYSLOG_CONSOLE),y) CSRCS += syslog_console.c endif +# (Add other SYSLOG_CONSOLE drivers here) + +endif + # Include SYSLOG build support DEPPATH += --dep-path syslog VPATH += :syslog - -############################################################################ -# The RAMLOG can be used even if system logging is not enabled. - -else ifeq ($(CONFIG_RAMLOG),y) - -CSRCS += ramlog.c - -ifeq ($(CONFIG_DRIVER_NOTE),y) - CSRCS += note_driver.c -endif - -# Include RAMLOG build support - -DEPPATH += --dep-path syslog -VPATH += :syslog - -############################################################################ -# The scheduler note driver can be used in any event. - -else ifeq ($(CONFIG_DRIVER_NOTE),y) - -CSRCS += note_driver.c - -# Include note driver build support - -DEPPATH += --dep-path syslog -VPATH += :syslog - -endif diff --git a/drivers/syslog/syslog.h b/drivers/syslog/syslog.h new file mode 100644 index 0000000000..86808cefdf --- /dev/null +++ b/drivers/syslog/syslog.h @@ -0,0 +1,126 @@ +/**************************************************************************** + * drivers/syslog/syslog.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __DRIVERS_SYSLOG_SYSLOG_H +#define __DRIVERS_SYSLOG_SYSLOG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: syslog_add_intbuffer + * + * Description: + * Add one more character to the interrupt buffer. In the event of + * buffer overlowed, the character will be dropped. The indication + * "[truncated]\n" will be appended to the end of the interrupt buffer. + * + * Input Parameters: + * ch - The character to add to the interrupt buffer (must be positive). + * + * Returned Value: + * Zero success, the character is echoed back to the caller. A negated + * errno value is returned on any failure. + * + * Assumptions: + * Called only from interrupt handling logic; Interrupts will be disabled. + * + ****************************************************************************/ + +#ifdef CONFIG_SYSLOG_INTBUFFER +int syslog_add_intbuffer(int ch); +#endif + +/**************************************************************************** + * Name: syslog_flush_intbuffer + * + * Description: + * Flush any characters that may have been added to the interrupt buffer + * to the SYSLOG device. + * + * Input Parameters: + * channel - The syslog channel to use in performing the flush operation. + * force - Use the force() method of the channel vs. the putc() method. + * + * Returned Value: + * On success, the character is echoed back to the caller. A negated + * errno value is returned on any failure. + * + * Assumptions: + * Interrupts may or may not be disabled. + * + ****************************************************************************/ + +#ifdef CONFIG_SYSLOG_INTBUFFER +int syslog_flush_intbuffer(FAR const struct syslog_channel_s *channel, + bool force); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __DRIVERS_SYSLOG_SYSLOG_H */ diff --git a/drivers/syslog/syslog_channel.c b/drivers/syslog/syslog_channel.c new file mode 100644 index 0000000000..6e2f3c14ad --- /dev/null +++ b/drivers/syslog/syslog_channel.c @@ -0,0 +1,207 @@ +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#ifdef CONFIG_RAMLOG_SYSLOG +# include +#elif defined(CONFIG_ARCH_LOWPUTC) +# include +#endif + +#include "syslog.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#ifndef CONFIG_ARCH_LOWPUTC +static int syslog_default_putc(int ch); +#endif +static int syslog_default_flush(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if defined(CONFIG_RAMLOG_SYSLOG) +static const struct syslog_channel_s g_default_channel = +{ + ramlog_putc, + ramlog_putc, + syslog_default_flush +}; +#elif defined(CONFIG_ARCH_LOWPUTC) +static const struct syslog_channel_s g_default_channel = +{ + up_putc, + up_putc, + syslog_default_flush +}; +#else +static const struct syslog_channel_s g_default_channel = +{ + syslog_default_putc, + syslog_default_putc, + syslog_default_flush +}; +#endif + +/* This is the current syslog channel in use */ + +static FAR const struct syslog_channel_s *g_syslog_channel = &g_default_channel; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifndef CONFIG_ARCH_LOWPUTC +static int syslog_default_putc(int ch) +{ + return ch; +} +#endif + +static int syslog_default_flush(void) +{ + return OK; +} + +static int syslog_force(int ch) +{ + DEBUGASSERT(g_syslog_channel != NULL && g_syslog_channel->sc_force != NULL); + + return g_syslog_channel->sc_force(ch); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: syslog_channel + * + * Description: + * Configure the SYSLOGging function to use the provided channel to + * generate SYSLOG output. + * + * Input buffer: + * channel - Provides the interface to the channel to be used. + * + * Returned Value: + * Zero (OK)is returned on success. A negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +int syslog_channel(FAR const struct syslog_channel_s *channel) +{ + DEBUGASSERT(channel != NULL); + + if (channel != NULL) + { + DEBUGASSERT(channel->sc_putc != NULL && channel->sc_force != NULL && + channel->sc_flush != NULL); + + g_syslog_channel = channel; + return OK; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: syslog_putc + * + * Description: + * This is the low-level system logging interface. + * + * Input Parameters: + * 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. + * + ****************************************************************************/ + +int syslog_putc(int ch) +{ + DEBUGASSERT(g_syslog_channel != NULL); + + /* Is this an attempt to do SYSLOG output from an interrupt handler? */ + + if (up_interrupt_context()) + { +#ifdef CONFIG_SYSLOG_INTBUFFER + /* Buffer the character in the interrupt buffer. The interrupt buffer + * will be flushed before the next normal, non-interrupt SYSLOG output. + */ + + return syslog_add_intbuffer(ch); +#else + /* Force the character to the SYSLOG device immediately (if possible). + * This means that the interrupt data may not be in synchronization + * with output data that may have been buffered by sc_putc(). + */ + + return syslog_force(ch); +#endif + } + else + { + DEBUGASSERT(g_syslog_channel->sc_putc != NULL); + +#ifdef CONFIG_SYSLOG_INTBUFFER + /* Flush any characters that may have been added to the interrupt + * buffer. + */ + + (void)syslog_flush_intbuffer(&g_syslog_channel, false); +#endif + + return g_syslog_channel->sc_putc(ch); + } +} + +/**************************************************************************** + * Name: syslog_flush + * + * Description: + * This is called by system crash-handling logic. It must flush any + * buffered data to the SYSLOG device. + * + * Interrupts are disabled at the time of the crash and this logic must + * perform the flush using low-level, non-interrupt driven logic. + * + * Input Parameters: + * ch - The character to add to the SYSLOG (must be positive). + * + * Returned Value: + * Zero (OK)is returned on success. A negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +int syslog_flush(void) +{ + DEBUGASSERT(g_syslog_channel != NULL && g_syslog_channel->sc_flush != NULL); + +#ifdef CONFIG_SYSLOG_INTBUFFER + /* Flush any characters that may have been added to the interrupt + * buffer. + */ + + (void)syslog_flush_intbuffer(&g_syslog_channel, true); +#endif + + /* Then flush all of the buffered output to the SYSLOG device */ + + return g_syslog_channel->sc_flush(); +} diff --git a/drivers/syslog/syslog_intbuffer.c b/drivers/syslog/syslog_intbuffer.c new file mode 100644 index 0000000000..707eb40e03 --- /dev/null +++ b/drivers/syslog/syslog_intbuffer.c @@ -0,0 +1,115 @@ +/**************************************************************************** + * drivers/syslog/syslog_intbuffer.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "syslog.h" + +#ifdef CONFIG_SYSLOG_INTBUFFER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: syslog_add_intbuffer + * + * Description: + * Add one more character to the interrupt buffer. In the event of + * buffer overlowed, the character will be dropped. The indication + * "[truncated]\n" will be appended to the end of the interrupt buffer. + * + * Input Parameters: + * ch - The character to add to the interrupt buffer (must be positive). + * + * Returned Value: + * Zero success, the character is echoed back to the caller. A negated + * errno value is returned on any failure. + * + * Assumptions: + * Called only from interrupt handling logic; Interrupts will be disabled. + * + ****************************************************************************/ + +int syslog_add_intbuffer(int ch) +{ +#warning Missing logic + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: syslog_flush_intbuffer + * + * Description: + * Flush any characters that may have been added to the interrupt buffer + * to the SYSLOG device. + * + * Input Parameters: + * channel - The syslog channel to use in performing the flush operation. + * force - Use the force() method of the channel vs. the putc() method. + * + * Returned Value: + * On success, the character is echoed back to the caller. A negated + * errno value is returned on any failure. + * + * Assumptions: + * Interrupts may or may not be disabled. + * + ****************************************************************************/ + +int syslog_flush_intbuffer(FAR const struct syslog_channel_s *channel, + bool force) +{ +#warning Missing logic + return -ENOSYS; +} + +#endif /* CONFIG_SYSLOG_INTBUFFER */ diff --git a/include/nuttx/syslog/syslog.h b/include/nuttx/syslog/syslog.h index 836440da81..3958a833a8 100644 --- a/include/nuttx/syslog/syslog.h +++ b/include/nuttx/syslog/syslog.h @@ -2,7 +2,7 @@ * include/nuttx/syslog/syslog.h * The NuttX SYSLOGing interface * - * Copyright (C) 2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ ****************************************************************************/ #include +#include /**************************************************************************** * Pre-processor Definitions @@ -79,6 +80,23 @@ # define CONFIG_SYSLOG_DEVPATH "/dev/ttyS1" #endif +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This structure provides the interface to a SYSLOG device */ + +struct syslog_channel_s +{ + /* I/O redirection methods */ + + CODE int (*sc_putc)(int ch); /* Normal buffered output */ + CODE int (*sc_force)(int ch); /* Low-level output for interrupt handlers */ + CODE int (*sc_flush)(void); /* Flush buffered output (on crash) */ + + /* Implementation specific logic may follow */ +}; + /**************************************************************************** * Public Data ****************************************************************************/ @@ -96,6 +114,24 @@ extern "C" /**************************************************************************** * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Name: syslog_channel + * + * Description: + * Configure the SYSLOGging function to use the provided channel to + * generate SYSLOG output. + * + * Input buffer: + * channel - Provides the interface to the channel to be used. + * + * Returned Value: + * Zero (OK)is returned on success. A negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +int syslog_channel(FAR const struct syslog_channel_s *channel); + /**************************************************************************** * Name: syslog_initialize * @@ -106,6 +142,13 @@ extern "C" * NOTE that this implementation excludes using a network connection as * SYSLOG device. That would be a good extension. * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK)is returned on success. A negated errno value is returned + * on any failure. + * ****************************************************************************/ #ifdef CONFIG_SYSLOG_CHAR @@ -116,17 +159,39 @@ int syslog_initialize(void); * Name: syslog_putc * * Description: - * This is the low-level system logging interface. The debugging/syslogging - * interfaces are syslog() and lowsyslog(). The difference is that - * the syslog() internface writes to fd=1 (stdout) whereas lowsyslog() uses - * a lower level interface that works from interrupt handlers. This - * function is the low-level interface used to implement lowsyslog(). + * This is the low-level system logging interface. + * + * Input Parameters: + * 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. * ****************************************************************************/ -#ifdef CONFIG_SYSLOG int syslog_putc(int ch); -#endif + +/**************************************************************************** + * Name: syslog_flush + * + * Description: + * This is called by system crash-handling logic. It must flush any + * buffered data to the SYSLOG device. + * + * Interrupts are disabled at the time of the crash and this logic must + * perform the flush using low-level, non-interrupt driven logic. + * + * Input Parameters: + * ch - The character to add to the SYSLOG (must be positive). + * + * Returned Value: + * Zero (OK)is returned on success. A negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +int syslog_flush(void); #undef EXTERN #ifdef __cplusplus