當前位置:首頁 > 單片機 > 單片機
[導讀]  在程序設計中,變量具體可以分為四種類型:全局變量、靜態(tài)全局變量、局部變量、靜態(tài)局部變量。這幾種變量類型對函數(shù)的可重入產(chǎn)生的重大的影響,因為不同的編譯器采用不同的策略?! ♂槍?1的存儲區(qū)有限,keil c

  在程序設計中,變量具體可以分為四種類型:全局變量、靜態(tài)全局變量、局部變量、靜態(tài)局部變量。這幾種變量類型對函數(shù)的可重入產(chǎn)生的重大的影響,因為不同的編譯器采用不同的策略。

  針對51的存儲區(qū)有限,keil c51因此有了覆蓋和共享的處理方法。

  共享:共享是針對全局變量或靜態(tài)變量而言的,對全局變量定義后就對其分配了內(nèi)存,其他變量不會覆蓋這一地址,在任何函數(shù)或者程序中都可以共享該變量的內(nèi)存。

  覆蓋:如果一個程序不再被調(diào)用,也不由其他的程序調(diào)用,在其他的程序運行之前程序也不在運行,那么這個程序的局部變量可以放在與其他的程序完全相同的RAM空間,這就是覆蓋。

  所以說C51編譯器并不是真正的C編譯器。

  先說一下keilc51的“覆蓋技術”。

1.局部變量存儲在全局RAM空間(不考慮擴展外部存儲器的情況);

2.在編譯鏈接時,即已經(jīng)完成局部變量的定位;

3.如果各函數(shù)之間沒有直接或間接的調(diào)用關系,則其局部變量空間便可覆蓋。

  在單任務編程下,重入似乎不是個問題,因為函數(shù)會一直執(zhí)行下去,就算被中斷打斷,中斷服務程序保存寄存器,中斷執(zhí)行完畢后又恢復環(huán)境(注意到keil c51默認這樣處理:中斷中局部變量會采用靜態(tài)分配內(nèi)存的方式,不會與函數(shù)的局部變量覆蓋),函數(shù)不會存在重不重入的問題。

  在實時操作系統(tǒng)下,就必須考慮函數(shù)的重不重入了。

先考慮一下可重入函數(shù)與不可重入函數(shù)的具體區(qū)別。在實時操作系統(tǒng)下,二者的區(qū)別并不是執(zhí)行過程中能否被打斷執(zhí)行??芍厝牒瘮?shù)在執(zhí)行過程中可以被打斷,內(nèi)核啟動另一個任務,該任務再次調(diào)用該函數(shù)。不可重入函數(shù)在執(zhí)行過程中可以被打斷,但在另一個任務中不得在調(diào)用這個函數(shù),除非再次回到原來的任務將這個函數(shù)執(zhí)行完成。

再來考慮可重入函數(shù)與不可重入函數(shù)的實現(xiàn):因為全局變量,靜態(tài)全局變量,靜態(tài)局部變量會分配到固定的內(nèi)存地址,這些量在可重入方面只需考慮保護,問題的關鍵在于動態(tài)局部變量的處理,如互相覆蓋和入棧。

  可重入函數(shù):首先是據(jù)絕對意義上的可重入函數(shù),函數(shù)不使用全局變量,只使用存放在寄存器的局部變量。這種函數(shù)任意時刻都可以被打斷,或再次調(diào)用,應為函數(shù)的局部變量在被中斷時全部被入棧了,等到重新啟用時又全部出棧了,例如函數(shù)

