Go Down

Topic: Strano freeze del loop (Read 4267 times) previous topic - next topic

leo72



Ma l'hai fatto un controllo statico del consumo di memoria con avr-size oppure no?
Tanto per capire dove andiamo a cascare..


no, come si fa?

Compili lo sketch senza farne l'upload e con la modalità verbose attiva.
Nel terminale dell'IDE leggi dove sono stati creati i file temporanei del progetto e ti sposti in quella cartella.
Lì dai il comando:
Code: [Select]
avr-size -C nomeFirmware.cpp.elf

Quote


Poi hai una miriade di invocazioni ad una funzione ToSerial che altro non fa che stampare stringhe sulla seriale. Peccato che tutte quelle stringhe gliele passi dalla Ram.


si, ma solo con il define DEBUG a 1
.
No, sempre! Il check se hai la modalità debug attiva lo fai all'interno della funzione ToSerial, quindi la funzione ToSerial viene chiamata sempre, col risultato che la variabile stringa viene sempre creata nella Ram e passata alla funzione, anche quando poi non stampi sulla seriale.

Quote


Riscrivi il codice togliendo quella funzione e mettendo un semplice Serial.println in modo da poter usare le stringhe gestite in Flash con la funzione F() e racchiudendo tutto tra #define se vuoi stampare solo in caso di debug.


già ho provato ad usare F() in tutto le Serial.println che non avevano all'interno variabili, ma il sistema andava lo stesso in loop.


So che così raddoppi la lunghezza del tuo codice ma elimini un sacco di occupazione di memoria.


questo non è un problema, puoi farmi un esempio? Grazie


Quindi questo:
Code: [Select]
ToSerial("Ethernet ready");
deve diventare
Code: [Select]
#if DEBUG
Serial.println(F("Ethernet ready"));
#endif

Solo in questo modo hai la certezza che:
1) includerai quel serial.println solo quando sei in modalità debug
2) una volta incluso, la stringa verrà letta dalla Flash

essere_digitale

Quote




Ma l'hai fatto un controllo statico del consumo di memoria con avr-size oppure no?
Tanto per capire dove andiamo a cascare..


no, come si fa?

Compili lo sketch senza farne l'upload e con la modalità verbose attiva.
Nel terminale dell'IDE leggi dove sono stati creati i file temporanei del progetto e ti sposti in quella cartella.
Lì dai il comando:
Code: [Select]
avr-size -C nomeFirmware.cpp.elf



ecco il risultato

AVR Memory Usage
----------------
Device: Unknown

Program:   19014 bytes
(.text + .data + .bootloader)

Data:        969 bytes
(.data + .bss + .noinit)


Quote

Quote

Quote


Poi hai una miriade di invocazioni ad una funzione ToSerial che altro non fa che stampare stringhe sulla seriale. Peccato che tutte quelle stringhe gliele passi dalla Ram.


si, ma solo con il define DEBUG a 1
.
No, sempre! Il check se hai la modalità debug attiva lo fai all'interno della funzione ToSerial, quindi la funzione ToSerial viene chiamata sempre, col risultato che la variabile stringa viene sempre creata nella Ram e passata alla funzione, anche quando poi non stampi sulla seriale.

Quote


Riscrivi il codice togliendo quella funzione e mettendo un semplice Serial.println in modo da poter usare le stringhe gestite in Flash con la funzione F() e racchiudendo tutto tra #define se vuoi stampare solo in caso di debug.


già ho provato ad usare F() in tutto le Serial.println che non avevano all'interno variabili, ma il sistema andava lo stesso in loop.


So che così raddoppi la lunghezza del tuo codice ma elimini un sacco di occupazione di memoria.


questo non è un problema, puoi farmi un esempio? Grazie


Quindi questo:
Code: [Select]
ToSerial("Ethernet ready");
deve diventare
Code: [Select]
#if DEBUG
Serial.println(F("Ethernet ready"));
#endif

Solo in questo modo hai la certezza che:
1) includerai quel serial.println solo quando sei in modalità debug
2) una volta incluso, la stringa verrà letta dalla Flash




