ソースを参照

Merge pull request #183 from grissiom/log_trace-in-mem

Log trace in mem
Bernard Xiong 11 年 前
コミット
d327f4a25a

+ 2 - 0
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

+ 2 - 0
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;
 }
 

+ 52 - 0
examples/log_trace/memlog.c

@@ -0,0 +1,52 @@
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <log_trace.h>
+
+#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);
+}
+