summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-02-11 15:58:11 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-02-11 15:58:11 +0000
commit56959f5762015fc1fd3ef43310040613c5d936aa (patch)
treeba54a2810abf0e6f6846690a4feeb657288eba13
parent4cb67b0b1b9ce6ba8c524a3a5b4fbb8f8aa184bb (diff)
downloadnuttx-56959f5762015fc1fd3ef43310040613c5d936aa.tar.gz
nuttx-56959f5762015fc1fd3ef43310040613c5d936aa.tar.bz2
nuttx-56959f5762015fc1fd3ef43310040613c5d936aa.zip
The RAM log cannot block like more character drivers, otherwise cat /dev/syslog does not work
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4383 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/drivers/ramlog.c79
-rw-r--r--nuttx/include/nuttx/ramlog.h11
2 files changed, 84 insertions, 6 deletions
diff --git a/nuttx/drivers/ramlog.c b/nuttx/drivers/ramlog.c
index fd94f5bf4..53e57b1a0 100644
--- a/nuttx/drivers/ramlog.c
+++ b/nuttx/drivers/ramlog.c
@@ -72,11 +72,15 @@
struct ramlog_dev_s
{
+#ifndef CONFIG_RAMLOG_NONBLOCKING
volatile uint8_t rl_nwaiters; /* Number of threads waiting for data */
+#endif
volatile uint16_t rl_head; /* The head index (where data is added) */
volatile uint16_t rl_tail; /* The tail index (where data is removed) */
sem_t rl_exclsem; /* Enforces mutually exclusive access */
+#ifndef CONFIG_RAMLOG_NONBLOCKING
sem_t rl_waitsem; /* Used to wait for data */
+#endif
size_t rl_bufsize; /* Size of the RAM buffer */
FAR char *rl_buffer; /* Circular RAM buffer */
@@ -252,7 +256,14 @@ static ssize_t ramlog_read(FAR struct file *filep, FAR char *buffer, size_t len)
if (priv->rl_head == priv->rl_tail)
{
- /* The circular buffer is empty. Did we read anything? */
+ /* The circular buffer is empty. */
+
+#ifdef CONFIG_RAMLOG_NONBLOCKING
+ /* Return what we have (with zero mean the end-of-file) */
+
+ break;
+#else
+ /* Did we read anything? */
if (nread > 0)
{
@@ -333,6 +344,7 @@ static ssize_t ramlog_read(FAR struct file *filep, FAR char *buffer, size_t len)
goto errout_without_sem;
}
+#endif /* CONFIG_RAMLOG_NONBLOCKING */
}
else
{
@@ -362,7 +374,10 @@ static ssize_t ramlog_read(FAR struct file *filep, FAR char *buffer, size_t len)
/* Notify all poll/select waiters that they can write to the FIFO */
+#ifndef CONFIG_RAMLOG_NONBLOCKING
errout_without_sem:
+#endif
+
#ifndef CONFIG_DISABLE_POLL
if (nread > 0)
{
@@ -380,9 +395,9 @@ static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, size
{
struct inode *inode = filep->f_inode;
struct ramlog_dev_s *priv;
- irqstate_t flags;
ssize_t nwritten;
- int i;
+ char ch;
+ int ret;
/* Some sanity checking */
@@ -400,7 +415,29 @@ static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, size
for (nwritten = 0; nwritten < len; nwritten++)
{
- int ret = ramlog_addchar(priv, buffer[nwritten]);
+ /* Get the next character to output */
+
+ ch = buffer[nwritten];
+
+ /* Pre-pend a carriage before a linefeed */
+
+ if (ch == '\n')
+ {
+ ret = ramlog_addchar(priv, '\r');
+ if (ret < 0)
+ {
+ /* The buffer is full and nothing was saved. Break out of the
+ * loop to return the number of bytes written up to this point.
+ * The data to be written is dropped on the floor.
+ */
+
+ break;
+ }
+ }
+
+ /* Then output the character */
+
+ ret = ramlog_addchar(priv,ch);
if (ret < 0)
{
/* The buffer is full and nothing was saved. Break out of the
@@ -414,24 +451,30 @@ static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, size
/* Was anything written? */
+#if !defined(CONFIG_RAMLOG_NONBLOCKING) || !defined(CONFIG_DISABLE_POLL)
if (nwritten > 0)
{
+ int i;
+
/* Are there threads waiting for read data? */
- flags = irqsave();
+ irqstate_t flags = irqsave();
+#ifndef CONFIG_RAMLOG_NONBLOCKING
for (i = 0; i < priv->rl_nwaiters; i++)
{
/* Yes.. Notify all of the waiting readers that more data is available */
sem_post(&priv->rl_waitsem);
}
+#endif
/* Notify all poll/select waiters that they can write to the FIFO */
ramlog_pollnotify(priv, POLLIN);
irqrestore(flags);
}
-
+#endif
+
/* Return the number of bytes written */
return nwritten;
@@ -581,7 +624,9 @@ int ramlog_register(FAR const char *devpath, FAR char *buffer, size_t buflen)
/* Initialize the non-zero values in the RAM logging device structure */
sem_init(&priv->rl_exclsem, 0, 1);
+#ifndef CONFIG_RAMLOG_NONBLOCKING
sem_init(&priv->rl_waitsem, 0, 0);
+#endif
priv->rl_bufsize = buflen;
priv->rl_buffer = buffer;
@@ -616,7 +661,9 @@ int ramlog_consoleinit(void)
/* Initialize the RAM loggin device structure */
sem_init(&priv->rl_exclsem, 0, 1);
+#ifndef CONFIG_RAMLOG_NONBLOCKING
sem_init(&priv->rl_waitsem, 0, 0);
+#endif
priv->rl_bufsize = CONFIG_RAMLOG_CONSOLE_BUFSIZE;
priv->rl_buffer = g_sysbuffer;
@@ -656,7 +703,9 @@ int ramlog_sysloginit(void)
/* Initialize the RAM loggin device structure */
sem_init(&priv->rl_exclsem, 0, 1);
+#ifndef CONFIG_RAMLOG_NONBLOCKING
sem_init(&priv->rl_waitsem, 0, 0);
+#endif
priv->rl_bufsize = CONFIG_RAMLOG_CONSOLE_BUFSIZE;
priv->rl_buffer = g_sysbuffer;
@@ -681,6 +730,24 @@ int ramlog_sysloginit(void)
int ramlog_putc(int ch)
{
FAR struct ramlog_dev_s *priv = &g_sysdev;
+ int ret;
+
+ /* Pre-pend a newline with a carriage return */
+
+ if (ch == '\n')
+ {
+ ret = ramlog_addchar(priv, '\r');
+ if (ret < 0)
+ {
+ /* The buffer is full and nothing was saved. Break out of the
+ * loop to return the number of bytes written up to this point.
+ * The data to be written is dropped on the floor.
+ */
+
+ return ch;
+ }
+ }
+
(void)ramlog_addchar(priv, ch);
return ch;
}
diff --git a/nuttx/include/nuttx/ramlog.h b/nuttx/include/nuttx/ramlog.h
index a800c077f..8f1a0c702 100644
--- a/nuttx/include/nuttx/ramlog.h
+++ b/nuttx/include/nuttx/ramlog.h
@@ -102,6 +102,17 @@
# define CONFIG_RAMLOG_CONSOLE_BUFSIZE 1024
#endif
+/* The normal behavior of the RAM log when used as a SYSLOG is to return
+ * end-of-file if there is no data in the RAM log (rather than blocking until
+ * data is available). That allows you to cat the SYSLOG with no ill
+ * consequences.
+ */
+
+#ifdef CONFIG_SYSLOG
+# undef CONFIG_RAMLOG_NONBLOCKING
+# define CONFIG_RAMLOG_NONBLOCKING 1
+#endif
+
/****************************************************************************
* Public Data
****************************************************************************/