<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Freescale 16位單片機(jī)的地址映射

          Freescale 16位單片機(jī)的地址映射

          作者: 時(shí)間:2016-11-28 來源:網(wǎng)絡(luò) 收藏

          INTO ROM_C000 ;

          OTHER_ROM INTO PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8;

          //.stackstart,
          SSTACK,
          //.stackend,
          PAGED_RAM,

          DEFAULT_RAM
          INTO RAM;

          DISTRIBUTE DISTRIBUTE_INTO
          ROM_4000, PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8;
          CONST_DISTRIBUTE DISTRIBUTE_INTO
          ROM_4000, PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8;
          DATA_DISTRIBUTE DISTRIBUTE_INTO
          RAM;
          //.vectors INTO OSVECTORS;
          END

          ENTRIES

          //_vectab OsBuildNumber _OsOrtiStackStart _OsOrtiStart
          END

          STACKSIZE 0x100


          VECTOR 0 _Startup
          //VECTOR 0 Entry
          //INIT Entry

          1 .prm 文件組成結(jié)構(gòu)
          按所含的信息的不同.prm文件有六個(gè)組成部分構(gòu)成,這里僅討論和內(nèi)存空間映射關(guān)系緊密的三個(gè)部分,其他的不做討論。
          · SEGMENTS … END
          定義和劃分芯片所有可用的內(nèi)存資源,包括程序空間和數(shù)據(jù)空間。一般我們將程序空間定義成ROM,把數(shù)據(jù)空間定義成RAM,但這些名字都不是系統(tǒng)保留的關(guān)鍵詞,可以由用戶隨意修改。用戶也可以把內(nèi)存空間按地址和屬性隨意分割成大小不同的塊,每塊可以自由命名。例如同樣是RAM,可以使用不同的屬性,使其有復(fù)位后變量清零和不清零之分。
          關(guān)于內(nèi)存劃分的具體方法在后面詳解。
          · PLACEMENT … END
          將指派源程序中所定義的各種段,如數(shù)據(jù)段DATA_SEG、CONST_SEG和代碼段CODE_SEG 被具體放置到哪一個(gè)內(nèi)存塊中。它是將源程序中的定義描述和實(shí)際物理內(nèi)存掛鉤的橋梁。
          · STACKSIZE
          定義系統(tǒng)堆棧長(zhǎng)度,其后給出的長(zhǎng)度字節(jié)數(shù)可以根據(jù)實(shí)際應(yīng)用需要進(jìn)行修改。堆棧的實(shí)際定位取決于RAM內(nèi)存的劃分和使用情況。默認(rèn)的情況下,堆棧放在RAM區(qū)域的起始部分。當(dāng)然,堆棧的定義不只有這種方式,還可以使用STACKTOP關(guān)鍵字。后面將詳細(xì)討論。

          2 內(nèi)存劃分的具體方式
          由SEGMENTS開始到END為止,中間可以添加任意多行內(nèi)存劃分的定義,每一行用分號(hào)結(jié)尾。定義行的語法型式為:
          [塊名] = [屬性1] [屬性2] ,… ,[屬性n] [起始地址] TO [結(jié)束地址];
          其中,

          · “塊名”的定義和C語言變量定義相同,是以英文字母開頭的一個(gè)字符串,用戶可以自己任意定義塊名。

          · “屬性”用戶是不能自己定義的,因?yàn)閷傩悦付松厦嫠f的“塊名”所對(duì)應(yīng)的不同的內(nèi)存類型和訪問方式,而不同物理內(nèi)存的類型和訪問方式是一定的。
          對(duì)于“屬性1”,Codewarrior 5.0中可以有三種不同的類型,對(duì)于只讀的Flash-ROM區(qū)屬性一定是READ_ONLY,對(duì)于可讀寫的RAM區(qū)屬性可以是READ_WRITE,也可以是NO_INIT。它們兩者的關(guān)鍵區(qū)別是ANSI-C的初始化代碼會(huì)把定位在READ_WRITE塊中的所有全局和靜態(tài)變量自動(dòng)清零,而NO_INIT塊中的變量將不會(huì)被自動(dòng)清零。當(dāng)然只是復(fù)位時(shí)不清零,掉電時(shí)還是清零的,但是對(duì)于單片機(jī)系統(tǒng),變量在復(fù)位時(shí)不被自動(dòng)清零這一特性有時(shí)是很關(guān)鍵的,在某些應(yīng)用中有特殊的用途。
          對(duì)于“屬性2 … 屬性n”,根據(jù)上面給出的.prm的范例文件可以看出來,可能的形式有“DATA_FAR”、“DATA_NEAR”、“IBCC_FAR”、“IBCC_NEAR”四種類型。其中,“DATA_FAR”和“DATA_NEAR”相對(duì)應(yīng),當(dāng)內(nèi)存區(qū)域包含變量或者是常量時(shí)(通常是RAM、Flash和EEPROM),必須指明上面兩種屬性中的一種,由于涉及到內(nèi)存的分頁,可以這樣理解:“DATA_FAR”屬性指定的內(nèi)存塊為可以保存數(shù)據(jù)的非固定頁,而“DATA_NEAR”屬性指定的內(nèi)存塊為可以保存數(shù)據(jù)的固定頁;同理“IBCC_FAR”和“IBCC_NEAR”相對(duì)應(yīng),當(dāng)內(nèi)存區(qū)域包含代碼時(shí)(Flash和EEPROM),必須指明上面兩種屬性中的一種,“IBCC_FAR”屬性指定的內(nèi)存塊為可以保存代碼的非固定頁,而“IBCC_NEAR”屬性指定的內(nèi)存塊為可以保存代碼的固定頁

          討論到這里,細(xì)心的讀者已經(jīng)發(fā)現(xiàn),在上面的.prm文件范例中,RAM的屬性有“DATA_FAR”和“DATA_NEAR”兩種,F(xiàn)lash的屬性中也是四種都有,但是EEPROM中卻只有“DATA_FAR”和“IBCC_FAR”兩種,這正好驗(yàn)證了上一篇文章(飛思卡爾16位單片機(jī)的資源配置)中所提到的,RAM、Flash中都有固定頁,但是EEPROM中全部是非固定頁。

          · 起始地址和結(jié)束地址決定了一內(nèi)存塊的物理位置,對(duì)于固定頁,用4位16進(jìn)制數(shù)表示,而對(duì)于非固定頁,則用6位16進(jìn)制表示,多出來的兩位其實(shí)是寄存器EPAGE、RPAGE或PPAGE的值,可見,對(duì)于分頁的資源,是通過寄存器(EPAGE、RPAGE或PPAGE)和16位的地址總線的組合來進(jìn)行尋址的。
          “TO”是系統(tǒng)保留的關(guān)鍵字,必須大寫。

          下面,根據(jù)上面范例提供的內(nèi)容,舉幾個(gè)例子:
          例1 RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x3FFF;
          上面這句話的意思是:分配0x2000-0x3FFF的區(qū)域的塊名為“RAM”(當(dāng)然可以定義別的名稱),由上一篇文章而知,這一區(qū)域的物理內(nèi)存的性質(zhì)為RAM,屬性應(yīng)該為“READ_WRITE”,并且這一區(qū)域中的兩頁都為固定頁,所以為“DATA_NEAR”。

          例2 將8K字節(jié)RAM的后面4K字節(jié)定義成非自動(dòng)清零的數(shù)據(jù)保留區(qū),則應(yīng)如下定義:
          SEGMENTS
          ……
          RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x2FFF;
          RAM_NO_INIT = NO_INIT DATA_NEAR 0x3000 TO 0x3FFF;
          ……
          END
          注意,各部分RAM的分配地址不應(yīng)該存在重疊的部分,否則會(huì)發(fā)生錯(cuò)誤。

          例3 EEPROM_00 = READ_ONLY DATA_FAR IBCC_FAR 0x000800 TO 0x000BFF;
          XS128單片機(jī)中的EEPROM由Data-Flash模擬,所以屬性為READ_ONLY。EEPROM全部為非固定頁,所以用“DATA_FAR”、“IBCC_FAR”。后面的起始地址和結(jié)束地址分別為6位的16進(jìn)制數(shù),前兩位的“00”實(shí)質(zhì)指的是EEPROM分頁寄存器EPAGE的值為0x00。

          用SEGMENTS只是從單片機(jī)的物理內(nèi)存這一角度對(duì)其進(jìn)行空間劃分。源程序本身并不知道物理內(nèi)存被分割和屬性定義的這些細(xì)節(jié)。它們兩者之間必須通過下面的PLACEMENT建立聯(lián)系。

          3 程序段和數(shù)據(jù)段的放置
          PLACEMENT-END內(nèi)所描述的信息是告訴連接器源程序中所定義的各類段應(yīng)該被具體放置到哪一個(gè)內(nèi)存塊中去。其語法型式為:
          [段名1], [段名2],... , [段名n] INTO [內(nèi)存塊名1],[內(nèi)存塊名2],… ,[內(nèi)存塊名n];

          [段名1], [段名2],... , [段名n] DISTRIBUTE_INTO [內(nèi)存塊名1],[內(nèi)存塊名2],… ,[內(nèi)存塊名n];

          其中

          · 段名就是在源程序中用“#pragma”聲明的數(shù)據(jù)段、常數(shù)段或代碼段的名字。如果用缺省名“DEFAULT”,則默認(rèn)的數(shù)據(jù)段名為DEFAULT_RAM,代碼段和常數(shù)段名為DEFAULT_ROM。若程序中定義的段名沒有在PLACEMENT中提及,則將被視同為DEFAULT。幾個(gè)相同性質(zhì)但不同名字的段可以被放置到同一個(gè)內(nèi)存塊中,相互之間用逗號(hào)分隔。

          · INTO 是系統(tǒng)保留的關(guān)鍵詞,在這里為“放入”的意思。

          · DISTRIBUTE_INTO 也是系統(tǒng)的保留關(guān)鍵字。Codewarrior 具有內(nèi)存自動(dòng)優(yōu)化的功能,但是在“Small memory”模式中,這種功能不會(huì)被啟用,只有當(dāng)16-bit的地址空間不能存放下所有的變量和代碼時(shí),才會(huì)啟用這種功能。

          在SEGMENTS-END區(qū)域中,當(dāng)在內(nèi)存模塊的屬性中加上“DATA_FAR”、“DATA_NEAR”、“IBCC_FAR”、“IBCC_NEAR”四種屬性中的任何一種時(shí),那么在PLACEMENT-END區(qū)域中,就需要指定段名“DISTRIBUTE”, “CONST_DISTRIBUTE”, “DATA_DISTRIBUTE”(系統(tǒng)默認(rèn)的,非關(guān)鍵字,用戶可以自行更改)所分配的內(nèi)存空間,這就需要使用“DISTRIBUTE_INTO”關(guān)鍵字。

          關(guān)于內(nèi)存自動(dòng)優(yōu)化功能,可以參考freescale的官方技術(shù)手冊(cè)“TN 262.pdf”。

          · 內(nèi)存塊名就是前面介紹的用SEGMENTS劃分好的不同的內(nèi)存塊名字。
          利用這樣直觀的定位描述文本可以方便靈活的將數(shù)據(jù)或代碼定位到芯片內(nèi)存任意可能的位置,實(shí)現(xiàn)某些特殊目的的應(yīng)用。

          下面的例子,說明了各種段名、PLACEMENT 和SEGMENTS之間的對(duì)應(yīng)關(guān)系。
          例4 定義非自動(dòng)清零的數(shù)據(jù)段

          SEGMENTS
          ……
          RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x2FFF;
          RAM_NO_INIT = NO_INIT DATA_NEAR 0x3000 TO 0x3FFF;
          ……
          END

          PLACEMENT
          ……
          DATA_PERSISTENT INTO RAM_NO_INIT;
          ……
          END

          //源程序編寫:
          #pragma DATA_SEG DATA_PERSISTENT //定義復(fù)位時(shí)非自定清零數(shù)據(jù)段
          byte sysState;
          #pragma DATA_SEG DEFAULT

          4 堆棧的設(shè)置
          關(guān)于堆棧的設(shè)置,Codewarrior提供了兩種方式:“STACKSIZE”命令方式和“STACKTOP”命令方式。這兩種方式在同一個(gè).prm文件中,不能同時(shí)存在。當(dāng)用戶只關(guān)心堆棧的大小而不關(guān)心堆棧的存放位置時(shí),推薦使用STACKSIZE方式。
          系統(tǒng)默認(rèn)的方式為使用STACKSIZE方式。

          STACKSIZE命令方式:
          當(dāng)使用STACKSIZE命令方式時(shí),如果在PLACEMENT-END部分聲明了“SSTACK INTO RAM”,這樣的話,堆棧區(qū)就被放在RAM區(qū)域的起始部分,下面的例子說明了這種方式:

          例5
          SEGMENTS
          ……
          RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x3FFF;
          ……
          END

          PLACEMENT
          ……
          SSTACK, PAGED_RAM, DEFAULT_RAM INTO RAM;
          ……
          END
          STACKSIZE 0x100

          上面的例子將堆棧區(qū)域存放的地址為0x20FF-0x2000,初始的堆棧指針指向棧頂?shù)刂?x20FF。
          相反,如果在PLACEMENT-END部分沒有聲明“SSTACK INTO RAM”,則堆棧被分配在RAM區(qū)域中已分配空間的后面。請(qǐng)參見例6。

          例6
          SEGMENTS
          ……
          RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x3FFF;
          ……
          END

          PLACEMENT
          ……
          PAGED_RAM, DEFAULT_RAM INTO RAM;
          ……
          END
          STACKSIZE 0x100

          在這個(gè)例子中,如果RAM區(qū)域中已經(jīng)分配的變量占用了4個(gè)字節(jié)(從0x2000到0x2003),則堆棧放在這四個(gè)字節(jié)的后面,從0x2103到0x2004,初始的堆棧指針指向0x2103。

          STACKYOP命令方式:
          當(dāng)使用STACKTOP命令方式時(shí),如果在PLACEMENT-END部分聲明了“SSTACK INTO RAM”,同樣,堆棧區(qū)就被放在RAM區(qū)域的起始部分,初始的棧頂則由STACKTOP指定。若沒有相應(yīng)的聲明,則初始的棧頂由STACKTOP指定,而堆棧的大小則根據(jù)處理器的不同由編譯器自行設(shè)定,其大小足夠裝下處理器的PC寄存器的值。

          上一頁 1 2 下一頁

          關(guān)鍵詞: Freescale16位單片機(jī)地址映

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();