PDA

View Full Version : Teensy 3.0 Memory Map



firelizzard
11-27-2012, 11:41 PM
As far as I can tell, the actual memory map is as follows:

Type (len): start address in hex
-------------------------------
Flash (128K): 0000,0000
FlexNVM (32K): 1000,0000
FlexRAM (2K): 1400,0000
SRAM (16K): 1FFF,E000
Bitband (256K): 2200,0000

The Flash and SRAM sections make sense as far as the specs go (128K Flash, 16K RAM, 2K EEPROM). The length of the FlexRAM suggests that it is the 'EEPROM'. Since the Bitband is actually the SRAM_U Bitband, it's length makes sense (8K * 32).
For those who don't know, the Bitband is a specially address space. It is aliased to the upper half of the SRAM (starting at 2000,0000, 8K in length). However, it is not byte-for-byte aliased. Every 32-bit location in the Bitband is aliased to a single bit in the upper SRAM. Setting or clearing the least significant bit of the Bitband location sets or clears the corresponding bit of the upper SRAM. The upper 31 bits of Bitband locations is unused.
My question is, what are FlexNVM and FlexRAM? Are there actual 32K and 2K blocks of memory on the chip? Are they aliased to Flash, to SRAM, somewhere else?

P.S.: Here's a memory map with ranges
Type: Start - End
Flash: 0000,0000 - 0001,FFFF
FlexNVM: 1000,0000 - 1007,FFFF
FlexRAM: 1400,0000 - 1400,07FF
SRAM_L: 1FFF,EFFF - 1FFF,FFFF
SRAM_U: 2000,0000 - 2000,3FFF
Bitband: 2200,0000 - 2203,FFFF

PaulStoffregen
11-28-2012, 12:28 AM
The FlexNVM is 32k of flash memory. It's separate from the 128K of flash used for the main program.

The FlexRAM is 2k of RAM. It's separate from the 16K of normal RAM used for program variables.

The chip can emulate a 2k EEPROM using both the FlexNVM and FlexRAM. The EEPROM library uses the chip this way. Both FlexNVM and FlexRAM are consumed to emulate the EEPROM. The hardware implements a wear leveling algorithm, so you get EEPROM-like write endurance by trading off the size. By default, the EEPROM library configures for 2k. If you edit the code, you can set it for less memory, which gives higher write endurance. If you care are write endurance while using the EEPROM, the hardware is designed to maximize endurance for 16 or 32 bit writes. If you write as 8 bit bytes, the write endurance is halved.

Even if you configure for a smaller EEPROM size, the hardware wear leveling uses the entire FlexRAM. None of the 2k can be used in EEPROM, even if the wear leveling is implementing only a 256 byte EEPROM.

It's also possible to configure the chip so the 2k of FlexRAM is available as ordinary RAM. Of course, the EEPROM emulation doesn't work in that mode because it depends on using the FlexRAM.

It's possible, when not using the FlexNVM for EEPROM to use it for data storage, with the caveat that the write size is 1K blocks and the write endurance isn't high. If you want to store relatively static data that never changes, or won't change very often, it can be useful because you get much more space than using it as EEPROM.

It's also possible, as if this wasn't already enough options, to use part of the FlexNVM as flash (1k blocks, low write endurance) and part as the storage for emulating EEPROM. The EEPROM library only supports using the entire FlexNVM for EEPROM storage, but it could be modified to partition the FlexNVM differently. Keep in mind a higher ratio of EEPROM to FlexNVM storage means lower write endurance because there's less memory for the wear leveling to spread all your writes across.

There isn't currently any example or library to write to the FlexNVM when configured as flash.

pixelk
11-28-2012, 11:10 AM
Your talk about Flash wear worries me a bit. Currently the EEPROM equivalent is wiped out at each code upload, which forces me to load it back each time, writing it another time. This means those cells are overwritten a lot (I use EEPROM.write) while I write and test my code (the final project will mostly read from it). Is there any way to mitigate this problem ?

lisper
12-05-2012, 11:11 PM
As far as I can tell, the actual memory map is as follows:

Type (len): start address in hex
-------------------------------
Flash (128K): 0000,0000
FlexNVM (32K): 1000,0000
FlexRAM (2K): 1400,0000
SRAM (16K): 1FFF,E000
Bitband (256K): 2200,0000

The Flash and SRAM sections make sense as far as the specs go (128K Flash, 16K RAM, 2K EEPROM). The length of the FlexRAM suggests that it is the 'EEPROM'. Since the Bitband is actually the SRAM_U Bitband, it's length makes sense (8K * 32).
For those who don't know, the Bitband is a specially address space. It is aliased to the upper half of the SRAM (starting at 2000,0000, 8K in length). However, it is not byte-for-byte aliased. Every 32-bit location in the Bitband is aliased to a single bit in the upper SRAM. Setting or clearing the least significant bit of the Bitband location sets or clears the corresponding bit of the upper SRAM. The upper 31 bits of Bitband locations is unused.
My question is, what are FlexNVM and FlexRAM? Are there actual 32K and 2K blocks of memory on the chip? Are they aliased to Flash, to SRAM, somewhere else?

P.S.: Here's a memory map with ranges
Type: Start - End
Flash: 0000,0000 - 0001,FFFF
FlexNVM: 1000,0000 - 1007,FFFF
FlexRAM: 1400,0000 - 1400,07FF
SRAM_L: 1FFF,EFFF - 1FFF,FFFF
SRAM_U: 2000,0000 - 2000,3FFF
Bitband: 2200,0000 - 2203,FFFF

Something doesn't add up here.

First, your starting addresses for the SRAM aren't consistent. Above you say that SRAM starts at 1FFF,E000, below you say 1FFF,EFFF. I presume the latter is just a typo.

Second, 1FFF,E000 to 2000,3FFF is not 16k, it's 24k.

Finally, when I actually run a malloc test, the first address I get is always 1FFFF0A8, and I can only allocate about 12k before it dies.

So... how much RAM is there really? 12k, 16k or 24k? And if it's 16k (which is what it's supposed to be) why does there seem to be 4k of overhead? That seems mighty high.

PaulStoffregen
12-05-2012, 11:28 PM
There really is 16K of RAM, from 1FFFE000 to 20001FFF. That's not including the FlexRAM, which is typically used for EEPROM emulation.

By default, the USB code allocates 30 usb_packet_t buffers, which are 72 bytes each (64 for the packet data and 8 for managing the data), and 512 bytes for a descriptor table to manage all the endpoints. Future versions will trim these to only what's reasonable needed, depending on the USB type selected. Right now, it's hard coded to consume 2672 bytes. There also a small amount of memory used for static variables within the USB code.

Between the USB data, stack usage, and perhaps other static data, 4k of RAM used is pretty reasonable.