利用条件编译实现RTT可控的调试输出
在嵌入式开发中,调试信息的输出通常对定位问题至关重要。然而,为了保证代码在正式发布时的性能和体积,调试信息往往需要在不修改主逻辑代码的前提下禁用。
代码一览
// debug.h
#pragma once// #define DEBUG#ifdef DEBUG#include "SEGGER_RTT.h"#define DEBUG_PRINT(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#else#define DEBUG_PRINT(...) do {} while (0)
#endif
设计目的
这段代码的核心目的是:根据是否定义了 DEBUG
宏来决定是否启用调试打印功能。它的设计符合以下几个关键需求:
- 编译期控制调试开关,无需手动删除调试代码;
- 避免无用代码膨胀,在非调试版本中编译器能优化掉;
- 统一调试接口,通过
DEBUG_PRINT
宏调用,使用简单。
逐行解析
-
#pragma once
:防止头文件被多次包含,是一种常用的 include guard。 -
// #define DEBUG
:默认注释掉,表示发布版默认关闭调试。如果需要开启调试,只需取消注释。 -
#ifdef DEBUG
:检查是否定义了DEBUG
宏。-
如果定义了,说明是调试版本:
- 引入
SEGGER_RTT.h
,它是 SEGGER 提供的高效调试输出工具; - 定义
DEBUG_PRINT(...)
宏,展开为SEGGER_RTT_printf
调用。
- 引入
-
如果没有定义:
DEBUG_PRINT(...)
宏将被替换成空语句do {} while (0)
,这是一种确保宏语法安全的惯用写法。
-
SEGGER RTT 简介
SEGGER RTT (Real-Time Transfer) 是 SEGGER 提供的用于 J-Link 调试器的高效数据传输方式,具有以下特点:
- 不依赖串口,速度快;
- 实时性强,适合嵌入式系统调试;
- 与 Keil、IAR、SEGGER Embedded Studio 等集成良好。
使用方法
-
开启调试输出:在
debug.h
中取消#define DEBUG
的注释; -
调用调试打印:
DEBUG_PRINT("Sensor value: %d\n", sensor_value);
-
发布前禁用调试:注释掉
#define DEBUG
即可,无需修改其他文件。