借除錯巨集的設計,梳理下c語言巨集的用法嵌入式裝置基本會配置rs232串列埠作為除錯io介面,假設底層串列埠單位元組輸出函式為serial_putchar(),利用fputc()和fputs()重定向printf函式
void fputc(int
byte, file* stream)
void fputs(const
char *pstr, file *stream)
}
這樣在**裡面利用printf()函式輸出的字串都老老實實從除錯串列埠出來
某個c驅動模組,希望在除錯時列印除錯資訊,而產品**中不顯示除錯資訊。
#define drv_debug 1
#if drv_debug
#define drv_print(x) printf(x)
#else
#define drv_print(x)
#endif
這個版本的drv_print(x)只能輸出單變數——純字串
void foo()
不需要列印除錯資訊時,更改drv_debug巨集定義
#define drv_debug 0
當然也可以直接這樣定義
#define drv_print printf
但是如果巨集呼叫了多個引數:
void foo()
產品**中的#define drv_print(x)
將編譯錯誤!
怎麼辦?一種**座肯定接受不了的做法,多加對括號
void foo()
不管是除錯**還是產品**,編譯都ok
#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
如果只需要列印乙個變數,第2
個引數用隨意值填位,如
void foo()
類似,如果有4個引數,就:
void foo()
很傻,但是沒辦法:(,vxworks 5.5
核心**裡就是這樣幹的!
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++卻不相容了有時候,某個模組,有輸入跟蹤資訊,輸出資訊,錯誤資訊等,如果我想單獨開啟某部分資訊,可以這樣設計
#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\ }while(0)
#else
#define drv_print(fmt, ...)
#endif
note: 多行巨集,注意換行前加\
號
這樣,我只列印out和err:
void drv_write(char* msg_out)
進一步,可以設計針對整個系統不同模組的log輸出控制!tcp/ip協議棧實現lwip
就是這麼幹的!
在嵌入式c語言裡面,運用printf除錯巨集,有助於事後分析,定位bug,多多益善!
printf 巨集 除錯技巧
printf除錯是嵌入式除錯的基本手段,而且是非常重要的手段,我認為相比單步除錯更加有用有效,特別是微控制器之後跑系統,單步除錯效率更加低下了,我們在工作遇到bug的時候,我們第一時間就想知道那些該死的日誌有沒有儲存下來,這樣好讓我們程式設計師裝逼一波把問題解決。printf巨集定義除錯非常重要,有...
除錯技巧 巨集定義開關和printf
printf 的巨集定義版本 前言 我們在寫程式的時候,總是或多或少會加入一些printf之類的語句用於輸出除錯資訊,但是printf語句有個很不方便的地方就是當我們需要發布程式的時候要一條一條的把這些語句刪除,而一旦需要再次除錯的時候,這些語句又不得不一條條的加上,這給我們帶來了很大的不便,浪費了...
c語言 除錯程式必備 c標準 巨集 除錯方法
c標準中指定了一些預定義的巨集,對於程式設計經常會用到。下面這個表中就是一些常常用到的預定義巨集。date 進行預處理的日期 mmm dd yyyy 形式的字串文字 file 代表當前源 檔名的字串文字 line 代表當前源 中的行號的整數常量 time 原始檔編譯時間,格式微 hh mm ss f...