Il sito per chi ama smanettare con Arduino, Raspberry Pi & Co.
Ottimizzare l’utilizzo della SRAM  di Arduino

Ottimizzare l’utilizzo della SRAM di Arduino

by

La RAM su Arduino può essere considerata come un bene prezioso! Impariamo ad usarla meglio.

Essendo l’ottimizzazione della RAM una procedura molto importante quando i nostri progetti arduino iniziano ad aumentare di dimensione vi proponiamo un nuovo articolo proprio per imparare ad ottimizzare l’utilizzo della memoria RAM della nostra scheda.

L’articolo praticamente è una traduzione in italiano di un tutorial di Adafruit, il link lo trovate a fine articolo.

La RAM su Arduino può essere considerata come un bene prezioso!

Inoltre la scarsità di memoria è un problema molto comune con Arduino ed inoltre uno dei più difficile da rilevare.

Se il nostro sketch comincia a comportarsi in maniera veramente strana e inspiegabile è molto probabile che abbiamo i limiti del nostro stack di memoria disponibile.

Per fortuna si possono prendere alcuni accorgimenti durante la programmazione per ridurre l’uso di RAM e queste sono solo alcune linee guida per iniziare:

Rimuovi le variabili non utilizzate

Se non sei sicuro che una variabile venga usata o meno nel tuo codice, commentala. Se lo sketch è ancora compilabile, sbarazzati di quella variabile!

Usa la macro F() per i letterali stringa!

I letterali stringa sono delle continue perdita di RAM: prima occupano spazio nell’immagine del nostro programma nella memoria Flash poi vengono caricati allo startup come variabili statiche.

Questo è un orribile spreco di memoria quindi non dovremmo mai scriverne.

Paul Stoffregen ha sviluppato la macro F() come semplice soluzione a questo tipo di problema

La macro F() dice al compilatore di tenere le stringhe nel PROGMEM. Tutto quello che si deve fare è racchiudere i letterali stringa nella macro F().

Per esempio rimpiazzando questo:

Serial.println("Sram sram sram sram. Lovely sram! Wonderful sram! Sram sra-a-a-a-a-am sram sra-a-a-a-a-am sram. Lovely sram! Lovely sram! Lovely sram! Lovely sram! Lovely sram! Sram sram sram sram!");

con questo:

Serial.println(F("Sram sram sram sram. Lovely sram! Wonderful sram! Sram sra-a-a-a-a-am sram sra-a-a-a-a-am sram. Lovely sram! Lovely sram! Lovely sram! Lovely sram! Lovely sram! Sram sram sram sram!"));

Risparmieremo ben 180 bytes di SRAM!

Usa la funzione reserve() per le stringhe

La libreria delle stringhe di Arduino ci permette di riservare lo spazio di buffer necessario per le stringhe con la funzione reserve() .

L’intento è quello di prevenire la frammentazione dell’heap al crescere della dimensione delle stringhe che crescono di dimensione durante l’esecuzione del programma pre-allocando loro la memoria di cui necessitano.

Con la memoria già allocata le stringhe non necessitano di chiamare la funzione realloc() se crescono in lunghezza.

In molti casi, molti altri piccoli oggetti stringa vengono creati temporaneamente mentre li si utilizza, forzando l’allocazione della memoria di una nuova stringa in una nuova area dell’heap e lasciando un grosso buco dove la precedente era stata allocata creando così il fenomemo della frammentazione della memoria.

Per prevenire questo è una buona pratica utilizzare la funzione reserve() su ogni oggetto stringa che utilizzeremo più volte nel programma e che sappiamo potrebbe crescere di dimensioni.

Si potrebbe fare meglio con le stringhe C ma già con queste linee guida si hanno degli ottimi risultati senza tanta difficoltà.

Spostare i dati costanti nel PROGMEM.

I dati dichiarati con PROGMEM non vengono copiati allo startup dello sketch nella SRAM.

E’ un po’ più difficile lavorarci ma si può risparmiare molta memoria.

I riferimenti ufficiali Arduino a PROGMEM si possono trovare qui, un tutorial più esustivo sullargomento qui.

Riduci la dimensione dei buffers

Allocazione di Buffer e Array :
Se allocate un buffer non allocatelo più grande di quel che serve.

Buffers nelle librerie:
Controllate i buffer allocati dalle librerie sono dei buoni candidati ad una “ritaratura”.

Buffers di sistema:
Un altro buffer nascondo nel profondo del sistema è il buffer della seriale di 64 caratteri per la ricezione. Se il nostro sketch non dialoga molto velocemente con la seriale si può probabilmente ridurre a metà o anche meno.

La dimensione del buffer è definita nel file HardwareSerial.cpp. Questo file può essere trovato nella directory di installazione di arduino:

….\Arduino-1.x.x\hardware\arduino\cores\arduino\HardwareSerial.cpp

Cerca la linea:

#define SERIAL_BUFFER_SIZE 64

E cambialo a 32 o meno.

Riduci la dimensioni delle variabili troppo grandi

Non usare un float quando un int va bene, non usare un int qunado basta un byte. Prova sempre ad utilizzare il più piccolo tipo di dati possibile capace di contenere l’informazione.

learn_arduino_DataTypes.jpg

Pensa Globalmente. Alloca localmente.

Diamo un’altra occhiata a come la SRAM viene usata in Arduino (e abusata):

learn_arduino_Stack_Operation.gif

Variabili Globali e Statiche

Le variabili globali e e le variabili statiche sono la prime cose che vengono caricate nella SRAM. Spingeranno l’inizio dell’heap di memoria su verso la zona dello stack e occuperanno questo spazio per tutta la vita dello sketch.

Allocazione dinamica

Gli oggetti e i dati allocati dinamicamente forzano la crescita dell’heap verso lo stack.

Diversamente dalle variabili statiche e globali queste variabili possono essere de-allocate per liberare spazio di memoria.

Ma questo non significa che l’heap a sua volta diminuisca! Se ci sono altri dati dinamici più in alto nell’heap, il punto più alto dell’heap non verrà modificato. Quando l’heap è pieno di buchi lo chiamiamo “heap frammentato”.

Variabili locali

Ogni chiamata a funzione crea uno stack frame che farà crescere lo stack di memoria in basso verso l’heap. Ogni stack frame contiene:

  • Tutti i parametri passati alla funzione
  • Tutte le variabili locali dichiarate nella funzione.

Questi dati sono utilizzabili all’interno della funzione, ma lo spazio è utilizzato lo stesso al 100% da quando la funzione esiste!

Quindi?

  • Evita l’allocazione dinamica dell’heap – Si può facilmente frammentare il poco spazio per l’heap.
  • Preferisci allocazioni locali a quelle globali – Le variabili conservate nello stack esistono solo quando vengono usate. Se si hanno variabili che si utilizzano solo in piccole porzioni di codice è bene considerare di far girare quel codice dentro una funzione per dichiarare le variabili dentro la funzione.

Fonte: https://learn.adafruit.com/memories-of-an-arduino/optimizing-sram

Buona Ottimizzazione!

Spread the love
  • 14
  •  
  •  
  •  
  •  
  •  
  •  
  •  
    14
    Shares

Ti è rimasta una domanda o un dubbio?

Iscriviti e chiedi nella community

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *