Memoria utilizzata

Sto cercando di risolvere un bug del mio codice, dovuto al fatto che, tra stringhe, variabili e altri buffer interni alle librerie di Arduino, tento di usare più memoria di quella disponibile. Questo porta inevitabilmente a continui reset.

Premesso che una possibile soluzione possa essere quella di spostare le stringhe nello spazio del codice, sarei curioso di sapere se esiste qualche tool per analizzare il codice prodotto e estrarre informazioni sulla memoria utilizzata.

Grazie :)

Sto cercando di risolvere un bug del mio codice, dovuto al fatto che, tra stringhe, variabili e altri buffer interni alle librerie di Arduino, tento di usare più memoria di quella disponibile. Questo porta inevitabilmente a continui reset.

allora,
alcuni compilatori, se ben istruiti, sono in grado di dirti se hai superato anche il limite di ram, ma quando ci si trova in condizioni critiche come le tue, la cosa migliore è sempre quella di dichiarare le variabili apponendo un remark (//) che ti ricorda il progressivo in byte utilizzato, ad esempio:

char aa[] = "0123456789"; //=10b
char bb[8]; //=18b

ecc.

Il problema maggiore però è nell’uso dello stack interno, che non gestisci direttamente tu ma il programma a seconda delle chiamate alle routine, ovvero: quando chiami una funzione il programma inserisce nello stack 2 byte di indirizzo + gli eventuali necessari per il passaggio dei parametri.
Come ben capirai questo vuol dire che se chiami una funzione e all’interno ne chiami un’altra le due si sommano nello stack (e lo stack è nella memoria che usi anche tu!).

Poi, cosa più probabile nel tuo caso, c’è il tranello della ricorsione tra funzioni, ovvero: quando una funzione richiama se stessa… e allora li il consumo della ram è infinito (cosa quindi da evitare proprio perchè vengono modificati gli indirizzi di ritorno delle funzioni e il programma modifica il suo flusso, provocando apparenti reset casuali come nel tuo caso).

Se poi hai proprio necessità di utilizzare più ram (effettivamente qui ne abbiamo pochina), sei obbligato a scegliere due strade:
Prima di tutto a mettere tutte le stringhe non variabili (le label, messaggi, ecc) nella memoria di programma (se guardi nella documentazione di arduino ti spiegano come fare), la seconda è quella di utilizzare un piccolo ic esterno con il collegamento seriale i2c, ne esistono di diversa capacità in commercio, sono semplici da implementare anche se certamente lente nell’uso.
Dipende tutto da quello che devi fare.

Comunque ricorda che il miglior sistema di debug è quello di documentare il più possible il codice (tanti rem, e dove necessario anche uno in ogni riga). Ti aiuta a ragionare e ti semplifica la vita se vuoi riutilizzarlo o modificarlo a distanza di tempo (oltre al fatto che consente ad altri di collaborare con te più facilmente).
Ciao

Grazie, è proprio quello che sto cercando di fare ora.

Non è un problema di chiamate ricorsive comunque (non ne uso) e la profondità dello stack è piuttosto limitata (almeno per quanto riguarda le mie funzioni).

Il progressivo in byte però è proprio scomodo perchè si presta poco alle modifiche: sto provando a documentare il consumo individuale delle singole variabili che poi lo raccolgo con un preprocessore. Un tool già esistente sarebbe però molto comodo.. nn è possibile estrarre queste informazioni da .hex o da qualche altro file intermedio prodotto da arduino? (.elf, .o, ...)

Ciao!

si

se fai girare avr-size sul file .elf ti da una spiegazione della memoria usata

esempio
text data bss dec hex filename
4218 22 172 4412 113c example.elf

qui c’è la spiegazione di cosa vogliono dire i parametri
http://www.nongnu.org/avr-libc/user-manual/mem_sections.html

considera che se gli passi il file .rom vedi valori diversi e questo credo che sia il risultato delle ottimizzazioni

massimo

PS finalmente un po di italiani :slight_smile:

Ah grazie! Stavo provando con avr-readelf ma avr-size è decisamente più comodo, soprattutto perché da le dimensioni già in decimale :)

Il file rom in effetti è diverso, ha solo solo il segmento .data con dimensioni leggermente minore alla somma dei tre segmenti del file .elf. Immagino che comunque le ottimizzazioni siano sulla parte .text.

Arduino invece riporta una dimensione diversa (minore).. com'è calcolata?

Bastava seguire quel link e leggere ^^ In un eccesso di felicità ho postato prima di farlo ^^

Arduino riporta .text + .data