forked from Archive/PX4-Autopilot
The RAM log cannot block like more character drivers, otherwise cat /dev/syslog does not work
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4383 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
parent
592c4f7deb
commit
57ae1bb526
|
@ -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,23 +451,29 @@ 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 */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
****************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue