博客專欄

        EEPW首頁 > 博客 > c語言宏定義##__VA_ARGS__封裝printf函數,單片機實現簡單的分級日志模塊

        c語言宏定義##__VA_ARGS__封裝printf函數,單片機實現簡單的分級日志模塊

        發布人:電子禪石 時間:2023-02-20 來源:工程師 發布文章

        在單片機開發中經常需要加入printf之類的函數來輸出調試信息,這些信息一般伴隨著整個開發過程,但是在程序發布時候,又得將它們注釋掉,非常的不方便,于是有了以下解決辦法:


        使用宏定義開關

         #ifdef __DEBUG
         #define DEBUG(info)    printf(info)
         #else
         #define DEBUG(info)
         #endif

        但是這樣并不能發揮出printf函數的強大功能,使用起來并不方便。


        使用不定參數的宏定義


        c99規范后,編譯器就開始支持不定參數##__VA_ARGS__的宏定義

        相關知識可參考博客http://blog.csdn.net/aobai219/archive/2010/12/22/6092292.aspx

        于是我們就有了這樣的一個宏定義

        ————————————————

         #ifdef __DEBUG
         #define DEBUG(format, ...) printf (format, ##__VA_ARGS__)
         #else
         #define DEBUG(format, ...)
         #endif

        嗯,現在printf的功能是有了,那干脆再輸出一些相關的信息,這樣一下子就可以知道代碼位置,然后就變成這樣了:


         #ifdef __DEBUG
             #define DEBUG(format, ...) \
                  printf("FILE: "__FILE__", LINE: %d: "format"/n", __LINE__,##__VA_ARGS__)
         #else
             #define DEBUG(format, ...)
         #endif

        調試信息會按照下面格式輸出
        FILE: xxx, LINE: xxx, …….

        到這邊似乎都挺完美了,可還有一個問題,這邊的調試開關是全局的,可是有時候我們只關心某一模塊的調試信息,要是能屏蔽無關的信息那就好了,那我們再做一點功課,簡單的實現日志分級,以下是代碼實現:

        /*
         * logger.h
         *
         *  Created on: 2018年01月28日
         *      Author: dj666
         */
        
        #ifndef APP_PUBLIC_LOGGER_H_
        #define APP_PUBLIC_LOGGER_H_
        
        #define __DEBUG    //日志模塊總開關,注釋掉將關閉日志輸出
        
        #ifdef __DEBUG
            #define DEBUG(format, ...) printf (format, ##__VA_ARGS__)
        #else
            #define DEBUG(format, ...)
        #endif
        
        //定義日志級別
        enum LOG_LEVEL {    
            LOG_LEVEL_OFF=0,
            LOG_LEVEL_FATAL,
            LOG_LEVEL_ERR,
            LOG_LEVEL_WARN,
            LOG_LEVEL_INFO,
            LOG_LEVEL_ALL,
        };
        
        #define log_fatal(level,format, ...) \
            do { \
                 if(level>=LOG_LEVEL_FATAL)\
                   DEBUG("\n->FATAL @ FUNC:%s FILE:%s LINE:%d \n" format "\n",\
                             __func__, __FILE__, __LINE__, ##__VA_ARGS__ );\
            } while (0)
        
        #define log_err(level,format, ...) \
            do { \
                 if(level>=LOG_LEVEL_ERR)\
                   DEBUG("\n->ERR   @ FUNC:%s FILE:%s LINE:%d \n" format "\n",\
                             __func__, __FILE__, __LINE__, ##__VA_ARGS__ );\
            } while (0)
        
        #define log_warn(level,format, ...) \
            do { \
                 if(level>=LOG_LEVEL_WARN)\
                   DEBUG("\n->WARN  @ FUNC:%s \n" format "\n",__func__, ##__VA_ARGS__ );\
            } while (0)
        
        #define log_info(level,format, ...) \
            do { \
                 if(level>=LOG_LEVEL_INFO)\
                   DEBUG("\n->INFO  \n"format"\n",##__VA_ARGS__ );\
            } while (0)
        
        #define log_debug(level,format, ...) \
            do { \
                 if(level>=LOG_LEVEL_ALL)\
                   DEBUG("\n->DEBUG \n"format"\n",##__VA_ARGS__ );\
            } while (0)
        
        #endif /* APP_PUBLIC_LOGGER_H_ */


        使用也非常簡單,定義一個局部的變量來保存該模塊的日志輸出級別,下面是使用示例:

        #include"logger.h"
        
        static enum LOG_LEVEL logger=LOG_LEVEL_WARN;//模塊日志輸出級別
        
        int main(void)
        { 
            logger = LOG_LEVEL_ALL; //修改模塊日志輸出級別
            log_debug(logger,"this is a debug");
            log_info(logger,"this is a info");
            log_warn(logger,"%s","this is a warn");
            log_err(logger,"this is a err %d ",-1);
        }


        c語言宏定義##__VA_ARGS__封裝printf函數,單片機實現簡單的分級日志模塊_昵稱隨便取啦的博客-CSDN博客

        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



        關鍵詞: c

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 金湖县| 枣阳市| 平山县| 镇沅| 鄱阳县| 株洲县| 东海县| 哈巴河县| 榆林市| 视频| 青川县| 财经| 迁西县| 南宫市| 高平市| 尚义县| 隆尧县| 平遥县| 敦煌市| 青神县| 玉溪市| 吴川市| 东辽县| 左云县| 兴仁县| 永康市| 大城县| 长寿区| 农安县| 富源县| 牙克石市| 江口县| 大庆市| 元阳县| 城市| 杭锦后旗| 宁远县| 那坡县| 全州县| 南丹县| 长寿区|