unsignecharMin(unsignedcharx1,unsignedcharx2){if(x1>x2){x1=x2;}returnx1;}

  另一種函數(shù):不使用全局變量,局部變量部分存放在寄存器,部分存放在固定內(nèi)存地址(哪怕靜態(tài)化,獨享該內(nèi)存),他總是不可重入的,分析如下:靜態(tài)的局部變量a,在第一進入函數(shù)后改變,中斷第二次進入又改變,回到第一調(diào)用時可能就改變了,存在Bug,不可重入。

  第二種可重入函數(shù):函數(shù)使用全部變量 ,只使用存放在寄存器的局部變量(keil c51盡量將局部變量保存在寄存器)。 這種函數(shù)常常是系統(tǒng)函數(shù),使用臨界區(qū)代碼。對起到標志作用的全局變量進行操作時要關中斷,防止中斷打斷破壞,處理完畢后再開中斷。這其實已經(jīng)不是絕對意義上的可重入函數(shù),但局部變量通過寄存器存放可以避免修改其他函數(shù)的局部變量。

  第三種可重入函數(shù):函數(shù)使用全局變量,局部變量部分存放在寄存器,部分存放在固定內(nèi)存地址(因為局部變量過多)。這種函數(shù)跟第二種很相似,不是真正意義上的可重入。進入函數(shù)必須關中斷,出去在開中斷。值得注意的是:存放在固定內(nèi)存地址的局部變量需要聲明為靜態(tài)以獨享該內(nèi)存,這樣做的目的并不是怕其他函數(shù)其他破壞其局部變量(關中斷不可能被破壞),而是怕破壞其他函數(shù)的局部變量,因為其他函數(shù)若有局部變量和其共享一個內(nèi)存空間,執(zhí)行其他函數(shù)→該函數(shù)→其他函數(shù),可能導致其他函數(shù)局部變量被破壞。

  不可重入函數(shù)(前面已經(jīng)說明這個函數(shù)在執(zhí)行過程中若被打斷,不會再次調(diào)用,即不可重入)

  第一種函數(shù):不使用全局變量,局部變量部分存放在寄存器,部分存放在固定內(nèi)存地址(若都存放在寄存器就是可重入函數(shù)了)。 這種函數(shù)不可重入,但存放在固定內(nèi)存地址的局部變量應該防止互相覆蓋,具體原因下面分析。

  第二種函數(shù): 不使用全局變量,局部變量都存放在固定內(nèi)存地址,存放在固定內(nèi)存地址的局部變量應該防止互相覆蓋,具體原因下面分析。不過這種函數(shù)很少見,因為keil c51先考慮把局部變量存放在寄存器。

  第三種函數(shù): 使用全局變量,局部變量部分存放在寄存器。進入函數(shù)不需要關中斷保護全局變量,因為這種函數(shù)大多是用戶函數(shù),全局變量大多不是起標志作用的,一邊是傳遞數(shù)據(jù)的,即一般是一個函數(shù)修改,一個函數(shù)讀取。

  第四種函數(shù):使用全局變量,局部變量部分存放在寄存器,部分存放在固定內(nèi)存地址,存放在固定內(nèi)存地址的局部變量應該防止互相覆蓋。跟第三種類似。

  還有一種函數(shù): 使用全局變量,局部變量都存放在固定內(nèi)存地址。跟第二種一樣少見,都不考慮。

  分析不可重入函數(shù)存放在固定地址的局部變量不能相互覆蓋的問題:

Keil進行以下處理:如果各函數(shù)之間沒有直接或間接的調(diào)用關系,則其局部變量空間便可覆蓋。

任務的基本結(jié)構(gòu)與模式:

voldTaskA(void*ptr){UINT8vaL_a;//其他一些變量定義do{//實際的用戶任務處理代碼}while(1);}voidTaskB(void*ptr){UINT8vaL_b;//其他一些變量定義do{Funcl();//其他實際的用戶任務處理代碼}while(1);}voidFuncl(){UlNT8val_fa;//其他變量的定義//函數(shù)的處理代碼}

  在上面的代碼中,TaskA與TaskB并不存在直接或間接的調(diào)用關系,因而其局部變量val_a與val_b便是可以被互相覆蓋的,即其可能都被定位于某一個相同的RAM空間。這樣,當TaskA運行一段時間,改變了val_a后,TaskB取得CPU控制權并運行時,便可能會改變val_b。由于其指向相同的RAM空間,導致TaskA重新取得CPU控制權時,val—a的值已經(jīng)改變,從而導致程序運行不正確,反過來亦然。另一方面,F(xiàn)uncl()與TaskB有直接的調(diào)用關系,因而其局部變量val_fa與val_b不會被互相覆蓋,但也不能保證其局部變量val_fa不會與TaskA或其他任務的局部變量形成可覆蓋關系。

  所以得到以下結(jié)論:存在直接或間接調(diào)用關系的函數(shù)局部變量不會覆蓋,不存在調(diào)用關系的函數(shù)局部變量又不能覆蓋。

  怎么辦?

  第一種解決方案:我們只能將非重入函數(shù)中不是存放在寄存器中的局部變量全部靜態(tài)化存放在固定內(nèi)存地址,這樣內(nèi)存開銷就會很大,但要保證程序運行的正確性,只能這么做。

  第二種:局部變量覆蓋,通過進入程序就關中斷進行保護,這樣就不會被打斷了,但這樣做系統(tǒng)的實時性就會降低很多。 現(xiàn)實情況是根據(jù)具體的情況進行決定,具體問題具體分析。


本站聲明: 本文章由作者或相關機構(gòu)授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