Memory management: flash, eeprom, ram

published: 10 December 2019 / updated 11 December 2019

Lire cette page en français

 


Memory organisation

There are three pools of memory in the microcontroller used on avr-based Arduino boards:

Flash memory and EEPROM memory are non-volatile (the information persists after the power is turned off). SRAM is volatile and will be lost when the power is cycled.

The ATmega328 chip found on the Uno has the following amounts of memory:

Flash32k bytes
SRAM2k bytes
EEPROM1k byte

The ATmega2560 in the Mega2560 has larger memory space:

Flash256k bytes
SRAM8k bytes
EEPROM4k byte
Organisation des différentes sectrion mémoire

The word HERE

The word here indicates the available memory address according to the memory context selected by the words flash, eeprom or ram.

We create a little word that will tell us at any time the state of the memory pointers:

: .memory ( ---) 
    cr ."  flash: "   flash  here u. 
    cr ." eeprom: "   eeprom here u. 
    cr ."    ram: "   ram    here u.  
    cr ; 

Using flash memory

flash memory space is automatically used by the FORTH language and the FORTH words that you define.

Except variables and other data explicitly stored elsewhere than in flash memory.

Words defined by : are automatically stored in flash memory:

-tests 
marker -tests 
.memory 
\  flash: 12942 
\ eeprom: 8716 
\    ram: 1250 
: test.loop  
    100 for r@ . next ; 
.memory 
\  flash: 12990 
\ eeprom: 8716 
\    ram: 1250 

We see that the value delivered by here for memory flash changed from 12942 to 12990, an increase of 48 bytes.

For some types of data, you can force storage in flash memory:

-tests 
marker -tests 
.memory 
\  flash: 12942 
\ eeprom: 8716 
\    ram: 1250 
flash 
create LIMIT 
    10 , 
.memory 
\  flash: 12958 
\ eeprom: 8716 
\    ram: 1250 

The word LIMIT marks a flash memory location whose contents can be retrieved:

LIMIT 
\ display 12956 
@ 
\ display 10 

If we reserve a memory zone whose contents are often changed, we must it is imperative to use another space than the flash memory.

All data stored in flash memory is retained after the shutdown ARDUINO card voltage.

Using ram memory

Ram memory should be used for variables whose value changes very often:

-tests 
marker -tests 
.memory 
\  flash: 12942 
\ eeprom: 8716 
\    ram: 1250 
ram 
create BUFFER 
    256 allot 
.memory 
\  flash: 12958 
\ eeprom: 8716 
\    ram: 1506 

The word BUFFER is created in the flash memory, but the 256 bytes buffer are reserved in ram memory:

BUFFER 
\ display 1250 

Running the word BUFFER displays the address of the beginning of the buffer of 256 bytes reserved in RAM memory.

We will store in memory ram all the variables whose value will evolve in time.

All data stored in ram memory is lost after being put out ARDUINO card voltage.

Using eeprom memory

The eeprom memory is faster to access than the flash memory. Just like this memory flash is a non-volatile memory.

The eeprom memory is ideal for storing tables of data without cluttering the flash memory:

-tests 
marker -tests 
.memory 
\  flash: 12942 
\ eeprom: 8716 
\    ram: 1250 
eeprom 
create SMILEYsprite ( --- addr) 
    %00000000 c,    %00000000 c, 
    %00000000 c,    %00000000 c, 
    %00000000 c,    %00000000 c, 
    %00000000 c,    %00000000 c, 
    %00100000 c,    %01000010 c, 
    %10000010 c,    %10011000 c, 
    %10011000 c,    %10000010 c, 
    %01000010 c,    %00100000 c, 
    %00000000 c,    %00000000 c, 
    %00000000 c,    %00000000 c, 
    %00000000 c,    %00000000 c, 
    %00000000 c,    %00000000 c, 
ram 
.memory 
\  flash: 12964 
\ eeprom: 8740 
\    ram: 1250        

We see that the pointer for the eeprom memory has changed from 8716 to 8740, an increase of 24 bytes.

Running SMILEYsprite shows the address in memory eeprom of the first byte of the placeholder where the description of the smiley sprite was stored.

To access the other bytes, simply increment this address the value corresponding to this memory position:

SMILEYsprite ( --- addr) 
    5 + c@ 

accesses the 5th octet after the address stacked by executing SMILEYsprite.

Memory selection in interpretation / compilation

At any time, while compiling a source code, you can change the memory context depending on the type of data to compile.

This selection should preferably be in interpretation. Example:

\ PORTB 
37 constant PORTB	\ Port B Data Register 
36 constant DDRB	\ Port B Data Direction Register 
\ 35 constant PINB	\ Port B Input Pins - unused 
 
: defRELAY: ( PORTx mask ---  |  --- mask port) 
    create 
        flash 
        , ,             \ compile PORT and min mask 
        ram 
    does> 
        dup @           \ push pin mask 
        swap 2+ @       \ push PORT 
    ; 

... is not a good solution!

Here, the selection eeprom is done in the word defRELAY: between create and does>.

Here is the recommended solution:

: defRELAY: ( PORTx mask ---  |  --- mask port) 
    create 
        , ,             \ compile PORT and min mask 
    does> 
        dup @           \ push pin mask 
        swap 2+ @       \ push PORT 
    ; 
 
\ definition RELAYx 
flash 
PORTB %00000001 defRELAY: RELAY1 
PORTB %00000010 defRELAY: RELAY2 
PORTB %00000100 defRELAY: RELAY3 
PORTB %00001000 defRELAY: RELAY4 
ram 

Here, the selection flash occurs before the definition of words RELAY1 to RELAY4.