用CCS開發環境以及有一年多了,之前寫程序,僅僅是停留在寫程序的階段,從來沒有想過內存是如何分配的。這次做這個,由于程序的代碼量比較大,有40K+,所以在程序整合編譯的過程中,遇到了一些之前沒有遇到過的問題,在查閱了一些資料之后,解決了這些問題,在這里做一下總結。
首先,我們先拋出遇到的問題。在將程序整合之后,編譯報錯了,報的錯誤如下圖所示。這個問題是說重定向時,重定向的地址為17位,太大了,超過了16位譯碼的范圍。

這里這個問題我是這樣理解的,是這些函數中需要調用一些字符串常量(根據錯誤定位得出的結論),這時候需要跳轉到這個常量所在的地址,但是由于這個地址離當前函數所在的地址“太遠了”,所以沒有辦法跳轉到那里執行。
有了這樣的分析,我們很自然地想到,如果這些字符串常量能夠離程序所在的區域“近一些”,那么這個問題就能解決了。如何來控制字符串常量所在的存儲區域呢?這里我們需要了解一下cmd文件。
以MSP430F6638的cmd文件為例,它主要包含了兩個信息。
一個是關于MSP430F6638的內存映射信息,如下圖所示。利用紅色的區域中的信息,我們也可以計算出,6638的RAM是從0x2400開始,大小為16K,USBRAM是從0x1c00開始,大小為2k,FLASH分為兩個區域總的大小為256K。

另一個是關于變量、代碼等分配的存儲位置。如下如所示。我們需要重點關注的是紅色區域內的信息。觀察一下。我們不難理解紅色區域內代碼的含義,是將.bss段、.data段、.sysmem段及.stack段的信息放在RAM區,而.test段等信息被存儲在FLASH區。這些段各代表什么呢?這里我也做了一下總結,如下如所示。


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