AVR 的 __brkval 是什么,它在哪里定义?
What is __brkval for AVR, and where is it defined?
我在https://playground.arduino.cc/Code/AvailableMemory中看到了freeMemory
函数,它似乎使用了一个叫做__brkval
的东西。但是,我根本找不到这个宏或变量定义在哪里:
$ 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
也就是说,只有Arduino IDE有一些引用,但只是作为extern int*
引用,没有定义。
最接近我的某种冗长解释来自 https://github.com/greiman/SdFat/blob/master/src/FreeStack.h :
/** boundary between stack and heap. */
extern char *__brkval;
...但同样,没有定义。
那么这个变量或者宏是在哪里定义的呢?
编辑:根据评论,搜索所有文件:
$ 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);
还有很多人有同样的问题。正如所指出的那样,用最简单的术语来说,它用于标记堆栈和堆内存之间的边界。以下是一些相关讨论,内容包括 __brkval
:
- Arduino: Question about memory allocation analysis。
- Free Memory Questions, Arduino。
- Arduino:You know you have a memory problem when...。
- AVRGCC: Monitoring stack usage。
- Arduino Playground: CorruptArrayVariablesAndMemory。
最后的 link 解决了您的主要问题,至少对于 Arduino 环境而言:
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;
我在https://playground.arduino.cc/Code/AvailableMemory中看到了freeMemory
函数,它似乎使用了一个叫做__brkval
的东西。但是,我根本找不到这个宏或变量定义在哪里:
$ 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
也就是说,只有Arduino IDE有一些引用,但只是作为extern int*
引用,没有定义。
最接近我的某种冗长解释来自 https://github.com/greiman/SdFat/blob/master/src/FreeStack.h :
/** boundary between stack and heap. */
extern char *__brkval;
...但同样,没有定义。
那么这个变量或者宏是在哪里定义的呢?
编辑:根据评论,搜索所有文件:
$ 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);
还有很多人有同样的问题。正如所指出的那样,用最简单的术语来说,它用于标记堆栈和堆内存之间的边界。以下是一些相关讨论,内容包括 __brkval
:
- Arduino: Question about memory allocation analysis。
- Free Memory Questions, Arduino。
- Arduino:You know you have a memory problem when...。
- AVRGCC: Monitoring stack usage。
- Arduino Playground: CorruptArrayVariablesAndMemory。
最后的 link 解决了您的主要问题,至少对于 Arduino 环境而言:
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;