Ram+Seriale+Overflow

sono qui a lamentarmi del fatto che mi ritrovi troppa RAM :slight_smile:

ditemi dove sbaglio:

invio ad arduino via seriale una stringa di 10 caratteri, quindi 10 byte, cioe' 80 bit giusto ?
Questi 80 bit vanno nella Ram del 328 arduinico

ma se misuro la ram, prima e dopo l'invio della stringa, mi mancano solo 33 bit di ram, invece di 80

Questa e' una cosa buona, ma da dove deriva ?
C'entrano le word ?

Ringrazio in anticipo per eventuali gradite risposte :slight_smile:

Come misuri la RAM? Ci dai il codice? Sei sicuro che la misura della RAm non mangi della RAM?
Non credo che la RAM viene usata in Bit ma in Byte.
Ciao Uwe

Posta il codice che hai utilizzato, non è che allochi PRIMA la ram?

Testato:
sono qui a lamentarmi del fatto che mi ritrovi troppa RAM :slight_smile:

Certo che siete veramente incontentabili :slight_smile:

ditemi dove sbaglio:

Come hai misurato la ram ?
Lo sai che durante il run time la memoria utilizzata varia in funzione di quello che fa il programma ?
Un conto è il valore massimo di memoria occupato dal sistema e dalle variabili dichiarate, e un conto è la reale ram in uso durante il funzionamento.

Grazie per lì'interesse,

Ecco lo sketch di test:

extern unsigned int __bss_end;
extern unsigned int __heap_start;
extern void *__brkval;

 
static int freeMemory() 
{
  int free_memory;

  if((int)__brkval == 0)
     free_memory = ((int)&free_memory) - ((int)&__bss_end);
  else
    free_memory = ((int)&free_memory) - ((int)__brkval);

  return free_memory;
}



String x;


void setup ()
{
   Serial.begin(19200);
   
   
}


void loop ()
{
  Serial.println ( freeMemory () );
  delay (1000);


//  x = "";                 // 1823 bit Ram   
//  x = "testato123";  // 1804 bit RAM
  
}

La differenza tra x=vuota ed x=10byte di dati, fa perdere solo 19bit di ram, invece di 80bit

Test, stiamo mettendo la pazienza di Astro a durissima prova; già me lo immagino con una motosega accesa sullo stile di "Non aprite quel Forum" :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes:

vero, il titolo era palesemente provocatorio.
Credo cmq la soluzione non sia banale, se c'era da fare figuracce sarebbero gia' uscite fuori :slight_smile:
Tu ne sai niente ? sei daccordo con il mio ragionamento ?
A limite mi sarei aspettato un differenza in eccesso, ma non in difetto.
Visto che la x la tengo nel loop ad ogni ciclo sono sicuro venga caricata

Testato:
vero, il titolo era palesemente provocatorio.
Credo cmq la soluzione non sia banale, se c'era da fare figuracce sarebbero gia' uscite fuori :slight_smile:
Tu ne sai niente ? sei daccordo con il mio ragionamento ?
A limite mi sarei aspettato un differenza in eccesso, ma non in difetto.
Visto che la x la tengo nel loop ad ogni ciclo sono sicuro venga caricata

Mi pare che la risposta di massima sia già uscita fuori, al di là del tuo giusto ragionamento matematico:

astrobeed:
Come hai misurato la ram ?
Lo sai che durante il run time la memoria utilizzata varia in funzione di quello che fa il programma ?
Un conto è il valore massimo di memoria occupato dal sistema e dalle variabili dichiarate, e un conto è la reale ram in uso durante il funzionamento.

Bisogna vedere se il codice che hai postato possa far variare ad Astro questa affermazione, ma non credo.

Testato:
La differenza tra x=vuota ed x=10byte di dati, fa perdere solo 19bit di ram, invece di 80bit

Guarda che il valore ritornato dalla freeMemory sono Byte e non bit, quindi consumi pure di più di quello atteso, il motivo è semplice stai usando una AnsiString invece di una stringa C standard.
Le AnsiString per la loro natura dinamica richiedono più memoria di quelle standard (che vengono predefinite in fase di creazione) e poi la freeRam ti fa vedere tutta la ram in uso, stack e heap compresi che non sono mai fermi ad un valore ben preciso.

Thanks :slight_smile:

in genere lo spazio nelle eeprom viene dichiarato in bit sui datasheet, ad esempio una eeprom da 2k si intende 2000bit.

ero convinto che anche nel caso del 328 fossero bit, invece sono 2000Byte.
OTTIMO, quindi ne ho tantissimissima di ram :slight_smile:

Testato:
in genere lo spazio nelle eeprom viene dichiarato in bit sui datasheet, ad esempio una eeprom da 2k si intende 2000bit.

