Pages: 1 [2] 3 4 ... 8   Go Down
Author Topic: Ram+Seriale+Overflow  (Read 7364 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged


0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5784
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ?
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

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

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.
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9158
"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

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.
Logged

BZ (I)
Online Online
Brattain Member
*****
Karma: 250
Posts: 21215
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

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

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.
Esatto. Difatti questo è uno dei bug alla base della fallacità di ArduinoISP dell'IDE 1.0, che infatti soffre del buffer in ricezione di dimensioni ridotte perché mettendo quel famoso delay di 40ms nella funzione di pulsazione dei led di stato, se arriva una pagina da scrivere in flash (che se non ricordo male sono 512 byte) mentre è in quel delay, il buffer si riempie, l'indice va in overflow e lo sketch si blocca. Con la modifica di millis al posto dei delay si risolve la questione perché si permette al software di svuotare il buffer mentre i dati arrivano.
Logged


Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9158
"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

perché mettendo quel famoso delay di 40ms nella funzione di pulsazione dei led di stato,

Infatti usare una delay con una discreta mole di dati in arrivo sulla seriale è  veramente una "gran furbata"  smiley-mr-green
Logged

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5784
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie anche per l'intervento di uwe

A questo punto approfondiamo.

1) l'handshake hardware RTS/CTS e DTR/DSR  non si puo' usare su arduino ?
2) l'hanshake sw Xon Xoff non si puo' usare su arduino ?
3) il concetto di buffer e' presente anche lato Pc? cioe' un sw che spedisce su seriale dei dati lo fa in modo diretto, non ha anche il pc un buffer ?
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5784
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mi avete snobbato, avete fatto bene  smiley

pero' ora sto' sbattendo la testa in un problema reale, abbiate cuore  smiley-roll-sweat

ho assodato che non dite stupidaggini quando asserite che l'IDE1.0 ha come buffer seriale 64Byte (non avevo dubbi, ma mi piace assodare, deformazione professionale  smiley-yell)

quindi se spedisco ad arduino via seriale 100 caratteri, lui ne acchiappa solo 64, il resto si perde nel limbo

esiste un modo software per aggirare la situazione, oppure devo aumentare per forza il buffer come ha detto leo ?
a quanto potrei aumentarlo ? potrei ad esempio mettere il buffer a 1KB ?

Pro/Contro di Sw-Hw solution ?

thanks
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

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

ho assodato che non dite stupidaggini quando asserite che l'IDE1.0 ha come buffer seriale 64Byte (non avevo dubbi, ma mi piace assodare, deformazione professionale  smiley-yell)

quindi se spedisco ad arduino via seriale 100 caratteri, lui ne acchiappa solo 64, il resto si perde nel limbo
No, l'importante è svuotare quel buffer più velocemente di quanto si riempia.
Se controlli la presenza di nuovi caratteri nel buffer (Serial.available) e lo svuoti non appena arriva qualcosa, non hai problemi.

Quote
esiste un modo software per aggirare la situazione, oppure devo aumentare per forza il buffer come ha detto leo ?

a quanto potrei aumentarlo ? potrei ad esempio mettere il buffer a 1KB ?

Pro/Contro di Sw-Hw solution ?
l core di Arduino usa questo accorgimento: ha inserito una ISR (Interrupt Service Routine) per gestire l'interrupt che si genera quando si attiva la seriale e da dentro essa preleva i caratteri in arrivo e li inserisci nel buffer. Quindi c'è già una gestione HW/SW. Potresti riaumentare il buffer riportandolo a 128 byte (oltre non andrei, togli SRAM alle variabili del tuo programma). Risolvi ma non del tutto, vista la memoria limitata di Arduino.
Mica puoi creare un buffer di 10 kB  smiley-wink

Un'altra soluzione potrebbe essere quella di usare una memoria tampone esterna (tipo una RAM seriale veloce) e parcheggiare lì i byte in arrivo, creando un grosso buffer esterno. Ma a questo punto si entra nel campo delle cose assurde: cosa mai ti arriva dal PC per dover gestire migliaia di byte di dati?  smiley-eek-blue
Logged


0
Offline Offline
Shannon Member
****
Karma: 129
Posts: 10447
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

3) il concetto di buffer e' presente anche lato Pc? cioe' un sw che spedisce su seriale dei dati lo fa in modo diretto, non ha anche il pc un buffer ?

sì, nel caso di arduino (quindi simulazione seriale) il buffer è "simulato" anche lui (buffer software) ma non dubito che le seriali HW abbiano un proprio buffer HW.
In oltre, grazie al multithreading, è facile fare un'applicazione che svuota il buffer del driver/SO e li parcheggi in un "mortale" array come fa la serial di arduino, con la differenza che la ram di un PC hai voglia a riempirla smiley

