2012-08-31 25 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