久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

Hi,歡迎來到嵌入式培訓高端品牌 - 華清遠見教育科技集團<北京總部官網>,專注嵌入式工程師培養15年!
當前位置: > 華清遠見教育科技集團 > 嵌入式學習 > 講師博文 > 何為C語言關鍵字volatile
何為C語言關鍵字volatile
時間:2017-01-04作者(zhe):華清遠見(jian)

在學習(xi)C關(guan)(guan)鍵(jian)詞(ci)的時候,我們看到(dao)了一(yi)個新面孔(kong)—&mdash;volatile。在程(cheng)序員(yuan)面試寶典中(zhong)提到(dao)“關(guan)(guan)鍵(jian)字(zi)volatile的面試例題是考查(cha)嵌入式(shi)編程(cheng)”,中(zhong)間有一(yi)段解析:

回(hui)答(da)不出這(zhe)個問(wen)(wen)題的(de)(de)人是不會被雇(gu)傭的(de)(de)。我認為(wei)這(zhe)是區分(fen)C程(cheng)序員(yuan)和嵌(qian)入式(shi)系統程(cheng)序員(yuan)的(de)(de)基本的(de)(de)問(wen)(wen)題。搞嵌(qian)入式(shi)的(de)(de)家伙(huo)們經常同硬件、中斷、RTOS等等打交道(dao),所(suo)有這(zhe)些都(dou)要求用到volatile變量。不懂(dong)得volatile的(de)(de)內容將(jiang)會帶來災難。 假設(she)被面試者正(zheng)確地回(hui)答(da)了這(zhe)是問(wen)(wen)題(嗯,懷疑是否會是這(zhe)樣(yang)),我將(jiang)稍微深究一(yi)下(xia),看一(yi)下(xia)這(zhe)家伙(huo)是不是直(zhi)正(zheng)懂(dong)得volatile完全的(de)(de)重要性。

 下(xia)面(mian)我(wo)們來看下(xia)寶(bao)典中(zhong)提(ti)到(dao)的問(wen)題:

關(guan)鍵字volatile有什么含(han)意?并給出三個(ge)不同(tong)的(de)例子。

volatile的(de)(de)本意是“易變(bian)的(de)(de)” 由于(yu)訪問寄存器(qi)的(de)(de)速度要(yao)快過RAM,所(suo)(suo)以編譯器(qi)一(yi)般都會作減少存取(qu)外(wai)部RAM的(de)(de)優化,但有可(ke)能會讀臟數(shu)據(ju)(ju)。當要(yao)求(qiu)使用volatile 聲明的(de)(de)變(bian)量的(de)(de)值的(de)(de)時(shi)候,系統總是重新(xin)從它(ta)所(suo)(suo)在(zai)的(de)(de)內存讀取(qu)數(shu)據(ju)(ju),即使它(ta)前面的(de)(de)指令剛剛從該(gai)處讀取(qu)過數(shu)據(ju)(ju)。而且讀取(qu)的(de)(de)數(shu)據(ju)(ju)立刻被保存。

精確地(di)說就(jiu)是(shi),優(you)化器在用(yong)到這(zhe)個(ge)(ge)變量(liang)(liang)時(shi)必須每次都(dou)小心地(di)重新從內存里(li)讀取這(zhe)個(ge)(ge)變量(liang)(liang)的(de)值,而不是(shi)使用(yong)保存在寄存器里(li)的(de)備份。 下面是(shi)volatile變量(liang)(liang)的(de)幾個(ge)(ge)例子:

1) 并行設備的硬件寄存器(如:狀態寄存器)
        2) 一個中斷服務子程序中會訪問到的非自動變量(Non-automatic variables) 
        3) 多線程(cheng)應用(yong)中(zhong)被幾個任務共享(xiang)的(de)變(bian)量

