當(dāng)前位置:首頁(yè) > 通信技術(shù) > 通信技術(shù)
[導(dǎo)讀]本文介紹了Keil C51實(shí)現(xiàn)大于64 KB程序的bank分組代碼切換機(jī)制的原理,提出了沒(méi)有操作系統(tǒng)情況下非正常轉(zhuǎn)移時(shí)bank的處理方法以及μc/os—II操作系統(tǒng)在多bank分區(qū)程序移植中應(yīng)采取的措施,在開(kāi)發(fā)實(shí)例中均得到了很好的應(yīng)用。

 在8051核單片機(jī)龐大的家族中,C8051F系列作為其中的后起之秀,是目前功能最全、速度最快的8051衍生單片機(jī)之一,正得到越來(lái)越廣泛的應(yīng)用。它集成了嵌入式系統(tǒng)的許多先進(jìn)技術(shù),有豐富的模擬和數(shù)字資源.是一個(gè)完全意義上的SoC產(chǎn)品。

  C805IFl2X作為該系列中的高端部分,具有最快100MIPS的峰值速度,集成了最多的片上資源。其128 KB的片上Flash和8 KB的片上RAM足以滿足絕大多數(shù)應(yīng)用的需求。使用C8051F12X,只需外加為數(shù)不多的驅(qū)動(dòng)和接口,就可構(gòu)成較大型的完整系統(tǒng)。只是其中128 KB的Flash存儲(chǔ)器不可避免地要處理bank分區(qū)問(wèn)題。

  幸運(yùn)的是Keil C51開(kāi)發(fā)環(huán)境對(duì)C8051F系列有良好的支持,包括一般的跨bank分區(qū)的程序跳轉(zhuǎn)和調(diào)用。作為數(shù)據(jù)存儲(chǔ)器使用時(shí),F(xiàn)lash的分區(qū)讀寫完全是編程者要考慮的事情,與開(kāi)發(fā)環(huán)境無(wú)關(guān)。本文只針對(duì)特殊的強(qiáng)制轉(zhuǎn)移和μC/OS—II在多bank分區(qū)中的移植問(wèn)題展開(kāi)討論。

  1 C8051F12X在Keil C51中的多bank分區(qū)轉(zhuǎn)移機(jī)制

  Keil C51的連接定位器支持分組連接,允許生成代碼長(zhǎng)度大于64 KB的8051目標(biāo)程序_1_。一般的8051系統(tǒng)只提供16根地址線,需要附加地址線來(lái)實(shí)現(xiàn)代碼分組切換,而編譯器產(chǎn)生bank切換代碼時(shí)受到配置文件L51_BANK.A51的支持,所以用戶必須根據(jù)自己的硬件結(jié)構(gòu)來(lái)修改這個(gè)配置文件。

  C8051F12X系列不用考慮硬件部分,也不存在地址線的擴(kuò)展問(wèn)題,因?yàn)?28 KB的4個(gè)bank區(qū)全部都在CPU內(nèi)部,所以作為常規(guī)跨bank的跳轉(zhuǎn)和調(diào)用,不需要處理1.5l_BANK.A51配置文件。但在特殊情況下就必須考慮該問(wèn)題,否則程序?qū)o(wú)法工作。下面以C8051F120為例先討論代碼的透明分組切換過(guò)程。

  C805IFl20在Keil C51的項(xiàng)目配置中被劃分為4個(gè)bank,每個(gè)32 KB。公共bank地址從0~0x7fff,其余bank從0x8000h~0xffff。在對(duì)應(yīng)的配置文件L51_BANK.A51中,涉及到特殊功能寄存器PSBANK(SFR地址:0B1H)、SWITCHn宏、B_BANKn、?B_SWITCHn分組信息保存和切換代碼,以及?B_CURENTBANK變量。

  PSBANK為C8051F120內(nèi)的特殊功能寄存器,128KB Flash的分bank訪問(wèn)就是通過(guò)它來(lái)實(shí)現(xiàn)的。要想轉(zhuǎn)移到新的bank中去,必須賦予PSBANK正確的值,然后再轉(zhuǎn)向bank區(qū)內(nèi)地址即可。

  SWITCHn宏共有4個(gè),分別是SwITCH0、SWlTCH1、SWITCH2和SWITCH3,對(duì)應(yīng)切換到4個(gè)bank中。其中SWITCH0對(duì)應(yīng)的語(yǔ)句為:

  MOV PSBANK.#00h ;把00h用1Ih、22h和33h替換,

  ;就是其他三個(gè)宏

  它將插入到?B_SWITCHn代碼中,用來(lái)切換新的bank和恢復(fù)到原來(lái)的bank。

  所有4組?B_BANKn和?B_SWlTCHn代碼也都是用宏實(shí)現(xiàn)的,對(duì)應(yīng)4個(gè)bank處理。它們匯集在?BANK?SWITCH代碼段中,整個(gè)bank切換及恢復(fù)機(jī)制非常巧妙,可以實(shí)現(xiàn)任意bank之間函數(shù)的相互調(diào)用及嵌套。下面以bank3區(qū)中的main函數(shù)調(diào)用bankl區(qū)的Delay_noOS()延時(shí)函數(shù)為例說(shuō)明該機(jī)制。

  void main(void){

  MCUInit(); //初始化CPU

  Delay_n00s(10); //延時(shí)lO ms

  Lcmlnition();

  :

 ?。?/p>

  bank3中被調(diào)用的函數(shù)Delay_noOS(10)對(duì)應(yīng)的匯編語(yǔ)句為:

  LCALL C:5049

  公共段(即Common段,對(duì)應(yīng)bank0)中C:5049處的

  匯編語(yǔ)句如下:

  MOV dptr,#Delay_noOS

  AJMP B_BANKl

  這里的B_BANKl就是宏?B_BANK&N中N為1的例程?,F(xiàn)在進(jìn)入問(wèn)題的核心:全部的跨bank區(qū)程序切換及恢復(fù)過(guò)程依靠公共段中?BANK?SWITCH代碼段里的以下匯編代碼實(shí)現(xiàn),對(duì)應(yīng)的N為0、1、2和3。?BANK?SWlTCH SEGMENT CODE PAGE

  ;

 ???B_BANK&N:

  PUSH ?B_CURRENTBANK (1)

  MOV A,#HIGH?BANK?SWITCH (2)

  PUSH ACC (3)

  PUSH DPL (4)

  PUSH DPH (5)

 ???B_SWITCH&N:

  MOV ?B_CURRENTBANK,#LOW? B_SWITCH&N

 ?。?)

  SWlTCH&N (7)

  RET (8)

 ?。?/p>

  Delay_noOS(10)函數(shù)的返回地址,即函數(shù)LcmIni-tion()的入口地址(也在bank3中),其高低位字節(jié)表示為ADDH和ADDL。程序進(jìn)入main()后的?B_CURRENTBANK變量初值是?B_SWITCH3的低8位,其意義稍后敘述。AJMP B_BANKl后程序執(zhí)行?B_BANKl和?B_SWITCHl的(1)~(8),執(zhí)行到(5)時(shí)的堆棧結(jié)構(gòu)如圖1所示。

  

  繼續(xù)執(zhí)行?B_SWITCHl到(7)時(shí),PSBANK變?yōu)橹赶騜ankl,?B_CURRENTBANK變?yōu)??B_SWITCHl的低8位。執(zhí)行(8)后,從堆棧結(jié)構(gòu)可以看出,堆棧彈出①作為新的PC值,程序進(jìn)入Delay_noOS(10)函數(shù),延時(shí)功能完成后,函數(shù)最后一條RET指令開(kāi)始返回。這是Keil C51處理bank機(jī)制的關(guān)鍵,此時(shí)的返回地址為堆棧中的②,此地址即?B_SWITCH&H代碼的入口,這里對(duì)應(yīng)main()函數(shù)所在的bank3分組,也就是?B_SWITCH3的人口。

  因?yàn)樗??B_SWITCH&N的高8位地址,即?BANK?SWITCH代碼段的高8位都一樣,由語(yǔ)句(2)中的操作符HIGH?BANK?SWITCH確定;低8位保存在已經(jīng)壓棧的?B_CURRENTBANK變量中,此時(shí)堆棧中的?B_CURRENTBANK壓棧值是?B_SWITCH3的低8位,這樣②的地址就是?B_SWITCH3。

  程序繼續(xù)執(zhí)行?B_SWITCH3,在執(zhí)行?B_SWITCH3的(6)語(yǔ)句之前,?B_CURRENTBANK還是前面執(zhí)行?B_SWITCHl時(shí)的值,即?B_SWITCHl的低8位。執(zhí)行語(yǔ)句(6)后,?B_CURRENTBANK恢復(fù)為?B_SWITCH3的低8位,為返回main函數(shù)做準(zhǔn)備。然后PSBANK置為33h,即指向bank3,接著執(zhí)行RET語(yǔ)句,堆棧③成為RET的返回地址,程序回到了main()中Delay_noOS(10)的下一條語(yǔ)句繼續(xù)執(zhí)行,?B_CURRENTBANK也已恢復(fù)。

  這個(gè)調(diào)用過(guò)程中,用了6個(gè)堆棧字節(jié),3條RET指令,關(guān)鍵內(nèi)容就是?B_CURRENTBANK變量,它保存了可以恢復(fù)調(diào)用前bank環(huán)境代碼的地址低位。從被調(diào)用函數(shù)返回 到這個(gè)地址后,就能恢復(fù)調(diào)用前的bank環(huán)境,即賦予PSBANK正確的值。

  不采用直接保存PSBANK值然后再恢復(fù),而是用壓棧的方式保存了相關(guān)地址(語(yǔ)句(1)~(3)),是為了實(shí)現(xiàn)跨bank區(qū)的嵌套調(diào)用。例如,在Delay_noOS(10)函數(shù)中,如果再次跨bank去調(diào)用新函數(shù),會(huì)再次重復(fù)上述過(guò)程,堆棧從②往上再長(zhǎng)6個(gè)字節(jié)。Delay_noOS(10)函數(shù)之前執(zhí)行?B_SWITCHI產(chǎn)生的?B_CURRENTBANK值(?B_SWITCHI的低8位)也會(huì)進(jìn)棧,為調(diào)用完新函數(shù)后返回到bankl繼續(xù)執(zhí)行Delay_noOS(10)提供保證。

  2 無(wú)操作系統(tǒng)bank分區(qū)間的強(qiáng)制跳轉(zhuǎn)

  通過(guò)上面的分析得知,如果要處理跨bank區(qū)的跳轉(zhuǎn)、調(diào)用和返回,關(guān)鍵是能正確處理好PSBANK中的內(nèi)容。當(dāng)程序沒(méi)有操作系統(tǒng)用于任務(wù)切換,而又需要強(qiáng)制退出某一函數(shù)進(jìn)入到另一函數(shù)的某一地址時(shí),比如說(shuō)在中斷發(fā)生后,結(jié)束原來(lái)的工作轉(zhuǎn)入到另一工作去,就需要處理好PSBANK。

  如果不考慮bank,可以在轉(zhuǎn)入新地址之前執(zhí)行一段代碼,保存該地址處的環(huán)境變量[2],包括堆棧指針sP和需要的入口地址。然后在中斷返回之前,恢復(fù)此環(huán)境變量,執(zhí)行中斷返回指令進(jìn)入該新地址。這個(gè)思路和C51庫(kù)函數(shù)setjump和longjump比較相近,但比它們靈活,因?yàn)榄h(huán)境變量可以自己處理。

  考慮bank后的情況稍微復(fù)雜些,環(huán)境變量中需增加bank的處理信息,那么只處理PSBANK行不行呢?

  如果僅保存和恢復(fù)PSBANK,則很簡(jiǎn)單,在保存環(huán)境變量的程序中加入:

  JMPEnv[envl][3]=PSBANK;

  在恢復(fù)環(huán)境變量的程序中加入:

  PSBANK=JMPEnv[envl][3];

  這里環(huán)境變量是二維數(shù)組JMPEnv,envl代表一個(gè)環(huán)境變量,即一個(gè)返回點(diǎn)。第二維是變量中的參數(shù)個(gè)數(shù)。因此可以保存多個(gè)環(huán)境變量以供使用。

  初看起來(lái)這樣處理是沒(méi)有問(wèn)題的,可實(shí)際上不行。因?yàn)檫M(jìn)入返回點(diǎn)后,雖然PSBANK正確了,但是?B_CUR-RENTBANK可能已經(jīng)被修改,不能和返回點(diǎn)程序的bank區(qū)匹配,如果再次出現(xiàn)跨bank調(diào)用的話將不能正確返回。

  處理方法是有點(diǎn)技巧的,因?yàn)镃語(yǔ)言不支持匯編變量?B_CURRENTBANK的寫法,所以在L51_bank.A51中要加上聲明:

  PUBLIC BLCURRENTBANK

  和偽指令:

  B_CURRENTBANK EQU ?B_CURRENTBANK

  這樣就可以在C程序中使用B_CURRENTBANK

  了,先聲明B_CURRENTBANK:

  extern Uchar data B_CURRENTBANK;

  然后在保存環(huán)境變量程序中加入:

  JMPEnv[envl][3]=PSBANK;

  JMPEnv[envl][4]=B_CURRENTBANK;

  恢復(fù)環(huán)境變量程序中加入:

  PSBANK=JMPEnv[envl][3];

  B_CURRENTBANK=JMPEnv[envl][4];

  這樣恢復(fù)環(huán)境變量進(jìn)入到新程序后,也將恢復(fù)該程序?qū)?yīng)的正確?B_cuRRENTBANK值,問(wèn)題得到解決。

 

  3 no/0S-ll移植中的bank分區(qū)處理

 

  μC/OS-II的51版本已經(jīng)很成熟,但是所有移植版本均未處理bank問(wèn)題,需要增加該內(nèi)容,否則不能在包括C8051F12X系列及其他多bank程序中使用。

  如前所述,Keil C51提供對(duì)跨bank調(diào)用的透明切換支持,但在使用操作系統(tǒng)時(shí),這種透明切換機(jī)制還需要提供對(duì)任務(wù)切換的支持。因?yàn)槿蝿?wù)的切換,程序可能需要到別的代碼分組中去運(yùn)行,而此時(shí)PSBANK和?B_CUR-RENTBANK還停留在原來(lái)代碼分組中的狀態(tài),將導(dǎo)致程序崩潰。顯然,無(wú)論由于什么情況導(dǎo)致的任務(wù)切換完成之前,都需要保存和恢復(fù)PSBANK和?B_CURRENT-BANK的值。解決的辦法是在每次任務(wù)切換前將PS-BANK和?B_CURRENTBANK壓入用戶任務(wù)棧。

  按照μC/OS-II的要求,在任務(wù)創(chuàng)建時(shí),任務(wù)棧必須初始化成像運(yùn)行中的任務(wù)剛剛發(fā)生過(guò)中斷一樣嘲。?B_CURRENTBANK的初始值取決于該任務(wù)所在分組對(duì)應(yīng)的切換代碼段的低8位地址。所以,任務(wù)堆棧的初始化函數(shù)OSTaskStkInit需要加入一個(gè)參數(shù)INT8U bank,指明該任務(wù)位于哪個(gè)代碼分組中。又由于任務(wù)堆棧的初始化函數(shù)是被任務(wù)創(chuàng)建函數(shù)OSTaskCreate調(diào)用的,所以該函數(shù)一樣需要加入?yún)?shù)INT8U bank。

  在壓棧,出棧宏中需要加入:

  PUSH PSBANK

  PUSH?B_CURRENTBANK

 ?。?/p>

  POP ?B_CURRENTBANK

  POP PSBANK

  在任務(wù)堆棧的初始化函數(shù)OSTaskStkInit中需要加入:

  *stk++=17; //堆棧長(zhǎng)度增加2個(gè)到17

  ;

  if(bank==0x22:){ //bank2

  *stk++=bank;

  *stk++=CurrentBank2();

  else if(bank==0x33){ //bank3

  *stk++=bank;

  *stk++=CurrentBank3();

  }

  else{ //bankl和common

  *stk++=0xll; //PSBANK

  *stk++=CurrentBankl();

 ?。?/p>

  其中,bank0用任何的PSBANK值均沒(méi)有問(wèn)題,所以簡(jiǎn)化了PSBANK取值0x00的情況。

  函數(shù)INT8U CurrentBankl(void),INT8U Current-Bank2(void)和INT8U CurrentBank3(void)是用匯編語(yǔ)言實(shí)現(xiàn)的,返回值通過(guò)R7傳遞,目的是獲得該任務(wù)所在分組對(duì)應(yīng)切換代碼段(?SWITCHn)的低8位地址。不用C語(yǔ)言編寫的原因同樣是?B_SWITCH&N不被C支持。

  CurrentBankl(void)代碼如下,其他兩個(gè)類同。

  RSEG?PR?CurrentBankl?Os_CPU_A

  CurrentBankl:

  MOV DPTR,#?B_SWITCHl

  MOV R7.DPL

  RET

  結(jié) 語(yǔ)

  本文介紹了Keil C51實(shí)現(xiàn)大于64 KB程序的bank分組代碼切換機(jī)制的原理,提出了沒(méi)有操作系統(tǒng)情況下非正常轉(zhuǎn)移時(shí)bank的處理方法以及μc/os—II操作系統(tǒng)在多bank分區(qū)程序移植中應(yīng)采取的措施,在開(kāi)發(fā)實(shí)例中均得到了很好的應(yīng)用。

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

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

關(guān)鍵字: 阿維塔 塞力斯 華為

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

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

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

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

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

關(guān)鍵字: 騰訊 編碼器 CPU

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

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

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

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

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

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

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

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

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

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