外部RAM工作和内存管理

时间:2019-03-03 12:16:00

标签: c embedded microcontroller ram

相对于具有内部RAM的MCU,如何利用外部RAM?

能否在外部RAM中创建堆栈/堆等区域?

如何在外部RAM中链接/执行功能? (Keil 4 IDE)

1 个答案:

答案 0 :(得分:2)

内存将按照分散文件或链接描述文件中定义的方式使用-与MCU和内部/外部RAM无关。

您可以在分散文件中描述平台上可用的物理内存区域(各种工具链可能使用不同的术语,例如链接描述文件),并为每个部分分配属性,以告知链接器每个内存可能用于什么并且可能明确地使用将某些代码或数据项定位到特定部分。

链接器不会在您未告知的内容中找到任何内容。您可能希望以相同的方式处理所有内存,并给链接器自由的控制权,以便在需要的地方进行分配,但是对于MCU,这可能不是最佳选择。例如,内部存储器总线可能比外部存储器总线快,因此您可能将时间紧迫的处理限制于此。如果让链接器按其分配的方式进行分配,那么如果将某些关键对象移至速度较慢的内存中,则对代码的修改可能会显着改变性能。

即使在内部RAM中,该部分也可以使用独立的总线将其划分为不同的区域,例如,您可以使用专门用于DMA的区域来减少或消除总线争用。

因此,虽然工具链提供的部分默认链接描述文件可能适合一般用途,但是如果您对内部,外部,QSPI等具有不同速度和不同属性的内存有复杂的要求,则可能需要自定义脚本,以充分利用可用资源。

特别是在Keil中,您可以在项目配置的“目标”选项卡中分配基本的内存区域安排:

enter image description here

在这种情况下,您可以在RAM1 / 2/3字段中添加外部存储器。

对于更复杂的要求(例如,创建命名节),请在链接器选项卡中: enter image description here 您需要取消选中“从目标使用内存布局对话框”框,然后对分散文件单击“编辑”(或提供新的分散文件路径)。默认的分散文件是由目标对话框中的设置创建的,但是现在您已将其解耦,以便可以根据需要进行自定义。

要注意的一件事是,经常访问外部存储器需要正确配置外部存储器控制器(例如,分配总线引脚并设置正确的总线时序)。如果链接器要分配此类内存的使用,则在由C或C ++运行时启动代码执行应用程序内存初始化之前,必须在运行时启动代码中配置内存,这一点很重要。通常至少在最初需要将系统堆栈放置在内部存储器中,因为启动代码可能需要在初始化外部存储器之前就需要一个堆栈。可以稍后在C运行时开始之前移动系统堆栈,但是如果您使用的是RTOS,则这是不必要的,因为在外部存储器工作之后,每个任务都会建立自己的堆栈。除了在系统堆栈也是中断堆栈的部分上,您还希望将其保存在最快,最可靠(就可用性而言)的内存中。

另一个要考虑的问题是,诸如ARM Cortex-M之类的体系结构具有用于代码和数据的单独总线,从而使它们能够同时获取指令和数据。如果将代码放在数据RAM中,则可能会显着减慢执行速度,因为必须顺序执行从同一存储器中提取指令和数据的操作。再加上外部存储器的总线速度通常较低,您可能需要谨慎地将要执行的代码放入外部RAM(或实际上是任何RAM)中。在某些部件上(通常是具有Von Neumann架构的部件),RAM的执行速度比从ROM执行的速度要快,但是对于具有哈佛架构总线,闪存加速器或高速缓存的部件,情况并非一定如此。因此,不要以为在外部RAM中定位代码会有好处。