Quote
quindi se spedisco ad arduino via seriale 100 caratteri, lui ne acchiappa solo 64, il resto si perde nel limbo

esiste un modo software per aggirare la situazione, oppure devo aumentare per forza il buffer come ha detto leo ?

allora, ogni quanto tempo tu entri nel ciclo di lettura? sai che un solo carattere impiega 1/baudrate secondi per essere inviato.
quindi 100 caratteri a 9600 impiegano 0.010 secondi (100 millis).
con un baud di 4800, i caratteri impiegano 200 millis.
quindi dimezzando il baudrate, abbiamo raddoppiato il tempo di overflow della seriale. Certo, abbiamo rallentato TUTTO il processo di lettura, ma se prima perdevi tanto tempo a fare altro, credo che la cosa sia ininfluente.

per completezza: a 9600 baud vai in overflow ogni 0.006 secondi, ovvero 60millis.
a 115200 baud (il massimo da ide) ogni 5ms
a 300 baud (il minimo da ide 1.0) ogni 0.21 secondi , 210 millis
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5784
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

X leo: semplicemente stampo su seriale 100 caratteri, sto facendo prove con caratteri senza senso, abcdef,ecc.
Lato Arduino ne afferro solo sempre esattamente 64.

X lesto: avevo pensato al trucco della velocita'. Ho fatto prove a 4800 ma resto fermo a 64 ricevut

mi sa che sbaglio candeggio.

Io faccio: if serial available concatena tutto
Ma mi sa che in questo modo visto che io spedisco 100 caratteri, la seriale e' sempre abailable e quindi non esce dal IF continuando a concatenare, arrivato a 64 il buffer va in overflow.
Che ne pensate ?
Mi chiedevo, ma inviare 100 caratteri su seriale e' talmente una coda strana ?
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

0
Offline Offline
Shannon Member
****
Karma: 129
Posts: 10447
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

scusami, ma quando fai una read elimini il dato letto dal buffer... puoi postare ilcodice?
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9158
"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

(non avevo dubbi, ma mi piace assodare, deformazione professionale  smiley-yell)

Adesso ci fai diventare tutti curiosi  smiley , non mi dire che come lavoro sei un qualche tipo di ispettore ?
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 120
Posts: 9158
"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

X leo: semplicemente stampo su seriale 100 caratteri, sto facendo prove con caratteri senza senso, abcdef,ecc.
Lato Arduino ne afferro solo sempre esattamente 64.

Come ti ha spiegato Leo Arduino gestisce la seriale tramite interrupt, fino alla revisione 0023 solo in lettura, la trasmissione avviene tramite polling, dalla 1.0 in poi anche in scrittura.
In pratica ogni volta che l'UART ha disponibile un nuovo carattere viene attivato il relativo interrupt e la sua ISR altro non fa che prelevarlo dal buffer (1 solo carattere) dell'UART e porlo nella prima posizione disponibile dell'array dati ricevuti è lungo 64 byte.
Ogni volta che vai a leggere il buffer ricezione seriale, la Serial.read, l'indice viene scalato di uno per ogni byte che leggi realmente pertanto rendi disponibile una nuova locazione nel buffer stesso, la Serial.available() si limita a dirti se ci sono caratteri nel buffer, ma non lo libera.
Se leggi i dati dal buffer con una velocità maggiore di quella con cui arrivano il buffer non si riempie mai, se non lo fai non appena arriva a 64 byte si ferma e i dati vengono persi.
Per come la vedo io la gestione che fa Arduino di questo buffer è sbagliata, il modo corretto è usare un ring buffer, ovvero un buffer dove in caso di superamento della capacità viene riscritto il primo byte e così via, e un flag di stato che avvisa dell'eventuale overflow, così posso sapere se c'è stata perdita di dati e comunque ho sempre disponibili gli ultimi 64 ricevuti.
Volendo fare le cose in modo perfetto l'ideale sarebbe rendere possibile tutti e due i modi di funzionamento, cioè sia il sistema con fermo a 64 byte e perdita di tutti gli altri, come è attualmente, e il ring buffer potendo scegliere tra i due durante l'init della seriale, p.e. scrivendo serial.begin(9600, RING) o serial.begin(9600, NORING).
Comunque per farla breve se mentre arrivano i dati sulla seriale tu li leggi con maggiore velocità non perdi un solo byte.
Come tempo (ipotizzando un flusso dati continuo) per riempire 64 byte a 9600 bps ci vogliono circa 67 ms, quindi non dovresti avere problemi per svuotare il buffer se lo gestisci ad ogni ciclo della loop senza usare in mezzo delle delay o altre istruzioni bloccanti.
Logged

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