我对编程微控制器相当新;我已经和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与SDRAM,它们并不相同。我不熟悉threadX,以及他们是否有适用于您的主板的板级支持包(BSP),但一般来说,必须设置SDRAM。这意味着启动代码必须初始化内存控制器,设置时序,然后启用该空间。根据您的堆实现,您需要动态添加它 - 或者 - 更有可能 - 您需要使用指向最终生存位置(在SDRAM空间中)的堆空间进行编译。然后,您必须确保在实际使用堆之前启动并配置和激活内存控制。
另外需要注意的是,您实际上可能正在从SRAM空间运行代码,并且某些空间也保留用于处理器异常表。整个空间可能不可用,并且可能存在两个不同的地址(例如0x00000000和0x10000000)。我知道在其他一些ARM9处理器中,这很常见。你可以从闪存引导,它最初被映射到0x00000000空间,然后你做一个歌曲和舞蹈,将引导复制到SRAM并将SRAM映射到该空间。此时,您可以启动Linux之类的东西,希望能够更新低于0的表。
顺便说一句,看起来你发布的代码中有一些内存泄漏。也就是说,currentMessage永远不会被释放...只能用新指针覆盖。那些街区将永远丢失。