The first 256 bytes of address space are the 32 general registers and various I/O registers. SRAM starts at 256 decimal.
The stack starts at 2303 = 256 + 2047. The stack pointer is decremented when items are pushed.
Looks like freeMemory() has not been fixed for the latest change to malloc./heap. The Arduino company changed malloc() to a nonstandard version then changed it again. This broke lots of free memory programs twice.
I was thrown off by the atmega328p datasheet diagram on page 18 (attached). The lower right shows the last address as 0x08FF. Just now I noticed the text:
The lower 768/1280/1280/2303 data memory locations address both the Register File, the I/O
memory, Extended I/O memory, and the internal data SRAM. The first 32 locations address the
Register File, the next 64 location the standard I/O memory, then 160 locations of Extended I/O
memory, and the next 512/1024/1024/2048 locations address the internal data SRAM.
fat16lib:
Looks like freeMemory() has not been fixed for the latest change to malloc./heap. The Arduino company changed malloc() to a nonstandard version then changed it again. This broke lots of free memory programs twice.
Here is my attempt at fixing it. Looks like it works to me.
#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else // __ARM__
extern char *__brkval;
extern char __heap_start;
#endif // __arm__
int freeMemory() {
char top;
#ifdef __arm__
return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(CORE_TEENSY)
return &top - __brkval;
#else // __arm__
return __brkval ? &top - __brkval : &top - &__heap_start;
#endif // __arm__
}
Here is my new output (added a malloc to the code to test a non-zero heap):
Your "fix" looks a lot like my SdFat code from 5/4/2013. What do you claim is new?
04 May 2013
Fix FreeRam() for 1.05/1.53 malloc.
/* Arduino SdFat Library
* Copyright (C) 2012 by William Greiman
*
* This file is part of the Arduino SdFat Library
*
* This Library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This Library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with the Arduino SdFat Library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else // __ARM__
extern char *__brkval;
extern char __bss_end;
#endif // __arm__
//------------------------------------------------------------------------------
/** Amount of free RAM
* \return The number of free bytes.
*/
int SdFatUtil::FreeRam() {
char top;
#ifdef __arm__
return &top - reinterpret_cast<char*>(sbrk(0));
#else // __arm__
return __brkval ? &top - __brkval : &top - &__bss_end;
#endif // __arm__
}
freeMemory returns free memory for both the heap and stack. My (not likely your) FreeRam() only returns free memory for the stack.
fat16lib:
Your "fix" looks a lot like my SdFat code from 5/4/2013. What do you claim is new?
I dont think i understand your question or your point. All I did was take the a MemoryFree library that I downloaded off the Arduino website and edit it until it worked for me. I only posted this in case someone else is having similar trouble.
fat16lib:
freeMemory returns free memory for both the heap and stack.
I think you are saying that freeMemory() returns the free space taking into account both the stack and the heap. If I am understanding you correctly then I completely agree.
fat16lib:
My (not likely your) FreeRam() only returns free memory for the stack.
I dont see any functional difference in our code given that for Arduino __bss_end is the same as __heap_start:
I dont think i am understanding your point. If I made a mistake please let me know; I am here to learn.
I have no doubt you are the original author and I sincerely thank your for your contribution. The last thing i want to do is piss off helpful forum folks such as yourself.