Pages: 1 2 3 [4]   Go Down
Author Topic: Verificare SRAM utilizzata  (Read 2293 times)
0 Members and 1 Guest are viewing this topic.
Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Come ulteriore riscontro al test fatto da Leo ecco un semplicissimo sketch che dimostra al di la di ogni dubbio che avr-gcc consente la ricorsività delle funzioni ed è abbastanza intelligente da non riempire lo stack.
Lo sketch conta da 0 a 10001 usando una funzione ricorsiva, l'uscita è determinata da una if e una return, i valori vengono inviati al monitor seriale e alla fine delle iterazioni viene ceduto il controllo al main loop che fa lampeggiare un led a dimostrazione che non c'è stato nessun stack overflow.

Code:
long iter = 0;
void setup()
{
  Serial.begin(115200);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  recurse();
  Serial.println("fine iterazioni");
}

void loop()
{
 digitalWrite(13, HIGH);
 delay(100);
 digitalWrite(13, LOW);
 delay(100);
}

void recurse(void)
{
 iter++;
 Serial.println(iter,DEC);
 if (iter > 10000)
   {
    iter = 0;
    return;
   }
 recurse();
}
Logged

Offline Offline
Sr. Member
****
Karma: 7
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

qua non abbiamo 2k ma 8... in pratica anneghiamo in un mare  smiley-roll di ram che non usiamo
Guarda che gli Atmega328 hanno solo 2 kB di RAM, l'ho scritto diverse volte.


 pensavo che si parlasse del  Atmega2560 con 8k. comunque mi permane il dubbio di come faccia a farsi 'ste funzioni ricorsive senza toccare lo stack... deve essere un barbatrucco non da poco.
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9185
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

comunque mi permane il dubbio di come faccia a farsi 'ste funzioni ricorsive senza toccare lo stack... deve essere un barbatrucco non da poco.

La cosa è molto più semplice di quelli che pensi, in realtà il compilatore si rende conto che c'è una ricorsività e la gestisce in modo opportuno senza incrementare lo stack ad ogni iterazione.
Se provi a fare un ricerca con argomento "tail call" e "tail recursive" trovi tutte le spiegazioni del caso.
Logged

Offline Offline
Sr. Member
****
Karma: 7
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Se provi a fare un ricerca con argomento "tail call" e "tail recursive" trovi tutte le spiegazioni del caso.


vedo... grassie...
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21650
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

In allegato trovate un piccolo sketch che stampa alcune info sull'allocazione della SRAM del microcontrollore.

La memoria SRAM viene suddivisa in 5 pezzi:
1) all'inizio della SRAM viene messa l'area .data, che contiene le variabili dichiarate nel programma
2) dopo c'è l'area .bss/.init: essa contiene le variabili non inizializzate
3) a seguire c'è l'HEAP, che contiene i dati per l'allocazione dinamica della memoria. L'HEAP cresce verso l'alto.
4) dopo l'HEAP c'è un'area vuota che funge da "materasso"
5) infine c'è lo STACK, collocato a partire dall'ultima locazione di memoria a crescere verso il basso, verso l'HEAP. Nello STACK ci vanno a finire non solo i punti di ritorno per i salti alle subroutine ma anche i registri di sistema durante le ISR nonché le variabili create localmente.

Sia lo STACK che l'HEAP si espandono nell'area materasso. Se queste 2 aree vengono a collidere sovrapponendosi, il micro crasha.
La memoria libera che lo sketch calcola è data dall'area compresa fra l'inizio dell'HEAP e l'inizio dello STACK.

Ovviamente potete inserire questo sketch in un vostro programma, ma anche infarcirlo di altre funzioni per vedere come i vari puntatori variano.

La funzione più importante è freeRam, pubblicata da JeeLabs, che può essere estrapolata per essere utilizzata in un proprio sketch.

Buonanotte   smiley-wink

* know_your_sram.ino (1.87 KB - downloaded 6 times.)
Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21650
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi sono dimenticato di precisare una cosa.
Se avete lanciato lo sketch, avrete visto che la SRAM inizia all'indirizzo $100. Questo perché in realtà un microcontrollore possiede 256 byte ($100) di RAM in più, che però usa per le sue necessità: nei primi 160 256 byte vengono infatti salvati i registri interni del microcontrollore ed i registri che controllano le linee di I/O. Poi inizia la RAM destinata ai dati del programma, che parte da $100 appunto e termina a $RAMEND, che varia a seconda del micro. Nel caso dell'Atmega328, che ha 2048 ($800) byte di RAM disponibile per i dati, la fine è a ($100+$800-$1)=2303 ($8FF). Questo indirizzo rappresenta anche la cella più alta dello STACK.

Ecco l'output del mio Arduino UNO:
Code:
SRAM and .data space start: 256 $100
.data space end/.bss start: 456 $1C8
.bss space end/HEAP start: 641 $281
HEAP end: 654 $28E
STACK start: 2241 $8C1
STACK and SRAM end: 2303 $8FF
Free memory at the moment: 1600 $640

Questo invece l'output della mia Leonardo:
Code:
SRAM and .data space start: 256 $100
.data space end/.bss start: 482 $1E2
.bss space end/HEAP start: 601 $259
HEAP end: 614 $266
STACK start: 2753 $AC1
STACK and SRAM end: 2815 $AFF
Free memory at the moment: 2152 $868
Qui ci sono 512 byte di memoria in più (2303+512=2815).
« Last Edit: November 23, 2012, 10:39:17 am by leo72 » Logged


0
Offline Offline
Faraday Member
**
Karma: 24
Posts: 2814
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Provato anche io su ATmega 644A, funziona.

Ho dovuto modificare tutti gli int in unsigned int perché sto usando utoa per convertire il numero in stringa, potrei usare itoa se ci sono controindicazioni, ma al momento mi sembra funzioni alla perfezione.

Ciao.
Logged

AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 104
Posts: 6616
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

x iscrizione
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21650
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Provato anche io su ATmega 644A, funziona.

Ho dovuto modificare tutti gli int in unsigned int perché sto usando utoa per convertire il numero in stringa, potrei usare itoa se ci sono controindicazioni, ma al momento mi sembra funzioni alla perfezione.

Ciao.

La cosa è ininfluente, tanto un indirizzo non sarà mai negativo per cui int o unsigned int sempre quello è.
Logged


Pages: 1 2 3 [4]   Go Up
Jump to: