C++ STM32 板的 RAM、堆和堆栈存储器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24929535/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:50:46  来源:igfitidea点击:

RAM, Heap, and Stack memory for an STM32 board

c++embeddedstm32keil

提问by Dude

I am working on a project that requires at least 500 kB of memory to be used. I have an SDK with this code defining the stack and the heap and it works fine.

我正在处理一个需要至少 500 kB 内存的项目。我有一个带有定义堆栈和堆的代码的 SDK,它工作正常。

Stack_Size      EQU     0x00004000

            AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp


; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00200000

            AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

However, I am trying to integrate a camera and LCD screen feature into this SDK, and when I do that, the highest values of the stack and heap that will at least bring up the LCD screen are shown below. Any values higher than this and the LCD screen stays black and the application doesn′t appear to run.

但是,我正在尝试将相机和 LCD 屏幕功能集成到此 SDK 中,当我这样做时,至少会显示 LCD 屏幕的堆栈和堆的最高值如下所示。任何高于此值的值都会使 LCD 屏幕保持黑色,并且应用程序似乎无法运行。

Stack_Size      EQU     0x00004000

            AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp


; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00002B50

            AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

I need the sizes of the stack and heap in the second code sample to match the sizes in the first code sample so that I do not get stuck in a hard fault exception loop due to no memory being available. Why does increasing the heap size make my project worse? Meaning how come it doesn′t even appear to run when I increase the heap size?

我需要第二个代码示例中堆栈和堆的大小来匹配第一个代码示例中的大小,这样我就不会因为没有可用内存而陷入硬故障异常循环中。为什么增加堆大小会使我的项目变得更糟?这意味着为什么当我增加堆大小时它甚至没有运行?

I have attached a screenshot of my project options so you can see the configuration of the RAM.

我附上了我的项目选项的屏幕截图,以便您可以看到 RAM 的配置。

Screenshot

截屏

Below is the amount of memory I have. Doesn′t this mean that I have 2 MB of RAM?

以下是我拥有的内存量。这不是说我有 2 MB 的 RAM 吗?

8 M x 32-bit SDRAM is connected to SDRAM Bank1 of the STM32F439NIH6 FMC interface.

8 M x​​ 32 位 SDRAM 连接到 STM32F439NIH6 FMC 接口的 SDRAM Bank1。

1 Mbit x 16 SRAM is connected to bank1 NOR/ PSRAM2 of the FMC interface and both 8-bit and 16-bit access is allowed by BLN0 & BLN1 connected to BLE & BHE of SRAM respectively.

1 Mbit x 16 SRAM 连接到 FMC 接口的 bank1 NOR/PSRAM2,BLN0 和 BLN1 分别连接到 SRAM 的 BLE 和 BHE,允许 8 位和 16 位访问。

回答by kkrambo

Your STM32F4 microcontroller does not physically have 0x200000 (2 MB) of RAM beginning at address 0x20000000. I believe it has only 0x30000 (192 KB). Check the memory map section of the datasheet.

您的 STM32F4 微控制器在物理上没有从地址 0x20000000 开始的 0x200000 (2 MB) RAM。我相信它只有 0x30000 (192 KB)。检查数据表的内存映射部分。

If you tell the linker that there is non-existent memory available, then the linker may try to use that memory and then your program will crash. I suspect for your original program the linker never used the non-existent memory so the program ran successfully. But in your subsequent program the linker is trying to use the non-existent memory and the program is crashing. Look at the map file generated by the linker to see how the various parts of your program have been assigned into memory by the linker. You'll probably find that the first program doesn't use memory beyond 0x20030000 but the second program does.

如果您告诉链接器没有可用的内存,那么链接器可能会尝试使用该内存,然后您的程序将崩溃。我怀疑对于您的原始程序,链接器从未使用过不存在的内存,因此程序成功运行。但是在您的后续程序中,链接器试图使用不存在的内存,并且程序崩溃了。查看链接器生成的映射文件,了解链接器如何将程序的各个部分分配到内存中。您可能会发现第一个程序不使用超过 0x20030000 的内存,但第二个程序使用。

If you really need 500 KB of memory or more then you're going to have to add an external memory device to your board because the microcontroller does not have that much RAM.

如果您真的需要 500 KB 或更多的内存,那么您将不得不向您的电路板添加一个外部存储设备,因为微控制器没有那么多 RAM。

Update: If your board has memory connected to the FMC (flexible memory controller) then that is external or off-chip memory. The external memory is not addressed at 0x20000000 though. It should be located somewhere in the range of 0x60000000 to 0xDFFFFFFF (see the memory map section of the datasheet). Your program will have to configure the FMC appropriately before accessing the external memory. And you should probably tell the linker that the external memory exists by enabling one (or more) of those off-chip memory sections in that options dialog box. You can probably get details and advice about how to enable the off-chip memory from the board designer.

更新:如果您的电路板有连接到 FMC(灵活内存控制器)的内存,那么它就是外部或片外内存。不过,外部存储器并未在 0x20000000 处寻址。它应该位于 0x60000000 到 0xDFFFFFFF 范围内的某个位置(请参阅数据表的内存映射部分)。在访问外部存储器之前,您的程序必须适当地配置 FMC。并且您可能应该通过在该选项对话框中启用一个(或多个)片外存储器部分来告诉链接器外部存储器存在。您可能会从电路板设计人员那里获得有关如何启用片外存储器的详细信息和建议。

回答by Clifford

If you tell the linker you part has 2Mb on-chip ROM and 2Mb + 64Kb of on-chip RAM it will believe you, and happily locate code and data accordingly - but don't expect anything useful to happen when you access memory that does not exist!

如果你告诉链接器你的部分有 2Mb 片上 ROM 和 2Mb + 64Kb 片上 RAM,它会相信你,并愉快地相应地定位代码和数据 - 但不要指望当你访问内存时会发生任何有用的事情不存在!

If you set the memory areas correctly, the linker will fail when you have exceeded the target's capacity. That's a physical limit, the solution is not to lie to the linker - that just generates a runtime error rather than a build error.

如果您正确设置了内存区域,则当您超出目标的容量时,链接器将失败。这是一个物理限制,解决方案不是对链接器撒谎——它只会生成运行时错误而不是构建错误。