Просмотр исходного кода

[add] 打印参数带字符串

Branch_elog
huangyulong 5 месяцев назад
Родитель
Сommit
d75694291d
3 измененных файлов: 67 добавлений и 2 удалений
  1. 23
    0
      Middlewares/elog/elog.c
  2. 26
    0
      Middlewares/elog/elog.h
  3. 18
    2
      Middlewares/elog/elog_test.c

+ 23
- 0
Middlewares/elog/elog.c Просмотреть файл

@@ -27,6 +27,23 @@ int elog_put(elog_t *log, const char *const msg, int n, msgparam_t args[])
27 27
     return 0;
28 28
 }
29 29
 
30
+int elog_put_str(elog_t *log, const char *const msg, const char *str)
31
+{
32
+    elog_entry_t *e = (elog_entry_t *)(log->buffer + log->offset); // 计算当前可写的位置e(即log->buffer)
33
+    long esize = strlen(str) + 1; // 参数占用字节数
34
+    long newoff = log->offset + sizeof(elog_entry_t) + esize; // 计算新的偏移量,开始是elog_entry_t头 + n个msg(id和长度组成)
35
+
36
+    if (newoff < log->buflen)
37
+    {
38
+        e->msgid = MSGPTR_MAKE(STR_FIXED_LEN, (msgptr_t)msg); // 通过字符串地址和个数生成msgid,并写入e
39
+        memcpy(e->data, str, esize); // 参数列表写入e
40
+        log->offset = newoff;
41
+        return 1;
42
+    }
43
+
44
+    return 0;
45
+}
46
+
30 47
 void elog_flush(elog_t *log, elog_flush_func_t func, void *ctx)
31 48
 {
32 49
     long off = 0;
@@ -35,6 +52,12 @@ void elog_flush(elog_t *log, elog_flush_func_t func, void *ctx)
35 52
     {
36 53
         elog_entry_t *e = ((elog_entry_t *)(log->buffer + off));
37 54
         size_t len = MSGPTR_LEN(e->msgid) * sizeof(long);
55
+
56
+        if (STR_FIXED_LEN == MSGPTR_LEN(e->msgid))
57
+        {
58
+            len = strlen((void *)e->data) + 1;
59
+        }
60
+
38 61
         size_t incr = sizeof(elog_entry_t) + len;
39 62
         off += incr;
40 63
         func(e, incr, ctx); // 解出一个e[id + data]

+ 26
- 0
Middlewares/elog/elog.h Просмотреть файл

@@ -29,6 +29,32 @@ typedef struct {
29 29
     ) \
30 30
 } while(0)
31 31
 
32
+// 打印字符串%s
33
+#define ELOG_STR(o, msg, str) do { \
34
+    __attribute__((section("elog"))) static const char p_msg[] = msg;  \
35
+    elog_put_str(o, p_msg, str); \
36
+} while(0)
37
+
38
+// 格式化字符串
39
+#include <stdarg.h>
40
+#define FORMAT_MAX 256
41
+#define STR_FIXED_LEN 0b1111
42
+
43
+static inline void _printf_and_put(elog_t *o, const char *format, ...)
44
+{
45
+    char temp[FORMAT_MAX] = {0};
46
+    va_list ap;
47
+    va_start(ap, format);
48
+    (void)vsnprintf(temp, sizeof(temp), format, ap);
49
+    va_end(ap);
50
+    elog_put_str(o, format, temp);
51
+}
52
+
53
+#define ELOG_PRINT(o, format, ...) do { \
54
+    __attribute__((section("elog"))) static const char p_msg[] = format; \
55
+    _printf_and_put(o, format, __VA_ARGS__); \
56
+} while(0)
57
+
32 58
 typedef void (elog_flush_func_t)(elog_entry_t *e, int len, void *ctx);
33 59
 
34 60
 extern elog_t *elog_init(void *arena, size_t size);

+ 18
- 2
Middlewares/elog/elog_test.c Просмотреть файл

@@ -5,9 +5,15 @@ static char arena[1024];
5 5
 
6 6
 static void log_to_semihost(elog_entry_t *e, int len, void *ctx)
7 7
 {
8
-    // 发送出去
8
+    // TODO: 直接通过协议发送出去 elog_t 的所有缓存log
9 9
     uint32_t *p = (void *)e;
10 10
     int num = len / sizeof(uint32_t);
11
+
12
+    if(STR_FIXED_LEN== MSGPTR_LEN(p[0]))
13
+    {
14
+        num = 2;
15
+    }
16
+
11 17
     rt_kprintf("num:%d\n", num);
12 18
     rt_kprintf("len:%d\n", MSGPTR_LEN(p[0])); // 通过msg->id解出参数个数
13 19
 
@@ -18,6 +24,11 @@ static void log_to_semihost(elog_entry_t *e, int len, void *ctx)
18 24
             rt_kprintf("0x%08X ", MSGPTR_MSG(p[i])); // 通过msg_id解出参数内容
19 25
             continue;
20 26
         }
27
+        else if (STR_FIXED_LEN == MSGPTR_LEN(p[0]))
28
+        {
29
+            rt_kprintf("%s ", &p[i]); // 通过msg_id解出参数内容
30
+            continue;
31
+        }
21 32
 
22 33
         rt_kprintf("%d ", p[i]);
23 34
     }
@@ -29,8 +40,13 @@ int elog_test(void)
29 40
 {
30 41
     logger = elog_init(arena, sizeof(arena));
31 42
     ELOG(logger, "Hello world %d\n", 10);  // 把字符串和参数放到内存中,(通过字符串 + 长度算法生成msg_id)和会形成一条msg_id和长度
32
-    ELOG(logger, "test %d %d %c\n", 1, 2, 3);
43
+    ELOG(logger, "test %d %d %d\n", 1, 2, 3);
33 44
     ELOG(logger, "no agrc test\n");
45
+    const char string[] = "this is test param string";
46
+    ELOG_STR(logger, "string test: %s\n", string);
47
+    ELOG_PRINT(logger, "test:%d,-- %s,-- %d, test end\n", 89, string, 23);
48
+
49
+    ELOG_PRINT(logger, "test %d %d %u\n", 1, 2, 3);
34 50
 
35 51
     elog_flush(logger, log_to_semihost, NULL);  // 将内存中的日志刷新到文件,也可以是传输到上位机。也就是之前(字符串和参数)生成的msg_id和长度
36 52
     return 0;

Загрузка…
Отмена
Сохранить