EasyLogger#
EasyLogger官网 的文档已经很详细了,这儿只是记录使用过程
在 elog.c 文件中首先定义了一个 elog 对象,以及每行输出内容的行缓存 log_buf,缓存区的大小由 ELOG_LINE_BUF_SIZE 决定。 当我们在源文件中调用日志打印函数时,它们都将最后调用 elog_output 函数来完成log_buf的初始化,最终由 elog_port_output 完成最终的输出
- 从流程图不难看出:
过滤优先级:级别 > TAG过滤级别 > tag关键字过滤 > 内容关键字过滤
输出优先级:异步输出 > 缓存输出 > 直接输出
日志无法输出到串口#
- 问题描述:
当在项目中将stdout定向到ITM时,日志输出正常。但把stdout重定向串口时,日志只打印前面几个字符后就无输出了。
[Info] System core frequency: 48000000Hz I/
从输出结果可以看出,使用printf输出正常,但使用`log_i`输出时就会被阻塞而无输出
- 排查过程:
在 stdout_USART.c 的 stdout_putchar 函数打上断点调试
92int stdout_putchar (int ch) { 93uint8_t buf[1]; 94 95buf[0] = ch; 96if (ptrUSART->Send(buf, 1) != ARM_DRIVER_OK) { 97 return (-1); 98} 99while (ptrUSART->GetTxCount() != 1); 100return (ch); 101}
结果断点调试又能正常输出,但一旦将断点取消全速运行就又会阻塞无输出。 结合上面直接使用 printf 函数输出又正常的现象,这两都之间的区别就在于: EasyLogger在输出前后加了 elog_port_output_lock 和 elog_port_output_unlock ,而这两个函数内空又如下:
void elog_port_output_lock(void) { __disable_irq(); } void elog_port_output_unlock(void) { __enable_irq(); }
可能的原因就是当调用 elog_port_output_lock 函数时,串口当前字符还未发送完成,但时中断又被禁用了。 所以当串口发送完当前字符后产生中断标志,但无法进入中断处就被阻塞了
- 处理方法:
注释掉 elog_port_output_lock 和 elog_port_output_unlock 中的中断开关语句