I have seen the freeMemory
function in https://playground.arduino.cc/Code/AvailableMemory , and it seems to use something called __brkval
. However, I simply cannot find where is this macro or variable defined:
$ grep -ri brkval /c/arduino-1.8.8/ --include='*.c' --include='*.h'
/c/arduino-1.8.8/libraries/Robot_Control/src/Fat16util.h: extern int* __brkval;
/c/arduino-1.8.8/libraries/Robot_Control/src/Fat16util.h: if (reinterpret_cast<int>(__brkval) == 0) {
/c/arduino-1.8.8/libraries/Robot_Control/src/Fat16util.h: - reinterpret_cast<int>(__brkval);
/c/arduino-1.8.8/libraries/SD/src/utility/SdFatUtil.h: extern int* __brkval;
/c/arduino-1.8.8/libraries/SD/src/utility/SdFatUtil.h: if (reinterpret_cast<int>(__brkval) == 0) {
/c/arduino-1.8.8/libraries/SD/src/utility/SdFatUtil.h: - reinterpret_cast<int>(__brkval);
$ grep -ri brkval /c/avr-gcc-8.2.0-x64-mingw/ --include='*.c' --include='*.h'
# nothing
$ grep -ri brkval /c/Program\ Files\ \(x86\)/Atmel/Studio/ --include='*.c' --include='*.h'
# nothing
$ grep -ri brkval /c/cvavr/ --include='*.c'
# nothing
That is, only Arduino IDE has some references to it, but only as extern int*
reference, it does not have a definition.
Closest I came to some sort of a verbose explanation is from https://github.com/greiman/SdFat/blob/master/src/FreeStack.h :
/** boundary between stack and heap. */
extern char *__brkval;
... but again, no definition.
So where is this variable or macro defined?
EDIT: as per comments, searching through all files:
$ grep -ri brkval /c/cvavr/
# nothing
$ grep -ri brkval /c/Program\ Files\ \(x86\)/Atmel/Studio/
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avr25/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avr25/tiny-stack/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avr3/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avr31/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avr35/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avr4/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avr5/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avr51/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avr6/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avrtiny/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avrxmega2/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avrxmega3/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avrxmega3/short-calls/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avrxmega4/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avrxmega5/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avrxmega6/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/avrxmega7/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/libc.a matches
Binary file /c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/tiny-stack/libc.a matches
/c/Program Files (x86)/Atmel/Studio/7.0/toolchain/avr8/avr8-gnu-toolchain/doc/avr-libc/avr-libc-user-manual/stdlib__private_8h_source.html:<a name="l00045"></a>00045 <span class="keyword">extern</span> <span class="keywordtype">char</span> *__brkval; <span class="comment">/* first location not yet allocated */</span>
$ grep -ri brkval /c/avr-gcc-8.2.0-x64-mingw/
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avr25/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avr25/tiny-stack/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avr3/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avr31/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avr35/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avr4/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avr5/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avr51/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avr6/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avrtiny/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avrxmega2/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avrxmega4/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avrxmega5/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avrxmega6/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/avrxmega7/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/libc.a matches
Binary file /c/avr-gcc-8.2.0-x64-mingw/avr/lib/tiny-stack/libc.a matches
$ grep -ri brkval /c/arduino-1.8.8/
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avr25/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avr25/tiny-stack/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avr3/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avr31/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avr35/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avr4/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avr5/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avr51/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avr6/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avrtiny/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avrxmega2/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avrxmega3/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avrxmega3/short-calls/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avrxmega4/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avrxmega5/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avrxmega6/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/avrxmega7/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/libc.a matches
Binary file /c/arduino-1.8.8/hardware/tools/avr/avr/lib/tiny-stack/libc.a matches
/c/arduino-1.8.8/libraries/Robot_Control/src/Fat16util.h: extern int* __brkval;
/c/arduino-1.8.8/libraries/Robot_Control/src/Fat16util.h: if (reinterpret_cast<int>(__brkval) == 0) {
/c/arduino-1.8.8/libraries/Robot_Control/src/Fat16util.h: - reinterpret_cast<int>(__brkval);
/c/arduino-1.8.8/libraries/SD/src/utility/SdFatUtil.h: extern int* __brkval;
/c/arduino-1.8.8/libraries/SD/src/utility/SdFatUtil.h: if (reinterpret_cast<int>(__brkval) == 0) {
/c/arduino-1.8.8/libraries/SD/src/utility/SdFatUtil.h: - reinterpret_cast<int>(__brkval);
There are many others with the same question. And as is pointed out, in simplest terms it is used to mark the boundary between stack and heap memory. Here are some related discussions with content that includes __brkval
:
The final link addresses your main question, at least for Arduino environments:
with the memory profiler function added (note that it uses freeMemory via MemoryFree.h, which is also given in the thread above), and starting array size of 100 elements (400 bytes):
// minitest.pde
static unsigned long mydata_count;
static const long SERSPEED=115200;
static const int SIZE=100;
static const char RSTSTR[] = "RESET!!";
static unsigned long mydata[SIZE];
#include <MemoryFree.h>
extern unsigned int __data_start;
extern unsigned int __data_end;
extern unsigned int __bss_start;
extern unsigned int __bss_end;
extern unsigned int __heap_start;
//extern void *__malloc_heap_start; --> apparently already declared as char*
//extern void *__malloc_margin; --> apparently already declared as a size_t
extern void *__brkval;