cancel
Showing results for 
Search instead for 
Did you mean: 

Have I run out of Memory, RAM Overflow

uli stone
Associate II

Hi,

I'm having trouble, because I got when I defined a second array which I need for processing a image with the STM32F429ZI Microcontroller a message that I have a RAM overflow.

When I now define a smaller array, like uint8_t image[240][320] my whole application is not running on the Microcontroller. But when I comment the initialization n of the image array out, everything is working fine.

How can I see how much memory I have used and how could I rearrange other memory on the Microcontroller?

Thank you

21 REPLIES 21
uli stone
Associate II

I get the following output on the console:

Generating binary and Printing size information:
arm-none-eabi-objcopy -O binary "test.elf" "test.bin"
arm-none-eabi-size --format=berkley "test.elf"
   text	   data	    bss	    dec	    hex	filename
   5088	   1328	 151372	 157788	  2685c	test.elf

S.Ma
Principal

Start with the MAP file usually optionally generated with the OUT file.

When you declare and not use a global variable, it typically is removed from the memory space by the linker.

union to recycle globals time multiplexed, variables prefferably in the stack than global, etc..

uli stone
Associate II

Hi,

I'm not sure how I can achieve what you are saying, as I never had this problem. I have in my project folder the file: "output.map" but how should I use it?

Bob S
Principal

Look in the MAP file and see what the highest address in the 0x2000xxxx range is. This is your RAM. You can also see what modules (source files) use lots of RAM. The STM32F429 should have 256K bytes, so 0x20000000 to 0x2003ffff.

As for @S.Ma​  comment about unused globals being removed by the linker - that depends on the compiler. And with the GCC compiler is typically not the case. There may be a configuration switch to enable this, I don't know. And other compilers may behave differently.

uli stone
Associate II

Hi Bob,

thank you very much. I didn't find anything above 0x0x20005xxx. So I should have left 0x1AAFF Memory left?

I'm not sure how to work with the map file and I only have the global variables I need to use.

*.map file:

                0x20030000                _estack = 0x20030000
                0x00000200                _Min_Heap_Size = 0x200
                0x00000400                _Min_Stack_Size = 0x400
 
...
...
...
 
 *fill*         0x20024e70      0x200 
                  0x20025470                . = (. + _Min_Stack_Size)

Bob S
Principal

Is this the map file WITHOUT the "uint8_t image[240][320] " that you mentioned in your first post? If so, put that declaration back in your code and compile it. Give us the exact compiler/linker error message and the map file. Now I am presuming the "RAM overflow" message was indeed from the compiler/linker and not a run-time message. Right?

Bob S
Principal

Hmmm..... I just noticed something else in the fragment of the map file you posted. "_estack" is set to 0x20030000, which is NOT the top of the 256K byte RAM space. It looks like the STM32F429 splits its 256K byte RAM into 3 sections: 112K bytes, 16K bytes and 64K bytes. The last 64K bytes is CCM RAM and I bet that your linker file (something.ld if you are using the GCC tool set) declares your RAM size to be 192K bytes (or 0x30000 bytes), thus excluding the CCM RAM.

I don't recall if you need to do anything special in the F4xx series to use the CCM. Or if that memory section is used by some module (USB???).

uli stone
Associate II

Thanks Bob for your reply.

Two things I want to clarify:

  • When I globally decleare uint16_t image[74880] I get the following error (for the attatched output.map file):
c:/ac6/systemworkbench/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.15.0.201708311556/tools/compiler/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/bin/ld.exe: dcmi_dma.elf section `.bss' will not fit in region `RAM'
makefile:57: recipe for target 'dcmi_dma.elf' failed
c:/ac6/systemworkbench/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.15.0.201708311556/tools/compiler/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/bin/ld.exe: region `RAM' overflowed by 105840 bytes
  •    When I use "uint8_t image[240][320]" (locally in the main function) I don't get an error. But somehow my code is not working correctly (when executed on the dev board). Only when I comment "uint8_t image[240][320]" out or reduce it to something like "uint8_t image[100][100]". So I thought it is connected to the memory.

=> I only use the following modules: i2c, dma, dcmi, spi and gpios (no usb). And program everything with a direct register access and with the gcc compiler.

I would not mind to have slow speed memory, because I think the flash is not used at all? How could I use this?

Bob S
Principal

First: uint16_t image[74880] is VERY MUCH different than uint8_t image[240][320]. The first occupies 149760 bytes , the second occupies 76800 bytes.

Second: in your second case of declaring "uint8_t image[240][320]" locally in main() will absolutely fail AT RUN TIME because that will be allocated on the STACK. And your linker file only guarantees 0x400 (1024) bytes of stack space, which means your stack will overflow and overwrite some of your global and global/static RAM variables. As a general rule, NEVER declare large arrays as local variables unless you know your stack can hold it.

So, questions for you:

  1. Why did you try uint16_t in your first example? Do you need 16-bit data, or 8-bit as you used in your original email and your second example above.
  2. Why did you choose 74880 as the array size for the uint16_t array? Or was that a typo and you meant 76800 (which is 240x320)?
  3. In your linker file (look for *.ld in the root of your project directory), find the "MEMORY" section and tell us what the RAM length is. You should see a line something like this "RAM (xrw) : ORIGIN = 0x20000000, LENGTH = ????K".

As I mentioned before, you will probably need to edit your linker file and change the length of the RAM segment from 192K to 256K, and then figure out if you need to do anything special to enable the CCM RAM that is the upper 64K of the 256K RAM.