dbglog
log 分为两种raw和stream。一般用stream,如果format中有%s 只能用raw。
-
raw就跟printf一样,输出原始log,没什么条件限制,但注意RAW不分level的,所以dbglog_level_ctrl 只要不是DBGLOG_LEVEL_NONE就会打印log
-
stream是优化的过的,只输出关键信息(file_id 、line_num),这样输出的log数据较小,且不占用FLASH空间,通过工具辅助还原log信息 ,限制条件就是只能输出变量只能数值类型(int)
Usage
raw:
DBGLOG_LOG(module, lvl, fmt, ...)
stream:
DBGLOG_STREAM_LOG(module, lvl, fmt, ...)
DBGLOG_STREAM_INFO(module, fmt, ...)
DBGLOG_STREAM_WARNING(module, fmt, ...)
DBGLOG_STREAM_ERROR(module, fmt, ...)
一般各模块还会在封装一层宏,例如APP LOG:
DBGLOG_USER_APP_RAW(fmt,arg...) DBGLOG_LOG(IOT_APP_MID,DBGLOG_LEVEL_VERBOSE,fmt,##arg)
DBGLOG_USER_APP_LOG(lvl, fmt, arg...) DBGLOG_STREAM_LOG(IOT_APP_MID, lvl, fmt, ##arg)
log module
将整个程序分成不同模块,可以更好的控制log打印,不同模块独立控制是否打印log 和 打印log的level
这样调试的时候比较方便,只输出自己关心的模块及其对应level的log
enum MODULE_ID_E {
IOT_BASIC_MID_START = 0,
UNKNOWN_MID = IOT_BASIC_MID_START,
OS_TIMER_MID,
OS_LOCK_MID,
OS_UTILS_MID,
IOT_OS_SHIM_MID,
IOT_RPC_MID,
IOT_VAD_MID,
IOT_DBGLOG_MID,
IOT_CLI_MID,
IOT_DRIVER_MID,
IOT_SHARETASK_MID,
IOT_OTA_MID,
IOT_LOGGER_MID,
IOT_DATAPATH_MID,
IOT_STREAM_MID,
RECORD_MID,
STORAGE_MID,
ADC_MID,
PLAYER_MID,
IOT_BATTERY_MID,
IOT_GENERIC_TRANSMISSION_MID,
IOT_MIC_ADC_SST_MID,
IOT_MIC_ADC_VCM_SET_MID,
IOT_KEY_VALUE_MID,
IOT_BASIC_MID_END = 0x5F,
LIB_MID_START = 0x60,
LIB_KEYMGMT_MID = LIB_MID_START,
LIB_DUMP_MID,
LIB_AUDIO_MID,
LIB_ANC_MID,
LIB_CODEC_MID,
LIB_LOADER_MID,
LIB_MID_END = 0x7F,
BT_STACK_MID_START = 0x80,
BT_STACK_CONTROLLER_MID = BT_STACK_MID_START,
BT_STACK_HOST_MID,
BT_STACK_APP_MID,
BT_STACK_TDS_MID,
BT_STACK_MID_END = 0xBF,
BT_PHY_MID_START = 0xC0,
BT_PHY_MID = BT_PHY_MID_START,
BT_PHY_STATUS_MID,
BT_PHY_MID_END = 0xDF,
IOT_APP_MID_START = 0xE0,
IOT_APP_MID = IOT_APP_MID_START,
IOT_APP_BATTERY_CASE_MID,
IOT_SENSOR_HUB_MANAGER_MID,
IOT_LED_MANAGER_MID,
IOT_TONE_MANAGER_MID,
IOT_VENDOR_MESSAGE_MID,
IOT_APP_DEMO_MID,
IOT_APP_MID_END = 0xFF,
MAX_MID_NUM = 0xFF,
};
log level
log分为八个等级,ALL 表示输出所以level的log,NONE表示不输出任何log,VERBOSE表示只输出verbose及以上的log(包括verbose),其他类推。
typedef enum {
DBGLOG_LEVEL_ALL = 0,
DBGLOG_LEVEL_VERBOSE = 1,
DBGLOG_LEVEL_DEBUG = 2,
DBGLOG_LEVEL_INFO = 3,
DBGLOG_LEVEL_WARNING = 4,
DBGLOG_LEVEL_ERROR = 5,
DBGLOG_LEVEL_CRITICAL = 6,
DBGLOG_LEVEL_NONE = 7,
DBGLOG_LEVEL_MAX = 8,
} DBGLOG_LEVEL;
CLI
可以通过 cli_common_basic_set_log_level 来控制不同module打印不同level的log
IOT_BASIC_MID_START这个module进行设置是对全部模块都有效,相当一个全局开关
![(dbglog.assets\image-20210601152531544.png)
module id :4(CLI_MODULEID_COMMON)
message id:25(CLI_MSGID_SET_LOG_LEVEL)
playload:00010000 (module:0 IOT_BASIC_MID_START , level: 1 debug ,reserved:0)
dbglog_raw_log_write
raw 比较简单,通过vsnprintf将log放到buffer中
dbglog_stream_log_write
stream_log通过va_arg(ap, int) 将变量取出放入buffer中
每个参数用4个Byte 存放变量值
Scons编译的时候会调用dbglog_tool.py中的generate_dbglog_table方法生成dbglog_table.txt
里面保存一个字典文件,对应的是 file_id,file_name,line_num,format
Wuqi.Beetle.Message 通过UART打印出的 dgblog_stream_log_header中的file_id 和line_num找到dbglog_table.txt字典中的format,最终输出实际的log
注意
LOG宏定义在C文件中必须是以DBGLOG_开头,宏替换也不行。
例如 #define xxxxLog DBGLOG_xx ,在C中使用xxxxLog是不行的。
dbglog_tool.py生成dbglog_table.txt的时候只会匹配DBGLOG_开头的,如果不是以DBGLOG_开头 最终在dbglog_table.txt是没有的,工具解析的时候就会提示“can't resolver stream log”
推荐阅读