模块化你的printf打印信息

处理器都会带有JTAG/SWD的调试端口进行侵入式的调试,但是在许多应用场景下这种方式仍是不太适合的。比如调试一个无线通讯系统,你希望捕获其中一些讯息但又无法停下来处理器来进行断点观察,因为一旦暂停则无法处理正在进行交互的信息而导致系统工作不正常。这种情况在代码中嵌入printf打印代码来调试最佳。

但当软件成规模的时候,控制台会有一堆的打印log产生,可能会造成几个负面影响:

  1. 影响代码体积
  2. 影响性能
  3. 难以找到需要关注的信息

如果手动去禁止和打开log无疑是不可取的,那么有什么简单而有效的来管理这些log呢?以下代码提供了一个很好的解决方案。

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include "debug_config.h"
#if defined (CFG_MODULE_x_DEBUG_EN) && (CFG_MODULE_x_DEBUG_EN > 0)
#define MODULE_x_DEBUG printf
#else
#define MODULE_x_DEBUG 1 ? (void) 0 : (void) printf
#endif
void func(void)
{
MODULE_x_DEBUG("Hey I'm module x prompts\r\n");
}

上面打印语句在

CFG_MODULE_x_DEBUG_EN 1```的时候等同于
1
2
```
printf("Hey I'm module x prompts\r\n");

而当

CFG_MODULE_x_DEBUG_EN 0```或者没有定义的时候等同于
1
2
```
1 ? (void) 0 : (void)printf("Hey I'm module x prompts\r\n");

这句话句在编译阶段就会C编译器优化并不会对代码体积或者运行速度有影响。

通过这个方法在debug_config.h"中对于多个CFG_MODULE_x_DEBUG_EN宏定义进行管理可以很好做到单独使能或者禁止各个模块的打印信息。