根据debug需要设计printf调试宏

转载自:https://segmentfault.com/a/1190000000456199

v1--单参数宏

#define DRV_DEBUG 1
#if DRV_DEBUG
    #define DRV_PRINT(x) printf(x)
#else
    #define DRV_PRINT(x) 
#endif

v2--指定参数宏

#define DRV_DEBUG 1
#if DRV_DEBUG
    #define DRV_PRINT(fmt, val1, val2) printf(fmt, val1, val2)
#else
    #define DRV_PRINT(fmt, val1, val2) 
#endif

v3--参数数量可变宏

C90和C++中可将宏声明为接受可变数量的自变量,如ARM编译器是这样的

#define DRV_DEBUG 1
#if DRV_DEBUG
    #define DRV_PRINT(fmt, ...) printf(fmt, __VA_ARGS__)
#else
    #define DRV_PRINT(fmt, ...) 
#endif

现在DRV_PRINT用法和printf完全一样了,这么爽的功能,C2000编译器却不支持!

题外话,注意这个特性C90支持,而C90是C++的一个子集,但是C99和C++却不兼容了

分层次LOG输出

有时候,某个模块,有输入跟踪信息,输出信息,错误信息等,如果我想单独打开某部分信息,可以这样设计

#define DRV_DEBUG 1
#define DRV_DEBUG_IN 0x0001
#define DRV_DEBUG_OUT 0x0002
#define DRV_DEBUG_ERR 0x0004
#define DRV_DEBUG_ALL 0xFFFF
#if DRV_DEBUG
        unsigned int drv_flags = DRV_DEBUG_ERR | DRV_DEBUG_OUT;
    #define DRV_PRINT(flag, fmt, ...) \
            do{\
                if(drv_flags & flag){\
                printf(fmt, __VA_ARGS__)}\
            }while(0)
#else
    #define DRV_PRINT(fmt, ...) 
#endif

NOTE: 多行宏,注意换行前加\

这样,我只打印OUT和ERR:

void drv_write(char* msg_out)
{
    DRV_PRINT(DRV_DEBUG_OUT, "Drivr write %s", msg_out); // 输出
        DRV_PRINT(DRV_DEBUG_ERR, "Drivr write %s", msg_out); // 输出
        DRV_PRINT(DRV_DEBUG_IN, "Drivr write %s", msg_out); // 不输出
}

进一步,可以设计针对整个系统不同模块的LOG输出控制!TCP/IP协议栈实现Lwip就是这么干的!

总结

在嵌入式C语言里面,运用printf调试宏,有助于事后分析,定位BUG,多多益善!

猜你喜欢

转载自blog.csdn.net/qingfengjuechen/article/details/87990642
今日推荐