女人被狂躁到高潮视频免费无遮挡,内射人妻骚骚骚,免费人成小说在线观看网站,九九影院午夜理论片少妇,免费av永久免费网址

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

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

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

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

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

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

  先說一下keilc51的“覆蓋技術(shù)”。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  怎么辦?

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

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


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

嵌入式開發(fā)作為一種專業(yè)且技術(shù)密集型的領(lǐng)域,涵蓋了從硬件底層驅(qū)動、中間件到應(yīng)用層軟件開發(fā)等多個層面的工作,其所需的工具種類繁多,各有針對性,旨在提升開發(fā)效率、保證代碼質(zhì)量以及簡化調(diào)試過程。

關(guān)鍵字: 嵌入式開發(fā) keil

單片機(jī)內(nèi)部有很多的特殊功能寄存器,每個寄存器在單片機(jī)內(nèi)部都分配有唯一的地址,一般我們會根據(jù)寄存器功能的不同給寄存器賦予各自的名稱,當(dāng)我們需要在程序中操作這些特殊功能寄存器時,必須要在程序的最前面將這些名稱加以聲明,聲明的...

關(guān)鍵字: C51 數(shù)據(jù)類型 擴(kuò)充定義

數(shù)據(jù)元(Data Element),也稱為數(shù)據(jù)元素,是用一組屬性描述其定義、標(biāo)識、表示和允許值的數(shù)據(jù)單元,在一定語境下,通常用于構(gòu)建一個語義正確、獨(dú)立且無歧義的特定概念語義的信息單元。數(shù)據(jù)元可以理解為數(shù)據(jù)的基本單元,將若...

關(guān)鍵字: C51 數(shù)據(jù)類型

之后新建新的工程,添加.a文件就可以使用了,當(dāng)然也可以使用keil來添加,但是keil默認(rèn)的是用.lab,需要自己配置一下文件屬性,改為lib文件即可。一半release sdk的時候用這種方式很關(guān)鍵的,畢竟自己的核心代...

關(guān)鍵字: keil 文件屬性 lib文件

▼點(diǎn)擊下方名片,關(guān)注公眾號▼歡迎關(guān)注【玩轉(zhuǎn)單片機(jī)與嵌入式】公眾號,回復(fù)關(guān)鍵字獲取更多免費(fèi)資料?;貜?fù)【加群】,限時免費(fèi)進(jìn)入知識共享群;回復(fù)【3D封裝庫】,常用元器件的3D封裝庫;回復(fù)【電容】,獲取電容、元器件選型相關(guān)的內(nèi)容...

關(guān)鍵字: C51 MDK RealView

在Keil C51軟件中51單片機(jī)的中斷服務(wù)和外設(shè)驅(qū)動程序的開發(fā)

關(guān)鍵字: keil5 編譯 C51

Intel公司1980年推出了MCS-51系列單片機(jī):集成 8位CPU、4K字節(jié)ROM、128字節(jié)RAM、4個8位并口、1個全雙工串行口、2個16位定時/計(jì)數(shù)器。尋址范圍64K,并有控制功能較強(qiáng)的布爾處理器。 80C5...

關(guān)鍵字: C51 KEIL 編程

c上標(biāo)3下標(biāo)5怎么算用計(jì)算機(jī),c上標(biāo)3下標(biāo)5怎么算

關(guān)鍵字: C51 KEIL

DSP28335與AD7606通過SPI的串行數(shù)據(jù)交互

關(guān)鍵字: keil C
關(guān)閉