Ⅰ寫(xiě)在前面
為方便大家閱讀,本文內(nèi)容已經(jīng)整理成PDF文件:
http://pan.baidu.com/s/1gfHygyn
對(duì)于我們大部分使用單片機(jī)進(jìn)行裸機(jī)開(kāi)發(fā)的朋友來(lái)說(shuō),可能很少有人在程序中許多關(guān)鍵的地方打印一些關(guān)鍵信息。
有較大系統(tǒng)開(kāi)發(fā),或復(fù)雜系統(tǒng)開(kāi)發(fā)經(jīng)驗(yàn)的朋友一般都會(huì)在程序中輸出很多調(diào)試信息,如在UCOS、freeRTOS、Linux等系統(tǒng)開(kāi)發(fā)調(diào)試時(shí)打印許多關(guān)鍵信息。
1.我們?cè)谑褂?a href="http://ttokpm.com/v/tag/751/" target="_blank">STM32庫(kù)開(kāi)發(fā)時(shí),在stm32fxxx_conf.h文件下會(huì)發(fā)現(xiàn)如下這么一條語(yǔ)句:
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
這條語(yǔ)句,對(duì)于使用寄存器,開(kāi)發(fā)簡(jiǎn)單且不大程序的朋友而言,可能他覺(jué)得用處不大,它可能就覺(jué)得很占資源,且耗時(shí)。
其實(shí)不然,ST這么設(shè)計(jì)是有他一定的道理的,對(duì)于開(kāi)發(fā)大型、復(fù)雜系統(tǒng)的朋友而言,這條語(yǔ)句其實(shí)用處很大。每次,程序運(yùn)行錯(cuò)誤之后,它會(huì)打印程序代碼指定的位置,方便我們?cè)邶嫶蟮某绦蛑泻芸煺业藉e(cuò)誤的位置。
2.我們的系統(tǒng)會(huì)隨著時(shí)間的推移,不斷升級(jí)更新,也就是需要提交很多版本的可執(zhí)行文件(hex、bin等)。但是,產(chǎn)品后期使用中,我們對(duì)某些設(shè)備進(jìn)行了升級(jí),可能忽略了一些設(shè)備,也就是有些設(shè)備沒(méi)有升級(jí),如果出現(xiàn)故障,我們?cè)鯓硬拍芎芸煺业绞悄囊粋€(gè)版本的軟件出現(xiàn)故障呢?
這里就需要我們?cè)诔绦蛑刑砑右恍╆P(guān)于版本的信息,我們最基礎(chǔ)的就是Vx.x.x.x等這種信息,但對(duì)于大型系統(tǒng)而言,這種信息是不夠的,還需要更多,比如:編譯日期,時(shí)間,編譯環(huán)境的版本等。
Ⅱ幾種特殊標(biāo)準(zhǔn)定義
上面說(shuō)了這么多,就是需要讓大家知道,這些特殊標(biāo)準(zhǔn)定義的用途。上面說(shuō)的只是簡(jiǎn)單的舉例,其實(shí)他們的用途還很廣泛,掌握了基礎(chǔ)之后相信你們都會(huì)知道它們更多比較實(shí)用的意義。言歸正傳,下面講述這些基礎(chǔ)的知識(shí)。
本文主要講述下面幾個(gè)標(biāo)準(zhǔn)定義:
__LINE__:正在編譯文件的行號(hào)
__FILE__:正在編譯文件的文件名
__DATE__:編譯時(shí)刻的日期字符串 如“Jun 17 2017”
__TIME__:編譯時(shí)刻的時(shí)間字符串 如”1000“
__STDC__:判斷該文件是不是標(biāo)準(zhǔn)C程序
1.__FILE__編譯文件名稱
File中文意思即文件,這里的意思主要是指:正在編譯文件對(duì)應(yīng)正在編譯文件的路徑和文件的名稱。
Keil版本對(duì)應(yīng)的路徑是相對(duì)于工程文件而言的路徑,IAR版本路徑是相對(duì)Windows路徑。
比如下面提供源代碼工程:
char BuildFile[] = __FILE__;
printf("編譯文件路徑:%s\n", BuildFile);
Keil:
編譯文件路徑:App\main.c
IAR:
編譯文件路徑:C:\Users\Administrator\Desktop\STM32F417ZG(IAR)_ANSIC幾種特殊的標(biāo)準(zhǔn)定義\App\main.c
2.__LINE__編譯文件行號(hào)
上面說(shuō)的是編譯的文件名,是一個(gè)字符串,而這里說(shuō)的是行號(hào),是一個(gè)整型變量,這是這兩者的區(qū)別,所以在我提供工程中可以看到的源代碼:
char BuildLine = __LINE__;
printf("編譯代碼所在行:%d\n", BuildLine);
可以看不是數(shù)組的字符串,打印信息:
編譯代碼所在行:44
一般情況下,__FILE__是和__LINE__結(jié)合一起使用,用于打印我們代碼信息,方便快速定位代碼位置。
3.__DATE__編譯日期
__DATE__日期,需要注意的是:這個(gè)日期是你在編譯時(shí)Windows系統(tǒng)的日期,如果對(duì)應(yīng)那部分代碼之前編譯好了,后面沒(méi)有編譯,這個(gè)日期還是之前的日期,而不是后面編譯的日期。因此,如果這里用于定版本,就需要在定版本時(shí)對(duì)工程進(jìn)行全部重新編譯,它才會(huì)更新至你最后編譯的日期。
代碼:
char BuildDate[] = __DATE__;
printf("編譯日期:%s\n", BuildDate);
輸出結(jié)果:
編譯日期:Jun 17 2017
4.__TIME__編譯時(shí)間
這個(gè)和__DATE__一樣的原理,編譯時(shí)的時(shí)間,也是一個(gè)字符串。
再次提醒:用于定版本:需要重新編譯,這樣才是最后一次編譯時(shí)間。
代碼:
char BuildTime[] = __TIME__;
printf("編譯時(shí)間:%s\n", BuildTime);
輸出結(jié)果
編譯時(shí)間:1115
5.__STDC__標(biāo)準(zhǔn)C代碼
這個(gè)標(biāo)準(zhǔn)在我們單片機(jī)及嵌入式編程中運(yùn)用的比較少,當(dāng)要求程序嚴(yán)格遵循ANSIC標(biāo)準(zhǔn)時(shí)該標(biāo)識(shí)符被賦值為1,主要是判斷我們的程序文件是不是標(biāo)準(zhǔn)C程序。
#ifdef __STDC__
printf("標(biāo)準(zhǔn)C代碼文件\n");
#else
printf("非標(biāo)準(zhǔn)C代碼文件\n");
#endif
Ⅲ源代碼分析與下載
為了方便大家學(xué)習(xí),本文提供的源代碼比較基礎(chǔ)和簡(jiǎn)單,也方便理論結(jié)合實(shí)際學(xué)習(xí),僅供參考。
我們?cè)谥靶陆ê玫腄emo工程上添加了如下部分代碼:
char BuildLine = __LINE__;
char BuildFile[] = __FILE__;
char BuildDate[] = __DATE__;
char BuildTime[] = __TIME__;
printf("編譯文件路徑:%s\n", BuildFile);
printf("編譯代碼所在行:%d\n", BuildLine);
printf("編譯日期:%s\n", BuildDate);
printf("編譯時(shí)間:%s\n", BuildTime);
#ifdef __STDC__
printf("標(biāo)準(zhǔn)C代碼文件\n");
#else
printf("非標(biāo)準(zhǔn)C代碼文件\n");
#endif
Keil版本輸出結(jié)果:
編譯文件路徑:App\main.c
編譯代碼所在行:44
編譯日期:Jun 17 2017
編譯時(shí)間:1115
標(biāo)準(zhǔn)C代碼文件
IAR版本輸出結(jié)果:
編譯文件路徑:C:\Users\Administrator\Desktop\STM32F417ZG(IAR)_ANSIC幾種特殊的標(biāo)準(zhǔn)定義\App\main.c
編譯代碼所在行:44
編譯日期:Jun 17 2017
編譯時(shí)間:1100
標(biāo)準(zhǔn)C代碼文件
源代碼工程(STM32F417ZG_ANSIC幾種特殊的標(biāo)準(zhǔn)定義)下載地址:
http://pan.baidu.com/s/1hskScba
-
單片機(jī)
+關(guān)注
關(guān)注
6030文章
44491瀏覽量
632014 -
寄存器
+關(guān)注
關(guān)注
31文章
5295瀏覽量
119824 -
ANSIC
+關(guān)注
關(guān)注
0文章
6瀏覽量
8663
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論