博客專欄

        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

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 镇巴县| 东光县| 建始县| 怀来县| 喀喇沁旗| 凤城市| 怀集县| 扎鲁特旗| 紫金县| 贵阳市| 合作市| 泽库县| 黄龙县| 布拖县| 湖南省| 上林县| 连云港市| 万载县| 逊克县| 介休市| 瓮安县| 吉安市| 连山| 繁昌县| 印江| 庐江县| 龙川县| 馆陶县| 上蔡县| 波密县| 准格尔旗| 上犹县| 绿春县| 左贡县| 临江市| 公主岭市| 玉溪市| 吴堡县| 綦江县| 隆昌县| 苍山县|