新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > MSP430FR5969內(nèi)存分配的問題

MSP430FR5969內(nèi)存分配的問題

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

cmd文件里的具體內(nèi)容我就不貼了,大家自己可以看一下。cmd文件主要由兩部分構(gòu)成,一個是MEMORY{};另一個是SECTIONS{}

本文引用地址:http://m.butianyuan.cn/article/201611/319189.htm其中MEMORY{}是定義內(nèi)部所有寄存器及存儲器的地址,在這里大部分內(nèi)容都是廠家定義好的,一般不能修改。但是咱們今天要改的就是他,當(dāng)然只能改其中允許該的地方,那就是FRAM的分配問題。根據(jù)數(shù)據(jù)手冊里提供的內(nèi)存分配情況(如下圖)我們可以得知,59x9的內(nèi)存從0x0000開始,一直到0x13FFF。對應(yīng)著這個圖和Cmd文件,我們可以了解內(nèi)部的地址分配問題,如果做過總線擴展之類的同學(xué)肯定對這個不會陌生了,如果沒有見過就需要理解一下。其實也很簡單,就是對應(yīng)的地址要對應(yīng)上就可以了。有一些是固定好的不能變,比如各個中斷向量的地址,各個寄存器的地址等。一般能變的就是程序存儲空間和數(shù)據(jù)空間了,對應(yīng)到59x9里面就是cmd文件里的三個部分,即
RAM :origin = 0x1C00, length = 0x0800
FRAM : origin = 0x4400, length = 0xBB80
FRAM2 : origin = 0x10000,length = 0x4000
其中origin 表示起始地址,length 表示長度

這幾個關(guān)鍵的起始地址和長度可以在上表以及msp430FR59xx69xx數(shù)據(jù)手冊.pdf的21頁22頁找到,這兩頁是中斷向量地址,也就是cmd文件下面的部分了。上面說到地址的和21頁和22頁上的地址是內(nèi)部規(guī)定好的,用戶不能自行改變??吹竭@里,我想大家應(yīng)該明白了,其實這個芯片留給用戶的地址有3部分。分別是0x1C00開始的2K空間,0x4400開始的46K空間以及0x100000開始的16K空間。那么這些空間都是放什么內(nèi)容的呢?這就要說到CMD文件中的另一部分SECTIONS{}了。
顧名思義,SECTIONS就是選擇的意思,當(dāng)然就是選擇程序編譯過程中的每一部分數(shù)據(jù)的位置了。這一部分每一行的具體意義我也說不太明白。只是略知一二,與此帖有關(guān)的的有這樣幾句
  1. .cinit : {}> FRAM /* INITIALIZATION TABLES */
  2. .pinit : {}> FRAM /* C++ CONSTRUCTOR TABLES */
  3. .init_array : {}> FRAM /* C++ CONSTRUCTOR TABLES */
  4. .mspabi.exidx : {}> FRAM /* C++ CONSTRUCTOR TABLES */
  5. .mspabi.extab : {}> FRAM /* C++ CONSTRUCTOR TABLES */
  6. .const : {} >> FRAM | FRAM2/* CONSTANT DATA */
  7. .text:_isr : {}> FRAM /* CODE ISRs */
  8. .text : {} >> FRAM2 | FRAM/* CODE
復(fù)制代碼
還有
  1. .bss : {} > RAM /* GLOBAL & STATIC VARS */
  2. .data : {} > RAM /* GLOBAL & STATIC VARS */
  3. .TI.noinit: {} > RAM /* For #pragma NOINIT */
  4. .stack : {} > RAM (HIGH) /* SOFTWARE SYSTEM STACK */
復(fù)制代碼
相信大家已經(jīng)看出來了,這一部分就是與我們實用的代碼和數(shù)據(jù)相關(guān)的部分。比如.text:_isr : {} > FRAM /* CODE ISRs */這一句是中斷代碼的位置,在FRAM區(qū)域,也就是0x4400開始的46K空間內(nèi),具體分配到什么位置就看編譯器了,反正不會出這個范圍。.text : {} >> FRAM2 | FRAM /* CODE這一個是其他代碼的位置,F(xiàn)RAM|FRAM2,即這兩塊FRAM區(qū)域均可。下面的.bbs、.stack、.data等均在RAM區(qū),也就是0x1C00開始的2K空間內(nèi)。 在實際的使用中,最常見的可能就是數(shù)據(jù)超出范圍,一般都是定義的變量較多或者緩沖區(qū)較大,比如在串口通訊的應(yīng)用中,2K不夠用,那么我們就可以把.data : {} > RAM修改為.data : {} > RAM|FRAM2,在以前數(shù)據(jù)和程序分開定義的芯片中,這個時候在上面.text和.const中就不能再出現(xiàn)FRAM2了。至于這個片子應(yīng)該是可以的,我還沒有試,留個疑問吧。大家可以自己試一下。

除了上面那樣利用官方分好的區(qū)塊重新定義之外,我們還可以自己重新劃分地址。比如把46K的區(qū)塊劃分成兩個或者多個區(qū)塊,當(dāng)然一般為了實用方便區(qū)塊還是少一些比較好,把同一類型數(shù)據(jù)中的子類數(shù)據(jù)的地址分配權(quán)利給編譯器會更簡單一些,如果對數(shù)據(jù)的存放比較關(guān)心,比如我想單獨拿出一塊放參數(shù),那么我們就可以單獨定義一塊地址作為參數(shù),方便數(shù)據(jù)的管理。

從上圖中,我們可以看到,字符串常量存儲的位置上FLASH1區(qū)或者FLASH2區(qū),可執(zhí)行代碼也是存儲在FLASH1去或者FLASH2區(qū)。這里出現(xiàn)這個問題的原因可能是可執(zhí)行代碼存儲在FLASH區(qū),但是需要的字符串常量存在是FLASH2區(qū),所以重定向時,由于存儲的位置較遠,導(dǎo)致無法定向到。
因此,我們考慮修改cmd文件,使得字符串常量全部存儲在FLASH區(qū)。在經(jīng)過了這樣的修改之后,再編譯時,不再報錯,程序正常運行。
通過工程目錄下的.map文件,我們也可以獲取內(nèi)存分配的信息,可以借此來驗證我們修改的正確性。
注:這樣做可能還存在一個問題,因為FLASH1區(qū)的大小非常小,只有31K,按照目前這種做法,中斷函數(shù)代碼、變量初始化的值以及字符串常量都被存儲在FLASH1區(qū),部分執(zhí)行代碼也存在這個區(qū)域。如果前面三者的大小超過了FLASH1區(qū)的大小,這種情況不知道編譯器是否會有提示。如果沒有提示,但是溢出的話,可能是會出問題的。但是從目前調(diào)試的情況來看,一切正常。如果后續(xù)出現(xiàn)奇怪的現(xiàn)象,需要考慮是否是這里的問題。


關(guān)鍵詞: MSP430FR5969內(nèi)存分

評論


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

關(guān)閉