我們已經(jīng)學(xué)習(xí)了分頁(yè)窗口和分頁(yè)寄存器的概念,對(duì)于64kB全局地址,我們可以把它理解為一個(gè)64kB的分頁(yè)窗口,其中的內(nèi)容取決于第四個(gè)分頁(yè)寄存器—GPAGE。
全局地址是個(gè)覆蓋了8Mb地址空間的23位地址,從地址0x000000到0x7FFFFF。在這個(gè)線性全局地址空間中,所有的內(nèi)存資源都被分組,GPAGE寄存器可以被用于訪問(wèn)所有的RAM、EEPROM和FLASH地址,以及外部地址空間。
在向GPAGE中寫(xiě)入正確的值后,全局地址的內(nèi)容就只能通過(guò)全局指令來(lái)訪問(wèn)了。
GPAGE的值的選取方式與其他分頁(yè)寄存器的方式很相似:
寫(xiě)0xFF到GPAGE中會(huì)使全局地址映射總地址的最后64kB。
寫(xiě)0xFE會(huì)映射物理地址的的倒數(shù)第二個(gè)64kB。
什么時(shí)候使用全局尋址使用全局尋址主要是由于兩個(gè)原因:
當(dāng)需要鏈接非常大的對(duì)象,大到由于本地地址中沒(méi)有足夠的連續(xù)地址空間而無(wú)法被鏈接時(shí)。這種情況下,使用全局尋址使得程序員能夠通過(guò)全局指令來(lái)訪問(wèn)高達(dá)64kB的連續(xù)地址空間??杀绘溄拥膯蝹€(gè)數(shù)據(jù)對(duì)象的最大大小是64kB。
當(dāng)在運(yùn)行被分頁(yè)存儲(chǔ)的代碼的同時(shí),試圖訪問(wèn)同一種內(nèi)存資源中的被分頁(yè)存儲(chǔ)的對(duì)象(變量或常量)。
.
比如,當(dāng)應(yīng)用需要訪問(wèn)分配在某個(gè)給定Flash分頁(yè)中的常量,但當(dāng)前執(zhí)行的代碼卻跑在一個(gè)不同的Flash分頁(yè)中。通常,當(dāng)在S12架構(gòu)中遇到這種情況時(shí),會(huì)使用一個(gè)non-banked運(yùn)行時(shí)例程來(lái)訪問(wèn)分頁(yè)的對(duì)象。
在S12X中,當(dāng)在分頁(yè)Flash中運(yùn)行時(shí),可以使用這個(gè)新的全局訪問(wèn)方式來(lái)訪問(wèn)Flash中的任何地址,不需要碰PPAGE寄存器,也不需要跳到一個(gè)non-banked例程。
為了指示編譯器使用全局訪問(wèn)來(lái)訪問(wèn)某個(gè)對(duì)象,可以把它聲明在一個(gè) #pragma DATA_SEG __GPAGE_SEG 塊或#pragma CONST_SEG __GPAGE_SEG 塊中,這取決于對(duì)象的特性。
S12X本地地址再映射能力在新的S12X設(shè)備上,MMC模塊可以由用戶(hù)來(lái)配置0x4000到0x7FFF之間的CPU本地地址。這部分的本地地址默認(rèn)是用來(lái)映射Flash的,但是它可以被配置來(lái)映射RAM或者外部空間,因此給用戶(hù)提供了更大的靈活性,更靈活的配置哪些地址是non-banked的。請(qǐng)參考S12X編譯器手冊(cè)的編譯器選項(xiàng) -Map以及你的設(shè)備的datasheet,MMC模塊,來(lái)獲取更多關(guān)于這一特性的信息。
現(xiàn)在你已經(jīng)見(jiàn)識(shí)到了訪問(wèn)內(nèi)存地址的兩種不同的方式。下一章會(huì)描述,怎么指示CodeWarrior鏈接器來(lái)放置我們的代碼和變量到需要的內(nèi)存地址中。我們還將看到,當(dāng)使用C語(yǔ)言來(lái)開(kāi)發(fā)時(shí),怎么確保CodeWarrior的編譯器知道某個(gè)對(duì)象應(yīng)該放在banked還是non-banked內(nèi)存地址中,以產(chǎn)生合適的代碼。
控制對(duì)象在內(nèi)存中的分配這個(gè)部分描述了CodeWarrior連接器默認(rèn)是怎么在內(nèi)存中放置對(duì)象的,以及怎么改變這個(gè)默認(rèn)行為以定制我們的應(yīng)用。
名詞 對(duì)象(objects) 指的是在內(nèi)存中有固定地址的實(shí)體。可以是:
函數(shù)(代碼)
變量(放置在RAM中的數(shù)據(jù)和數(shù)組)
常量(放置在Flash中并被標(biāo)識(shí)為”const”的數(shù)據(jù))
字符串(沒(méi)有被預(yù)定義為數(shù)組的字符串字面值)
比如:printf( “Hello World”)將會(huì)產(chǎn)生字符串”Hello World”。相反地,聲明一個(gè)變量為
unsigned char Message[] = “Hello World”;
的話,鏈接器會(huì)認(rèn)為它是一個(gè)數(shù)組而不是一個(gè)字符串。
.
對(duì)象的位置由#pragma聲明來(lái)控制。后面的內(nèi)容并不是對(duì)#pragma聲明的完全描述,只列出了那些常用的而已。如果想要詳細(xì)描述的話,請(qǐng)參考放在你的CodeWarrior安裝路徑下編譯器和搭建工具的手冊(cè)。
我們將看到四種#pragma聲明:
#pragma CODE_SEG
#pragma DATA_SEG
#pragma CONST_SEG
#pragma STRING_SEG
.
這四種聲明都可以插入到C源文件中,并用于控制聲明后面的對(duì)象的位置和特性。
怎么使用pragma聲明來(lái)控制對(duì)象的位置讓我們先看一個(gè)例子。這里,一個(gè)變量、一個(gè)常量和一個(gè)函數(shù)被放在一個(gè)明確的placement section中。placement section是指向內(nèi)存中特定區(qū)域的標(biāo)簽,被定義在項(xiàng)目的鏈接器參數(shù)文件(*.prm文件)的PLACEMENT塊中。下一章中給出了鏈接器參數(shù)文件的結(jié)構(gòu),用于參考。
unsigned char variable1; const unsigned char constant1; void function1(void) { /* 代碼 */ }. #pragma聲明并不是強(qiáng)制的。在上例中就沒(méi)有#pragma聲明。這種情況下,鏈接器使用默認(rèn)行為并將放置對(duì)象到他們的默認(rèn)位置。
DEFAULT_ROM 是代碼的默認(rèn)位置
DEFAULT_RAM 是變量和數(shù)組的默認(rèn)位置
ROM_VAR
是常量(ROM變量)的默認(rèn)位置
.
電子發(fā)燒友App


















評(píng)論