ok, adesso lo modifico
--
Alfredo

essere_digitale


Quindi questo:
Code: [Select]
ToSerial("Ethernet ready");
deve diventare
Code: [Select]
#if DEBUG
Serial.println(F("Ethernet ready"));
#endif

Solo in questo modo hai la certezza che:
1) includerai quel serial.println solo quando sei in modalità debug
2) una volta incluso, la stringa verrà letta dalla Flash



il codice sta già girando ... speriamo bene!

Piccolo appunto: se attivo il debug, il compilatore mi segnala errori perchè alla funzione F() posso passare solo stringhe e non variabili che contengono stringhe.
Code: [Select]

    #if DEBUG
    Serial.println(F("Ethernet ready in " + secs_txt + " sec.")); ////ERRORE DEL COMPILATORE
    #endif


invece

Code: [Select]

  #if DEBUG
  Serial.println(F("Ethernet initialization ...")); //// NESSUN ERRORE
  #endif



Per queste uso Serial.println senza F() ?
Grazie
--
Alfredo

leo72

Code: [Select]
Serial.println(F("Ethernet ready in " + secs_txt + " sec.")); ////ERRORE DEL COMPILATORE
Scomponila in più parti, no?  ;)

Esempio:
Code: [Select]
#if DEBUG
Serial.print(F("Ethernet ready in "));
Serial.print(secs_txt); //solo questo verrà copiato in Ram
Serial.println(F(" sec."));
#endif

Nota l'uso di println solo con l'ultima stampa.

essere_digitale



Quindi questo:
Code: [Select]
ToSerial("Ethernet ready");
deve diventare
Code: [Select]
#if DEBUG
Serial.println(F("Ethernet ready"));
#endif

Solo in questo modo hai la certezza che:
1) includerai quel serial.println solo quando sei in modalità debug
2) una volta incluso, la stringa verrà letta dalla Flash



il codice sta già girando ... speriamo bene!



Niente da fare: dopo 36 ore si blocca.
--
Alfredo

leo72

Perché non provi ad includere la libreria memoryFree ed a spedire ad intervalli regolari il quantitativo libero di RAM? Così capiamo se il blocco avviene per esaurimento della memoria oppure no.

essere_digitale


Perché non provi ad includere la libreria memoryFree ed a spedire ad intervalli regolari il quantitativo libero di RAM? Così capiamo se il blocco avviene per esaurimento della memoria oppure no.


Scusa l'ignoranza, come si fa?
--
Alfredo

tuxduino

Installi la libreria, che probabilmente fornirà una funzione tipo freeMemory(), il cui risultato stampi periodicamente (tipo 1 volta ogni 10 secondi) sulla seriale.

leo72



Perché non provi ad includere la libreria memoryFree ed a spedire ad intervalli regolari il quantitativo libero di RAM? Così capiamo se il blocco avviene per esaurimento della memoria oppure no.


Scusa l'ignoranza, come si fa?

Ho scritto un articolino apposta:
http://www.leonardomiliani.com/?p=572


Installi la libreria, che probabilmente fornirà una funzione tipo freeMemory(), il cui risultato stampi periodicamente (tipo 1 volta ogni 10 secondi) sulla seriale.

10 secondi come intervallo sono troppo pochi. Basta 1 volta all'ora, visto che gli è andato in crash l'Arduino dopo 36 ore.

essere_digitale




Perché non provi ad includere la libreria memoryFree ed a spedire ad intervalli regolari il quantitativo libero di RAM? Così capiamo se il blocco avviene per esaurimento della memoria oppure no.


Scusa l'ignoranza, come si fa?

Ho scritto un articolino apposta:
http://www.leonardomiliani.com/?p=572


Installi la libreria, che probabilmente fornirà una funzione tipo freeMemory(), il cui risultato stampi periodicamente (tipo 1 volta ogni 10 secondi) sulla seriale.

10 secondi come intervallo sono troppo pochi. Basta 1 volta all'ora, visto che gli è andato in crash l'Arduino dopo 36 ore.


Non ho parole ...
--
Alfredo

Go Up