From 0feefc03b6008301a19a430427390cc9c44decf8 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Wed, 23 Oct 2013 01:43:18 +0800 Subject: [PATCH 1/2] device/pipe: add a control cmd to get the space left in pipe --- components/drivers/include/rtdevice.h | 2 ++ components/drivers/src/pipe.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h index 60d4dc1e8a..8ed9f34ca4 100644 --- a/components/drivers/include/rtdevice.h +++ b/components/drivers/include/rtdevice.h @@ -114,6 +114,8 @@ struct rt_pipe_device struct rt_portal_device *read_portal; }; +#define PIPE_CTRL_GET_SPACE 0x14 /**< get the remaining size of a pipe device */ + #define RT_DATAQUEUE_EVENT_UNKNOWN 0x00 #define RT_DATAQUEUE_EVENT_POP 0x01 #define RT_DATAQUEUE_EVENT_PUSH 0x02 diff --git a/components/drivers/src/pipe.c b/components/drivers/src/pipe.c index 8a6c97aabf..f438a92898 100644 --- a/components/drivers/src/pipe.c +++ b/components/drivers/src/pipe.c @@ -190,6 +190,8 @@ static rt_size_t rt_pipe_write(rt_device_t dev, static rt_err_t rt_pipe_control(rt_device_t dev, rt_uint8_t cmd, void *args) { + if (cmd == PIPE_CTRL_GET_SPACE && args) + *(rt_size_t*)args = rt_ringbuffer_space_len(&PIPE_DEVICE(dev)->ringbuffer); return RT_EOK; } From a391e0a89307258b54e2599368963ce95fa7e7d3 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Wed, 23 Oct 2013 01:48:47 +0800 Subject: [PATCH 2/2] log_trace: add a in-mem-log example After `log_trace_init()`, call `memlog_init`. It then turn the logtrace into a "in-memory" logger which will buffer all the log in memory. It also set a hook in idle to flush all the log into console. One may create an other thread to flush the logs but idle might be the simplest place to go. --- examples/log_trace/memlog.c | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 examples/log_trace/memlog.c diff --git a/examples/log_trace/memlog.c b/examples/log_trace/memlog.c new file mode 100644 index 0000000000..a94e77fe7e --- /dev/null +++ b/examples/log_trace/memlog.c @@ -0,0 +1,52 @@ +#include +#include +#include + +#define PIPE_SZ 2048 +#define PIPE_NAME "lgpipe" + +static rt_uint8_t pipebuf[PIPE_SZ]; +static struct rt_pipe_device pipedev; + +static rt_uint8_t outbuf[1024]; +void memlog_flush(void) +{ + rt_size_t remainsz, readsz; + rt_device_t console; + + console = rt_console_get_device(); + + if (!console) + return; + + rt_device_control((rt_device_t)&pipedev, PIPE_CTRL_GET_SPACE, &remainsz); + if (remainsz == 0) + { + rt_kprintf("logtrace pipe "PIPE_NAME" is full, some log may lost\n"); + } + + readsz = rt_device_read((rt_device_t)&pipedev, 0, outbuf, sizeof(outbuf)); + if (readsz) + rt_device_write(console, 0, outbuf, readsz); +} + +void memlog_init(void) +{ + rt_err_t res; + + /* make sure the RT_PIPE_FLAG_BLOCK_RD is not set. The Idle should not be + * blocked. RT_PIPE_FLAG_FORCE_WR will let the pipe discard some old data + * when pipe is full. */ + res = rt_pipe_init(&pipedev, PIPE_NAME, RT_PIPE_FLAG_FORCE_WR, + pipebuf, sizeof(pipebuf)); + if (res != RT_EOK) + { + rt_kprintf("init pipe device failed: %d\n", res); + return; + } + + log_trace_set_device(PIPE_NAME); + + rt_thread_idle_sethook(memlog_flush); +} +