在這里要說下(xia),其(qi)(qi)實不(bu)僅僅是并行設備(bei)的(de)(de)硬(ying)件(jian)寄(ji)(ji)存器,串行設備(bei)的(de)(de)硬(ying)件(jian)寄(ji)(ji)存器也行,也就(jiu)(jiu)是說只要是硬(ying)件(jian)寄(ji)(ji)存器都需要這么做(zuo),當(dang)我們不(bu)能確保寄(ji)(ji)存器里的(de)(de)值一(yi)定不(bu)會(hui)變(bian)的(de)(de)情(qing)況下(xia)就(jiu)(jiu)需要使用volatile。看下(xia)面的(de)(de)例子(zi),2410addr.h是所有(you)寄(ji)(ji)存器中的(de)(de)頭文件(jian),其(qi)(qi)中就(jiu)(jiu)有(you)很多volatile的(de)(de)應用,下(xia)面列出一(yi)個宏定義出來:

#define rURXH0 (*(volatile unsigned char *)0x50000024) //UART 0 Receive buffer

這個就是串行的(de)(de)接收buffer,其地址為0x50000024,如(ru)果(guo)我(wo)們沒有將這個地址強行轉換(huan)成volatile,那么我(wo)們在(zai)使用rURXH0時,可能直接從cpu的(de)(de)寄(ji)存(cun)(cun)器(qi)中(zhong)(zhong)取值(zhi)。因為之前(qian)rURXH0被(bei)訪(fang)問(wen)過(guo),也就是說之前(qian)就從內存(cun)(cun)中(zhong)(zhong)取出rURXH0的(de)(de)值(zhi)保存(cun)(cun)到 某個寄(ji)存(cun)(cun)器(qi)中(zhong)(zhong)。之所(suo)以(yi)直接從寄(ji)存(cun)(cun)器(qi)中(zhong)(zhong)取值(zhi),而不(bu)去內存(cun)(cun)中(zhong)(zhong)取值(zhi),是因為編(bian)譯器(qi)優(you)化(hua)代(dai)碼的(de)(de)結果(guo)(訪(fang)問(wen)cpu寄(ji)存(cun)(cun)器(qi)比(bi)訪(fang)問(wen)ram快的(de)(de)多)。用volatile關(guan)鍵字對(dui)0x50000024進行強制轉換(huan),使得(de)每一次被(bei)訪(fang)問(wen)rURXH0時,執(zhi)行部件(jian)都會(hui)從0x50000024這個內存(cun)(cun)單元(yuan)中(zhong)(zhong)取出值(zhi)來(lai)賦值(zhi)給(gei)rURXH0。

volatile關鍵(jian)字(zi)是一種類型(xing)修(xiu)飾(shi)符,用它聲明的(de)(de)類型(xing)變(bian)(bian)量表示可(ke)(ke)以被某些編(bian)譯(yi)器(qi)未知(zhi)的(de)(de)因素更改(gai)。volatile提(ti)醒編(bian)譯(yi)器(qi)它后面(mian)所(suo)定(ding)義的(de)(de)變(bian)(bian)量隨時都(dou)有可(ke)(ke)能(neng)(neng)改(gai)變(bian)(bian),因此編(bian)譯(yi)后的(de)(de)程序每(mei)次需要存(cun)儲或讀(du)取(qu)這(zhe)個(ge)變(bian)(bian)量的(de)(de)時候(hou),都(dou)會(hui)直(zhi)接從變(bian)(bian)量地(di)址(zhi)中(zhong)讀(du)取(qu)數據。如(ru) 果沒有volatile關鍵(jian)字(zi),則(ze)編(bian)譯(yi)器(qi)可(ke)(ke)能(neng)(neng)優化(hua)讀(du)取(qu)和存(cun)儲,可(ke)(ke)能(neng)(neng)暫時使用寄存(cun)器(qi)中(zhong)的(de)(de)值(zhi),如(ru)果這(zhe)個(ge)變(bian)(bian)量由別的(de)(de)程序更新了的(de)(de)話(hua),將(jiang)出(chu)現不一致(zhi)的(de)(de)現象(xiang)。所(suo)以遇到(dao)這(zhe)個(ge)關鍵(jian)字(zi)聲明的(de)(de)變(bian)(bian)量,編(bian)譯(yi)器(qi)對訪問(wen)該變(bian)(bian)量的(de)(de)代(dai)碼就不再進行(xing)優化(hua),從而可(ke)(ke)以提(ti)供對特殊地(di)址(zhi)的(de)(de)穩定(ding)訪問(wen)。

