Go Down

Topic: Arduino UNO: RAM occupata da sketch (Read 3209 times) previous topic - next topic

Nik_90

Ciao a tutti, credo di avere un problema con la RAM disponibile di un programma che sto scrivendo per Arduino, premetto che non ho fatto ancora pulizia di un sacco di variabili che stanno li senza essere utilizzate magari, oppure di Serial.print che ho visto che vengono allocate in memoria quindi se non servono vanno tolte dopo il debug. Volevo comqune sapere se esiste un modo di controllare la RAM disponibile di arduino durante l'esecuzione di uno sketch, magari tramite qualche libreria e l'uso di serial.print così da vedere l'effettivo consumo di RAM
Spero di aver reso l'idea..:)

Spero in un vostro aiuto:)

Saluti

Nicola

brunialti

Usa la funzione seguente:

Code: [Select]

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
  }


Ti da la ram disponibile, che è probabilmente quella che si esaurisce prima della progmem.

PaoloP

La funzione FreeRam() è anche definita nella libreria SdFarUtil.h che fa parte della libreria SD.
Code: [Select]
#define UNUSEDOK __attribute__((unused))
//------------------------------------------------------------------------------
/** Return the number of bytes currently free in RAM. */
static UNUSEDOK int FreeRam(void) {
  extern int  __bss_end;
  extern int* __brkval;
  int free_memory;
  if (reinterpret_cast<int>(__brkval) == 0) {
    // if no heap use from end of bss section
    free_memory = reinterpret_cast<int>(&free_memory)
                  - reinterpret_cast<int>(&__bss_end);
  } else {
    // use from top of stack to heap
    free_memory = reinterpret_cast<int>(&free_memory)
                  - reinterpret_cast<int>(__brkval);
  }
  return free_memory;
}


Inoltre per i Serial.print usa la funzione F() [con l'IDE 1.0 o 1.0.1], in questo modo:
Code: [Select]
Serial.print(F("quello che vuoi stampare"));

Nik_90

Allora ho provato ad utilizzare questa funzione, creando un'intero (es: int memoria_disp) e chiamando questa funzione e dopo stamparla su seriale, mi viene stampato un  numero intorno al 700.. Significa quindi che la memoria disponibile è pari a 700 byte? Se fosse così credo sia sufficiente ..

Grazie mille


Usa la funzione seguente:

Code: [Select]

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
  }


Ti da la ram disponibile, che è probabilmente quella che si esaurisce prima della progmem.

testato

si, e' 700 byte liberi, il tuo programma sta usando 1,3 KB dei 2 disponibili

pero' attenzione a quale punto usi per stampare il freeRam, se ad esempio lo metti nl setup, potrebbe essere che il rpogramma in fasi successive, nel loop, vada sotto.
Metti la stampa in piu' punti
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

brunialti

Si, in teoria bisognerebbe metterla nella "deepest nested call", cioè nella funzione chiamata a livello più basso.
Il valore viene influenzato da: parametri di chiamata di una funzione (meglio è passare pountatori invece di oggetti), valori di ritorno (come sopra), variabili non static all'interno delle funzioni ed ovviamente da eventuali esplicite allocazioni di memoria (p.es. malloc)

cyberhs

Caro Brunialti,

ho provato la funzione freeRam e funziona perfettamente: da tempo cercavo qualcosa del genere!

Le mie limitate conoscenze del C, però, non mi fanno capire il significato del "'?" e del ":" dell'ultima riga.

Me le puoi spigare per favore?

Ettore Massimo Albani

Nik_90


Caro Brunialti,

ho provato la funzione freeRam e funziona perfettamente: da tempo cercavo qualcosa del genere!

Le mie limitate conoscenze del C, però, non mi fanno capire il significato del "'?" e del ":" dell'ultima riga.

Me le puoi spigare per favore?

Ettore Massimo Albani


Ciao, si tratta di un'operatore condizionale, diciamo che effettivamente rende il codice abbastanza ostico, ma (credo) abbia le stesse caratteristiche del costrutto if - else.

Si costruisce così

?espressione1 ? espressione2 : espressione 3;

Praticamente viene prima valutata espressione1, se è vera allora viene presa in considerazione espressione2 che diventa il risultato, se invece espressione1 risulta falsa viene presa in considerazione espressione3.

Quindi una riga del genere:
Code: [Select]
max = (x > y)? x: y; 

equivale a:

Code: [Select]

if(x > y)
max = x;

else max = y;



Spero di aver espresso bene il concetto! :)

Saluti

Nicola

cyberhs


Go Up