Holmes: Querida, ¿no me digas dónde estamos?
Pastor: ¡Estás en un globo!
Holmes: Debes ser un programador.
Pastor: Sí, pero ¿cómo lo adivinaste?
Holmes: Solo un programador podría dar una información tan precisa y
con una respuesta tan inútil.
... extracto de una broma famosa
Si alguna vez programó para un microcontrolador, no importa usar el IDE de Arduino o trabajar directamente con un compilador para AVR, ARM o ESP, probablemente haya visto informes de finalización de compilación como
Sketch uses 1,090 bytes (3%) of program storage space. Maximum is 30,720 bytes.
Global variables use 21 bytes (1%) of dynamic memory, leaving 2,027 bytes for local variables. Maximum is 2,048 bytes.
text data bss dec hex filename
52136 1148 12076 65360 ff50 MyProject
… , . , , . new malloc . . , .
,
. , . – .
( – , C++). .
, 3 :
- – : ,
- (heap) – , ( ) . malloc new
- – , .
. Arduino IDE Arduino Nano.
( ). , .
Global variables use 21 bytes (1%) of dynamic memory, leaving 2,027 bytes for local variables. Maximum is 2,048 bytes.
.
int * buf;
void setup()
{
buf = new int[3000];
}
void loop() {}
. , . , . ,
, , . . ?
, , ! , 2, 3000 2 . . , , - . , … , .
? . , , . ?
.
int buf[300];
void setup()
{
buf[0] = 1; //Avoid optimizing this array
}
void loop()
{
}
300*2=600 , . , , objdump (, , Arduino IDE )
cd C:\Users\GrafAlex\AppData\Local\Temp\arduino_build_55567
"C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-objdump.exe" -x -D -S -s StaticMem.ino.elf
…
00800100 l O .bss 00000258 buf
…
0x00800100 , , 0x258 (600 ).
3000 . «»
Sketch uses 456 bytes (1%) of program storage space. Maximum is 30,720 bytes.
Global variables use 6,009 bytes (293%) of dynamic memory, leaving -3,961 bytes for local variables. Maximum is 2,048 bytes.
...
Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.
, – , .
, . , , . , – , /, . , ( ).
// static. – cpp .
static int buf[300];
void setup()
{
buf[0] = 1; //Avoid optimizing this array
}
cpp , extern, .
extern int buf[300];
void foo()
{
buf[0]++;
}
, buf
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/main.cpp:47: undefined reference to `buf'
buf static, cpp
!
static int buf[300];
void foo()
{
buf[0]++;
}
objdump
0080036a l O .bss 00000258 _ZL3buf.lto_priv.12
00800112 l O .bss 00000258 _ZL3buf.lto_priv.13
namespace
namespace , . .
namespace
{
int buf[300];
}
.
class A
{
static int buf[300];
public:
int * getBuf()
{
return buf;
}
};
int A::buf[300];
void setup() {}
void loop()
{
A a;
a.getBuf()[0] += 1;
}
, A ( , loop()), . , .
00800100 l O .bss 00000258 A::buf
, , .
int getCounter()
{
static int counter = 0;
return ++counter;
}
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.println(getCounter());
}
counter . getCounter(),
00800116 l O .bss 00000002 getCounter()::counter
( ) , «» — getCounter() .
.
int * getBuf()
{
static int buf[300];
return buf;
}
C++ , buf getBuf(), , .bss ( , ).
int * getBuf()
{
static int buf[300] = {1, 2, 3};
return buf;
}
, 600 , .
class Buf
{
public:
int buf[300];
Buf(int v)
{
buf[1] = v;
}
};
int * getBuf()
{
static Buf buf(1234);
return buf.buf;
}
, - getBuf(). AVR (ATMega) , . , .. , getBuf(), .
ARM (, STM32) . 60 . , ARM ++ ( getBuf()).
, , ? undefined behavior, g++
recursive_init_error. , , . ( 60), .
– -fno-threadsafe-statics, , , .
,
— , . , .
class Singleton
{
int buf[300];
public:
static Singleton & getInstance()
{
static Singleton instance;
return instance;
}
int * getBuf()
{
return buf;
}
};
void setup()
{
Serial.begin(9600);
Singleton::getInstance().getBuf()[42] = 10;
}
void loop()
{
Serial.println(Singleton::getInstance().getBuf()[42]);
}
— , . , / // . .
00800116 l O .bss 00000258 Singleton::getInstance()::instance
, buf . instance, . objdump . Singleton buf , objdump .
,
. .
, , . ARM (STM32, nRF, NXP) ESP8266 ( «» ). AVR ( Arduino ), 1-4. MCS51, .
(new, malloc), ( STM Cube, Arduino), , .
, . , .
. . , .
, . , .
. . .
UPD:
FreeRTOS