diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h index 60d4dc1e8a431e72069ff92bce1ba218fd7da1d3..8ed9f34ca48b5d6bddc8cb617f3a3ad7c9debb23 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 8a6c97aabfd1812dd61d935fdc4def5836b6a087..f438a92898ff4e8b4aa40a5c92e7d71bfb91400f 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; } diff --git a/examples/log_trace/memlog.c b/examples/log_trace/memlog.c new file mode 100644 index 0000000000000000000000000000000000000000..a94e77fe7ee3739b3c42702f751300768fb31e18 --- /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); +} +