Go Down

Topic: CONFUSED. Arduino DUE and memory misunderstandings (Read 1 time) previous topic - next topic

digimorf

Hello everybody,

I am new to Arduino Due, I am trying to get familiar with this platform, and I started to do tests with the memory map/locations.

I bumped into this page:
http://rdiez.shoutwiki.com/wiki/Hacking_with_the_Arduino_Due

that shows a Memory map of the Arduino Due:
Code: [Select]
0x0008 0000 - 0x000B FFFF   256 KiB flash bank 0
0x000C 0000 - 0x000F FFFF   256 KiB flash bank 1
                            Both banks above provide 512 KiB of contiguous flash memory
0x2000 0000 - 0x2000 FFFF   64 KiB SRAM0
0x2007 0000 - 0x2007 FFFF   64 KiB mirrored SRAM0, so that it's consecutive with SRAM1
0x2008 0000 - 0x2008 7FFF   32 KiB SRAM1
0x2010 0000 - 0x2010 107F   4224 bytes of NAND flash controller buffer


Maybe it's a silly, but the first thing I am trying to understand is the dynamic allocation of memory with "malloc" that should be related to the Heap. I know that his can generate problems on microcontrollers, bt what it's not clear is why the malloc function returns a valid ( != NULL ) pointer when trying to allocate a 256Kb range of memory. Actually it shouldn't.

Code: [Select]
 Serial.begin(9600);

  char Txt[255];

  // Try to malloc 256Kb
  char *RAMPtr = (char *)malloc(256*1024*sizeof(char));
  
  // Show the pointer value
  sprintf(Txt, "RAM pointer 'RAMPtr': %p", RAMPtr);
  Serial.println(Txt);


the pointer returned is at: 0x20071310. This location should be in the SRAM0 mirrored bank, correct? But actually the malloc function shouldn't be able to allocate this memory range.

The second problem is similar but this should be related to the Stack. If I declare an array which size is bigger than the memory available it works in any case:

Code: [Select]
 Serial.begin(9600);
  
  char Txt[255];

  char Array1[1024*256];
    
  // Show the pointer value
  sprintf(Txt, "'Array1' pointer': %p", &Array1);
  Serial.println(Txt);


And the 'Array1' pointer' is: 0x20047fe8, but where is this in the memory map?

Are those issues or I am doing something wrong?

Thanks.



RayLivingston

This might help clarify where things are in memory:

Code: [Select]

struct mallinfo mi=mallinfo();

pConsole->printf("    arena=%d\n",mi.arena);
pConsole->printf("  ordblks=%d\n",mi.ordblks);
pConsole->printf(" uordblks=%d\n",mi.uordblks);
pConsole->printf(" fordblks=%d\n",mi.fordblks);
pConsole->printf(" keepcost=%d\n",mi.keepcost);

char *heapend=sbrk(0);
register char * stack_ptr asm("sp");

pConsole->printf("RAM Start %lx\n", (unsigned long)ramstart);
pConsole->printf("Data/Bss end %lx\n", (unsigned long)&_end);
pConsole->printf("Heap End %lx\n", (unsigned long)heapend);
pConsole->printf("Stack Ptr %lx\n",(unsigned long)stack_ptr);
pConsole->printf("RAM End %lx\n", (unsigned long)ramend);

pConsole->printf("Heap RAM Used: %d\n",mi.uordblks);
pConsole->printf("Program RAM Used %d\n",&_end - ramstart);
pConsole->printf("Stack RAM Used %d\n",ramend - stack_ptr);
pConsole->printf("Estimated Free RAM: %d\n\n",stack_ptr - heapend + mi.fordblks);

pConsole->printf("Enabling Motion Control...\n");


Not sure why malloc would return non-zero for a too-large request, unless perhaps the max request size is limited to a 16-bit value?  You'd have to find the malloc source code to check.

Regards,
Ray L.

digimorf

#2
Feb 23, 2016, 10:09 am Last Edit: Feb 23, 2016, 10:21 am by digimorf Reason: Updated attachments
Hello Ray,

thanks for your reply. I merged your code with another one found in the forum, regarding the available memory and I attached the sketch in this post "ArduinoDueMemInfo".

So this is definitely useful to monitor the memory used by Arduino Due Sketches. But yesterday I did other tests, and actually I think that there is something broken on the "Malloc" function.

Malloc-Test-1:

This test performs multiple allocations of a growing buffer. For every cycle the size of the buffer is increased. After each allocation the buffer is freed. This test ends when the size of the buffer reach 256Kb (clearly over the range of RAM available).
The result of the test is weird, because the "free" function works perfectly in fact the pointer of the buffer is always the same. But the "Malloc" seems not to care about the free memory and goes beyond the available memory range.


Malloc-Test-2

Like the previous, this test performs multiple allocations of a growing buffer. For every cycle the size of the buffer is increased. This time the allocated buffer is NOT freed. This test ends when the size of the buffer reach 256Kb (clearly over the range of RAM available).
The result of the test again is weird, because the pointer of the buffer always changes like it should, but it goes beyond the allowed range and seems to crash when it goes over 0x200fxxxx. It should return a null pointer actually.


Probably this it's not a big deal, but I wanted to understand more about this subject. Maybe I am doing something wrong...  Anyway I think I will try to implement my own memory manager for the applications I am going to develop.

amitmc19

Hi Ray

Did you figure out the reason for this behavior? I observe the same. "malloc" successfully returns 256KB when I request heap data through malloc even though due doesnt have enough memory.

Thanks,
Amit

Go Up