ero convinto che anche nel caso del 328 fossero bit, invece sono 2000Byte.
OTTIMO, quindi ne ho tantissimissima di ram :slight_smile:

No, i "k" sui micro sono ancora usati nella vecchia accezione di "kB", e non di "kiB" (i "kiB" sono spiegati qui). Quindi 2k di SRAM sono 2kB ossia 2048 byte, e non 2000 byte.
Ugualmente 1 kB di EEPROM sono 1024 byte e non 1000 byte.

questo e' il vecchio casino di byte che fa anche windows quando calcola lo spazio, e' altro discorso, non l'ho messo in conto, grazie cmq dell'approfondimento.
l'importante per me e' sapere che ho dei byte sotto e non dei bit :slight_smile:

visto che quindi ho a disposizione mettiamo 1500Byte, e che con il discorso di String (dispendioso come dice Astro) posso forse gestire max un 700B (caratteri) mi chiedevo:

Ma via seriale posso spedire un'unica stringa di 700Byte per poi riceverla e spacchettarla come piu' mi aggrada lato arduino ?
Oppure ci sono dei limiti sulla seriale, tipo inviare massimo tot byte ?

Thanks

Via seriale la spedizione è byte per byte, quindi una stringa verrà sempre spezzettata per l'invio.

Come limite ricordati che la seriale è gestita tramite un buffer software. Tale buffer è di 128 byte sull'IDE 002x e di 64 sull'IDE 1.0. Se riempi quel buffer potresti perdere dei dati. E' uno dei problemi che affligge l'IDE 1.0 e lo sketch ArduinoISP 1.0 che soffre del problema del buffer di dimensioni ridotte.

sul discorso di invio dei dati su seriale ci sono, ok, giustamente sulla seriale scorrono dei byte, e possono scorrerci 24h/24h

il discorso dell''ide invece non lo seguo almeno nel mio caso, cioe' io l'ide nemmeno lo apro, ho arduino che riceve via seriale.
Dovra' ricevere sta paccottiglia di 700Byte e gestirli, ram permettendo. C'e' sempre un discorso di buffer in questo caso ?

Quando crei un eseguibile, il compilatore crea il codice a partire dal tuo sketch. Se nel tuo sketch c'è la gestione della seriale, viene integrata nel firmware anche la libreria per gestirla. Quella dell'Arduino s'intende. E la seriale viene gestita con questo buffer dove vengono parcheggiati i dati. Il buffer viene creato con una dimensione differente a seconda che usi l'IDE 002x o l'1.0 perché la libreria che gestisce la seriale è diversa nelle 2 versioni.

Questa cosa è indipendente dall'uso con l'IDE. Essendo parte del firmware, il buffer viene inserito nel codice compilato. Quindi viene coinvolto in una trasmissione seriale, a prescindere con chi l'arduino sta dialogando (il computer, il terminale seriale dell'IDE o un altro micro).ia

Chiaro ?
Trasparente
aggiunti ulteriori test alla tua linea di credito

a questo punto quindi visto che uso la 1.0 mi becco il 64KB di limite

devo spezzettare la paccottiglia in 10 stringhe magari separate da un tot di tempo ?

cioe' mando 64K, aspetto chenneso' 100ms ? in modo che i dati passano dal buffer alla Ram ?

Non 64kB, 64 byte.
Cmq puoi aumentarlo. Basta aprire il file /hardware/arduino/cores/arduino/hardwareserial.cpp e modificare la voce che riguarda la dimensione del buffer e rimetterlo a 128 com'era nell'IDE 002x.

leo72:
Non 64kB, 64 byte.
Cmq puoi aumentarlo.

Attenzione a non fare confusione tra il buffer di ricezione della seriale e la capacità di trattare i dati, il buffer serve solo come tampone momentaneo se il micro è impegnato in altre cose mentre arrivano i dati, ma se non riesci a processarli più velocemente di come arrivano non importa se il buffer è di 10-20-64-100k alla fine si riempie sempre e cominci a perdere dati.
Per farla breve, l'importante è che il software sia in grado di elaborare i dati in arrivo più velocemente di come vengono trasmessi, se questa condizione è soddisfatta puoi inviare dati 24/7 senza problemi, se non lo è devi prevedere un modo per bloccare l'invio dei dati temporaneamente fino a che il micro non è grado di elaborare quelli nuovi, che poi è il concetto che sta alla base dei vari segnali di handshake della RS232 quali RTS/CTS e DTR/DSR.

c'é inoltre ai handshake HW via cavi anche quello Xon/Xoff che é via SW (vengono trasmessi questi 2 valori per fermare e riprendere la trasmissione).
Ciao Uwe