diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-02-11 15:58:11 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-02-11 15:58:11 +0000 |
commit | 56959f5762015fc1fd3ef43310040613c5d936aa (patch) | |
tree | ba54a2810abf0e6f6846690a4feeb657288eba13 | |
parent | 4cb67b0b1b9ce6ba8c524a3a5b4fbb8f8aa184bb (diff) | |
download | nuttx-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.c | 79 | ||||
-rw-r--r-- | nuttx/include/nuttx/ramlog.h | 11 |
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 ****************************************************************************/ |