Map layout of RAM

I’m not sure if this is correct:

#include "xmem.h"
extern unsigned int __heap_start, __heap_end;
extern unsigned int __bss_start, __bss_end;
extern unsigned int __data_start, __data_end;
/////////////////////////////////////////////////////////////////////////////
void print4hex(unsigned int adr){
  Serial.print("0x");
  if (adr<0x1000){Serial.print("0");};
  if (adr<0x0100){Serial.print("0");};
  if (adr<0x0010){Serial.print("0");};
  Serial.print(adr, HEX);
};
/////////////////////////////////////////////////////////////////////////////
void printborders(bool moveheap){
  xmem::begin(moveheap);
  print4hex((unsigned int)&__data_start);
  Serial.println(" __data_start");
  print4hex((unsigned int)&__data_end);
  Serial.println(" __data_end");
  print4hex((unsigned int)&__bss_start);
  Serial.println(" __bss_start");
  print4hex((unsigned int)&__bss_end);
  Serial.println(" __bss_end");
  print4hex((unsigned int)&__heap_start);
  Serial.println(" __heap_start");
  print4hex((unsigned int)&__heap_end);
  Serial.println(" __heap_end");
  print4hex((unsigned int)&__brkval);
  Serial.println(" __brkval");
  print4hex((unsigned int)__malloc_heap_start);
  Serial.println(" __malloc_heap_start");
  print4hex((unsigned int)__malloc_heap_end);
  Serial.println(" __malloc_heap_end");
  print4hex((unsigned int)SP);
  Serial.println(" SP (call stack pointer)");
};
/////////////////////////////////////////////////////////////////////////////
void printalloc(){
  Serial.println("Conventional memory usage:");
  printborders(false);
  Serial.println("Extended memory usage (Heap moved):");
  printborders(true);
};

Running on Arduino Mega 2560 R3 (exactly: EtherMega) with SRAM shield the output is:

Conventional memory usage:
0x0200 __data_start
0x058C __data_end
0x058C __bss_start
0x0B79 __bss_end
0x0B79 __heap_start
0x0000 __heap_end
0x0B75 __brkval
0x0B79 __malloc_heap_start
0x0000 __malloc_heap_end
0x2198 SP (call stack pointer)

Extended memory usage (Heap moved):
0x0200 __data_start
0x058C __data_end
0x058C __bss_start
0x0B79 __bss_end
0x0B79 __heap_start
0x0000 __heap_end
0x0B75 __brkval
0x2200 __malloc_heap_start
0xFFFF __malloc_heap_end
0x2198 SP (call stack pointer)

So, my question si: is this correct or wrong way to get .Data .Bss and Heap borders? And where is call stack? How to print stack address (or address of memory location of return address)?
What means: __heap_end=0x0000 ? And if __brkval is outside __malloc_heap_start/end is this OK?

I created this image, please check it and correct me if I’m wrong

Really no one knows?

It seems reasonable but I haven't looked at the 2560 memory map for years. You can get 64k external mem blocks but I can't remember how you do that or how that would affect your map. I would assume it eats downward into the stack etc.


Rob

It looks OK. Is it important to know this?

The stack pointer normally starts at the top of RAM and grows downwards. The heap starts at the end of variables and grows upwards. This is what your diagram showed, I think.

In the coming age of 8-bit home computers /early '80/ it was important to know the arrangement of computer memory. I think it's still important to understand how "things" work.

And next question (Arduino IDE): -how to set the compiler to directly set the heap at address 0x2200? -where and how to define switches for the compiler?

-how to set the compiler to directly set the heap at address 0x2200?

The compiler does that automatically:

000000e6 <__ctors_end>:
  e6:	11 24       	eor	r1, r1
  e8:	1f be       	out	0x3f, r1	; 63     <----- SREG
  ea:	cf ef       	ldi	r28, 0xFF	; 255
  ec:	d1 e2       	ldi	r29, 0x21	; 33
  ee:	de bf       	out	0x3e, r29	; 62     <----- SPH
  f0:	cd bf       	out	0x3d, r28	; 61     <----- SPL

Well, it’s 0x21FF but that’s close enough. Note that instructions like PUSH put data into the current location and then decrement the stack pointer, so that the stack pointer has to point to valid RAM initially (which 0x2200 is not).

PUSH – Push Register on Stack

Description:

This instruction stores the contents of register Rr on the STACK. The Stack Pointer is post-decremented by 1 after the PUSH.

is this correct or wrong way to get .Data .Bss and Heap borders?

You're looking at symbol definitions produced by the compiler/linker at compile-time, so they won't take into account changes in the heap caused by doing actual memory allocations. Other than that, I think it looks OK. If you're looking at the avr-libc documentation for malloc() and etc (and you should be), be sure that you're looking at the documentation that goes with the version of avr-libc that Arduino is actually using.

-where and how to define switches for the compiler?

In 1.5.x, you can modify hardware/arduino/avr/platform.txt

how to set the compiler to directly set the heap at address 0x2200?

You're already looking at the values that the compiler has set. "heap" (and etc) has no meaning outside of the compiler/libc context. See also the "Data Memory Map" in the Atmel datasheets (registers, io registers, internal ram, external ram, are the things that have more fundamental meaning.)