一般說來,volatile用在如下的幾個地方:
        1、中斷服務程序中修改的供其它程序檢測的變量需要加volatile;
        2、多任務環境下各任務間共享的標志應該加volatile;
        3、存(cun)(cun)儲器映(ying)射的(de)(de)硬件寄(ji)存(cun)(cun)器通常也要加(jia)volatile說明,因為每次對(dui)它的(de)(de)讀寫都可能由不同意義;

另(ling)外,以上這(zhe)幾種情況經(jing)常還要同時考(kao)慮數據的(de)完整性(相互關聯的(de)幾個標志讀了一半被打斷(duan)(duan)了重寫),在1中(zhong)可以通過(guo)關中(zhong)斷(duan)(duan)來實現,2中(zhong)可以禁止任務調度,3中(zhong)則只能依靠硬件的(de)良好設計了。

 下面舉例說明。在(zai)DSP開發中,經常需要等待某個事(shi)件的觸(chu)發,所以經常會(hui)寫出(chu)這樣(yang)的程序:

short flag;
        void test()
        {
        do1();
        while(flag==0);
        do2();
   &nbsp;    }

 這段程序等待內存變量(liang)flag的值變為1(懷疑(yi)此(ci)處(chu)是0,有點疑(yi)問(wen),)之(zhi)后才運(yun)行do2()。

變量flag的(de)值由(you)別的(de)程(cheng)序(xu)(xu)更(geng)改,這(zhe)(zhe)個程(cheng)序(xu)(xu)可能是某(mou)個硬件中斷(duan)服(fu)務程(cheng)序(xu)(xu)。例(li)如(ru):如(ru)果某(mou)個按(an)(an)鈕(niu)按(an)(an)下的(de)話,就會對(dui)DSP產生中斷(duan),在按(an)(an)鍵中斷(duan)程(cheng)序(xu)(xu)中修改flag為1,這(zhe)(zhe)樣(yang)上面(mian)的(de)程(cheng)序(xu)(xu)就能夠得以(yi)繼續運行。

但(dan)是,編譯器(qi)(qi)并(bing)不知道flag的(de)(de)(de)值會被別的(de)(de)(de)程序(xu)修(xiu)改,因(yin)此在(zai)它(ta)進(jin)行(xing)優化(hua)的(de)(de)(de)時候(hou),可能(neng)會把flag的(de)(de)(de)值先讀入(ru)某個(ge)(ge)寄存器(qi)(qi),然后等待那個(ge)(ge)寄存器(qi)(qi)變(bian)為(wei)1。如果不幸(xing)進(jin)行(xing)了(le)這樣的(de)(de)(de)優化(hua),那么while循環就變(bian)成(cheng)了(le)死(si)循環,因(yin)為(wei)寄存器(qi)(qi)的(de)(de)(de)內(nei)容不可能(neng)被中斷服務程序(xu)修(xiu)改。

為了讓程序每次都讀取真正flag變量的值,就需要定義為如下形式:
volatile short flag;

需(xu)要注意(yi)的(de)(de)是,沒有(you)volatile也可能能正常(chang)(chang)運行,但是可能修(xiu)改了編(bian)譯器的(de)(de)優化(hua)級別(bie)之后就(jiu)又不能正常(chang)(chang)運行了。因此經常(chang)(chang)會(hui)出(chu)現debug版(ban)本(ben)(ben)正常(chang)(chang),但是release版(ban)本(ben)(ben)卻不能正常(chang)(chang)的(de)(de)問題。所以為(wei)了安全起(qi)見(jian),只要是等待別(bie)的(de)(de)程(cheng)序(xu)修(xiu)改某個變量的(de)(de)話(hua),就(jiu)加(jia)上volatile關鍵字。在曹(cao)老師(shi)的(de)(de)《volatile在多(duo)線(xian)程(cheng)中(zhong)(zhong)的(de)(de)應(ying)用》一文中(zhong)(zhong)也舉例(li)說明了volatile在多(duo)線(xian)程(cheng)中(zhong)(zhong)的(de)(de)應(ying)用。

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)