-
Notifications
You must be signed in to change notification settings - Fork 5
Memory Mapping
Here some information about how the various Teensies utilize the available on- and off chip memory, how you can specify which part of the memory to use and how to handle sketches with high memory demand.
The Teensy LC and all of the Teensy 3.x boards have a very simple memory model: There is a single block of flash and a single block of RAM memory. The size of RAM and flash depend on the board type. For all boards the flash memory starts at address 0x0000'0000. The image below shows the flash and RAM sizes and the respective start/end addresses.
Please note: the processors used on the T3.x boards distinguish between a low (< 0x1FFF'FFFF) and high (> 0x1FFF'FFFF) part of the RAM. Usually this splitting has no consequences. However, in rare cases it can generate weird alignment errors if the linker places a variable across the bank border (see here for more information on this issue).
For the T-LC and T3.x boards, both, RAM and flash memory are part of the processor and can be accessed very quickly. The maximum wait cycles to access RAM is 2 cycles (for consecutive reads the processor often can access the RAM without any wait cycle). Data from the flash can be read with maximal 4 wait cycles.
to be described
to be described
The linker will place different objects, like constants, variables, code etc. into various locations in the given memory. (For those, interested in technical details, these locations are defined in so called linker scripts. Here for example the one for the T3.2 and here the script for the T4.1)
Global variables are variables defined outside of any functions, static variables are defined inside a function. Here some examples.
int i; // global variable (uninitalized)
double x = 42; // global variable (uninitalized)
void setup(){
static int k;
}
void loop(){
}
The linker places such variables at a fixed location in the RAM. This location, is determined at link-time and can not change at runtime.
If you want to have a closer look yourself, you can use the MemoryTool
which
consists of the two files MemoryTool.h
and MemoryTool.cpp
and can be
downloaded from here: https://github.com/luni64/TeensyHelpers.
int i; // global variable (uninitalized)
double x = 42; // global variable (initalized)
void setup(){
static int k; // static variable, stored in the same place as global variables
while (!Serial) {} // wait until the pc connected
printMemoryInfo(i); // print info about the variables
printMemoryInfo(x);
printMemoryInfo(k);
}
void loop(){
}
For a T3.6 this prints:
i
Start address: 0x1FFF'11EC
End address: 0x1FFF'11EF
Size: 4 Bytes
Location: RAM (not initialized)
x
Start address: 0x1FFF'0738
End address: 0x1FFF'073F
Size: 8 Bytes
Location: RAM (initialized)
k
Start address: 0x1FFF'11F0
End address: 0x1FFF'11F3
Size: 4 Bytes
Location: RAM (not initialized)
Lets see what happens if we change x
to a constant:
int i;
const double x = 42; // <== constant
void setup(){
static int k;
while (!Serial) {}
printMemoryInfo(i);
printMemoryInfo(x);
printMemoryInfo(k);
}
void loop(){
}
Since one can't change a constant at runtime the linker leaves the constant in the flash as you can see in the printout below:
i
Start address: 0x1FFF'11E4
End address: 0x1FFF'11E7
Size: 4 Bytes
Location: RAM (not initialized)
x
Start address: 0x0001'08C8
End address: 0x0001'08CF
Size: 8 Bytes
Location: FLASH
k
Start address: 0x1FFF'11E8
End address: 0x1FFF'11EB
Size: 4 Bytes
Location: RAM (not initialized)
What about c-strings:
char myString[] = "This is a global c-string"; // can be changed at runtime
const char myConstantString[] = "I'm constant"; // can not be changed
void setup()
{
while(!Serial){}
char myLocalString[] = "Local c-string";
printMemoryInfo(myString);
printMemoryInfo(myConstantString);
printMemoryInfo(myLocalString);
}
void loop(){
}
Here the printout which shows that if you want to place a string in the flash, all you need to do is declaring it const.
myString
Start address: 0x1FFF'0734
End address: 0x1FFF'074D
Size: 26 Bytes
Location: RAM (initialized)
myConstantString
Start address: 0x0001'0908
End address: 0x0001'0914
Size: 13 Bytes
Location: FLASH
myLocalString
Start address: 0x2002'FFD0
End address: 0x2002'FFDE
Size: 15 Bytes
Location: STACK
Teensy is a PJRC trademark. Notes here are for reference and will typically refer to the ARM variants unless noted.