简述
zephyr log系统提供一个通用的接口用于输出调试信息,主要有以下特性:
- 异步显示,不占用当前上下文时间
- 最多9个显示后端
- 编译时module filter level筛选
- 运行时后端filter level设置
- 运行时module filter level设置
- 同模块下多实例(instances)
- 可用户设置时间戳格式
- 提供dump raw data API
- Panic支持
- printk支持(printk重定位到log)
基本概念
Frontend : 前端,需要显示log的模块
Backend : 终端,log显示终端
Level : log等级,Frontend可以指定自己在指定Backend上的显示log的等级
Frontend呼叫LOG显示API将信息显示到Backend,可以有多个Frontend和Backend,每个Frontend都可以指定自己的信息在Backend的level。
例如:有2个Frontend:a1,a2,2个backend: uart,net,那么可以指定
- a1的wrn以上信息在uart显示
- a1的inf以上信息在net显示
- a2的信息不在uart显示
- a1的所有信息在net显示
使用实例
使用log系统很简单:
- conf中进行log配置
- 代码中注册log frontend
- 在代码中使用log API进行message显示
- 启动系统后通过shell的log命令控制
代码
配置文件prj.conf中配置使用log系统,开启了net backend,同时开启了shell,因此会有两个backend:net backend & shell uart backend1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23CONFIG_TEST_RANDOM_GENERATOR=y
# 网络配置,启动net backend需要网络配置
CONFIG_NETWORKING=y
CONFIG_NET_UDP=y
CONFIG_NET_IPV6=n
CONFIG_NET_IPV4=y
CONFIG_NET_DHCPV4=n
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_NEED_IPV6=n
CONFIG_NET_CONFIG_NEED_IPV4=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2"
#使用Shell,会开启shell uart backend
CONFIG_SHELL=y
#使用log系统
CONFIG_LOG=y
#使用和配置net backend
CONFIG_LOG_BACKEND_NET=y
CONFIG_LOG_BACKEND_NET_SERVER="192.0.2.2:514"
下面代码在一个thread调用LOG相关API显示log,注释log相关代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <zephyr.h>
#include <shell/shell.h>
#include <logging/log.h>
#define STACKSIZE 1024
//注册一个名为main的log frontend, build-in level为LOG_LEVEL_DBG
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);
static K_THREAD_STACK_DEFINE(stack, STACKSIZE);
static struct k_thread main_thread;
static void log_thread_fun(void *p1, void *p2, void *p3)
{
int i = 0;
while(1){
LOG_ERR("main err %d", i++); //ERR Level log
LOG_WRN("main wrn"); //WRN Level log
LOG_INF("main info"); //INFO Level log
LOG_DBG("main dbg"); //DBG Level log
k_sleep(1000);
}
}
void main(void)
{
k_thread_create(&main_thread, stack, STACKSIZE, log_thread_fun, NULL, NULL,
NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
}
操作
上面代码运行后可以在shell中进行log的控制,并在shell uart和net syslog(配置方法参见[如何接收UDP-Syslog[https://lgl88911.gitee.io/2019/02/03/%E5%A6%82%E4%BD%95%E6%8E%A5%E6%94%B6UDP-Syslog/]])中看到如下情况:
使用详解
配置
基本上将CONFIG_SHELL和CONFIG_LOG配置好就可用log系统,其它配置这里不展开说明了可以看官方文档
Level
log系统支援4种等级,严重程度为:err>wrn>inf>dbg
当前显示log level必须大于等于系统设置的level,例如当设置为显示wrn level,那么就只有err和wrn会被显示。
module&输出
不同的module用不同的module注册,显示时会显示module名称,log控制时也已module控制。
下面的示例注册module名称为main, build-in level为LOG_LEVEL_DBG1
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG)
build-in level是在编译的时候指定了该module的level,在运行设置的level只能比build-in的大,否则无效,例如build-in level是wrn,如果运行时设置level为dbg,实际显示还是只会显示level大于等于wrn的log。
一个module只能在一个文件中注册,但可以跨文件使用,只用在其它文件中使用LOG_MODULE_DECLARE声明即可,例如下面几个文件都属于led module:1
2
3led_main.c LOG_MODULE_REGISTER(main, LOG_LEVEL_INF)
led_control.c LOG_MODULE_DECLARE(main)
lec_check.c LOG_MODULE_DECLARE(main)
log显示使用下面的宏:
- 格式化字符串显示的宏:LOG_ERR,LOG_WRN, LOG_INF, LOG_DBG
- raw hex显示的宏:LOG_HEXDUMP_ERR,LOG_HEXDUMP_ERR, LOG_HEXDUMP_INF, LOG_HEXDUMP_DBG
例如1
2LOG_ERR("This is err");
LOG_HEXDUMP_ERR(buffer, 16, "Raw:");
命令控制
shell的log命令共有下面几条
- backend : 控制backend
- list_backends : 显示所有backend
- disable : 关闭shell uart backend
- enable : 设置/启动 shell uart backend
- go : 恢复shell uart backend
- halt : 停止shell uart backend
- status : 查看shell uart backend中不同module的level
例如设置main module显示wrn及以上log信息:
log enable wrn main
对于backend命令可以对指定的backend执行子命令disable,enable,go,halt,status
例如设置net backend在main module显示inf及以上log信息:
log backend log_backend_net enable inf main
参考
https://docs.zephyrproject.org/latest/reference/logging/index.html