2012-08-31 21 views
0

我對編程微控制器相當陌生,我一直在使用LPC1788幾個星期。LPC1788微控制器的內存分配問題

我最近遇到的一個問題是我的內存耗盡時間比我想象的要早得多。我已經測試了多少內存似乎可以通過測試多大塊連續內存我可以malloc,結果是972字節。分配從地址0x10000000開始(片上SRAM的開始,該板應該在64kB左右)。

我目前正在使用的程序是用作一個簡單的調試程序,它利用LCD並允許將消息打印到它。我有一個字符串會不斷被新消息「添加」,然後整個消息將被打印在LCD上。當屏幕上的消息長度超過垂直邊界時,它將刪除最早的消息(靠近頂部的消息),直到它適合。但是,在拒絕分配更多內存之前,我只能添加大約7條附加消息。如果需要,該項目的main.c託管在http://pastebin.com/bwUdpnD3

早些時候我也開始使用threadX RTOS創建和執行多個線程的項目。當我試圖在該程序中使用LCD時,我發現內存也非常有限。 LCD似乎存儲從SDRAM基地址開始的所有像素數據,但我不確定這與我使用的SRAM是否一樣。

我需要的是一種足夠分配內存以允許多個線程工作或存儲大字符串的方式,同時能夠使用LCD。一種可能是使用緩衝區或其他內存區域,但我不太確定如何做到這一點。任何幫助,將不勝感激。

tl; dr:嘗試在LCD上打印出大字符串時,快速耗盡SRAM上的可分配內存。

編輯1:與變量currMessage注意到內存泄漏。我認爲現在已經修復:

strcpy(&trimMessage[1], &currMessage[trimIndex+1]); 

// Frees up the memory allocated to currMessage from last iteration 
// before assigning new memory. 
free(currMessage); 
currMessage = malloc((msgSize - trimIndex) * sizeof(char)); 
for(int i=0; i < msgSize - trimIndex; i++) 
{ 
    currMessage[i] = trimMessage[i]; 
} 

編輯2:實施內存泄漏修復程序。現在程序運行得好多了,我覺得很蠢。

+0

這可能是堆碎片或者甚至可能只是內存泄漏 - 您需要對內存管理策略給予更多思考。 –

回答

1

在嵌入式環境中選擇使用動態內存分配時,尤其是在內存受限的情況下,您需要小心。你可以很容易地結束內存空間的分割,使剩下的最大空洞是972字節。

如果您必須從堆中分配一次,然後掛在內存上 - 幾乎就像是一個靜態緩衝區。如果可能的話,使用靜態緩衝區並避免所有的分配。如果您必須具有動態分配,則將其保留到固定大小的塊將有助於分段。

不幸的是,它需要一些工程努力來克服碎片問題。這是值得的努力,它確實使系統更健壯。

至於SRAM vs SDRAM,它們是不一樣的。我對threadX不熟悉,以及他們是否有用於開發板的板級支持包(BSP),但一般來說,必須設置SDRAM。這意味着引導代碼必須初始化內存控制器,設置時序,然後啓用該空間。根據你的堆實現,你需要動態地添加它,或者更可能的是,你需要編譯堆空間,指向它最終將生存的地方(在SDRAM空間中)。然後,您必須確保在實際使用堆之前啓動配置和激活的內存控制器。

另一件需要注意的事情是,您可能實際上正在從SRAM空間運行代碼,並且其中一些空間也被保留用於處理器異常表。例如,整個空間可能不可用,並且可能通過兩個不同的地址(0x00000000和0x10000000)生存。我知道在其他一些ARM9處理器中,這很常見。您可以從閃存啓動,該閃存最初映射到0x00000000空間,然後您做歌曲和舞蹈以將引導程序複製到SRAM並將SRAM映射到該空間。在這一點上,你可以引導到像Linux這樣的人,他們希望能夠更新以0表示的表格。

順便說一句,它看起來好像你在你發佈的代碼中有一些內存泄漏。也就是說,currentMessage永遠不會被釋放......只會被一個新的指針覆蓋。那些街區然後永遠消失。

+0

首先,謝謝指出內存泄漏。我修改了printMessage()的代碼(更改的細節將被編輯爲原始文章),並希望現在已經排序,儘管我的程序似乎仍然在同一時間內存不足。 建議動態分配一次並掛在內存上似乎是我現在可以做的最好的事情。也許在開始時爲currMessage創建一個500字符的數組,然後修改其中的字符。儘管如此,對於我想處理的任何事情而言,仍然只剩下大約400個字節。 – Tagc

+0

另一個內存泄漏存在於第177行左右......類似的問題。 – jszakmeister

+0

好點。我更正了trimMessage()中的代碼,當時我以爲我在printMessage()中(這兩個函數看起來有些類似)。兩者都包含內存泄漏,但是從目前的任何地方我都沒有調用trimMessage(),這就解釋了爲什麼修改沒有效果。我在修復printMessage()中的問題時遇到了一些問題,但在工作時我會進行更新。 TY。 – Tagc