Go Down

Topic: Eseguire istruzioni in parallelo (Arduino 2) (Read 3203 times) previous topic - next topic

kapooo

Ciao,

spero di postare nella sezione corretta. La mia è una domanda generica anche se legata ad un problema preciso, quindi...

E' possibile con un uC come quello presente nel Arduino Due eseguire istruzioni in parallelo? Da quel che so nessun uC può eseguire istruzioni in parallelo come si può fare, invece, programmando con i thread su PC. Sbaglio?

Chiedo questo per un semplice motivo: sto' utilizzando un ADC via SPI per riempire un buffer di 100 campioni. Dopo aver campionato 100 volte devo necessariamente interrompere ed inviare il buffer via seriale al PC. Nel caso non volessi interrompere il campionamento durante l'invio al PC sarebbe possibile??

Grazie 1000

nid69ita

Ti invitiamo a presentarti qui: http://forum.arduino.cc/index.php?topic=113640.0
e a leggere il regolamento: http://forum.arduino.cc/index.php?topic=149082.0
- qui una serie di schede by xxxPighi per i collegamenti elettronici vari: http://forum.arduino.cc/index.php?topic=146152.0
- qui le pinout delle varie schede by xxxPighi: http://forum.arduino.cc/index.php?topic=151646.0
- qui una serie di link utili: http://forum.arduino.cc/index.php?topic=126861.0
my name is IGOR, not AIGOR

pablos71

#2
May 16, 2014, 11:04 pm Last Edit: May 16, 2014, 11:08 pm by pablos Reason: 1
I processori o microcontrollori eseguono istruzioni in sequenza che sia uno Z80 o un Intel 7, quello che chiedi tu è un multitask, che è comunque fatto interrompendo per un attimo quello che faccio per fare un altra cosa velocemente e poi riprendere. Anche se tu avessi un dualcore dovresti smettere di fare campionamenti per passare i dati all'altro processore. Quello che fa la differenza in questi casi è la velocità del micro che ad alti livelli non noti.
L'esperienza è il tipo di insegnante più difficile ....
Prima ti fa l'esame e poi ti spiega la lezione.

Maurotec

Il processore della due dovrebbe avere DMA che ti permette di fare accesso diretto alla memoria RAM e con l'aiuto di qualche interrupt si riesce a fare due cose apparentemente in contemporanea.

La DUE supporta benissimo un sistema operativo RTSO con scheduler premptive, questo ti permette di fare qualcosa di molto simile a quello che fai lato PC. Crei task e li affidi allo scheduler che in base a delle priorità esegue task0 per 10ms e passa al task successivo che è di priorità minore.

Avere a che fare con un RTOS comporta la conoscenza dei meccanismi della esecuzione concorrente, in mancanza di ciò ti sconsiglio di provare perché potrebbe essere frustrante. Ci sono concetti che devono essere chiari come è chiaro che 2+2 fa 4. Ci sono i semafori, le priorità, l'eredità della priorità, la condivisione delle risorse, i rischi di rimanere in loop a fare sempre la stessa cosa. Il debug richiede harware e software specifici e si deve sapere fare debug.

In molti casi si può evitare di usare un RTOS creandosi qualcosa di vagamente simile, strutturando il codice in modo che micro esegue entrambe i task alternativamente in modo sufficientemente rapido che sembra lavorino in contemporanea. Purtroppo per fare ciò è richiesta una buona conoscenza del microprocessore e degli algoritmi
come fifo, lifo e coda, ringbuffer ecc.

Nello specifico del tuo problema in via teorica si deve mettere in atto un meccanismo in cui chi riceve i dati da mettere nel buffer viene interrotto (o si prende una pausa) e passa il controllo a quello che invia i dati presenti nel buffer al momento T, trovando il modo in cui ciclicamente a tempo T legge e a tempo T1 invia si ottiene un buon risultato, ma si devono stabilire i tempi T e T1 e il buffer in  modo opportuno per dare l'impressione che tutto avviene contemporaneamente (ho detto impressione). Se la necessità invece è quella di processare i dati in parallelo al momento non mi viene a si almeno in teoria c'è un micro 8 core (xcore) ma altro non so.

Ciao.

leo72

La Due ha un sys-tick apposito, cioè un timer generatore di interrupt nato appositamente per la scrittura di RTOS.
Alcuni degli RTOS più diffusi dovrebbero già essere in grado di girare sulla Due.
Se non si hanno particolari esigenze, il core di Arduino mette a disposizione un RTOS di tipo cooperativo molto base:
http://arduino.cc/en/Reference/Scheduler

kapooo

Grazie per le ottime risposte  :)  Avevo pensato di usare il DMA con l'SPI ma sarebbe comunque rimasto il problema del invio sulla Seriale quindi ho evitato di perdere tempo...

Sinceramente non ho mai usato un rtos su un uC, li ho sempre programmati in maniera "classica": scrittura del codice + debug. Mi piacerebbe comunque capire meglio i vantaggi/svantaggi nell'usare un rtos per progetti di media e grande dimensione. Sapete darmi dei consigli su guide, manuali, libri, corsi, ecc.?

pablos71

#6
May 17, 2014, 07:05 pm Last Edit: May 17, 2014, 07:16 pm by pablos Reason: 1
si ma alla fine sempre 1 main() c'è, le istruzioni vengono eseguite in modo sequenziale, quando trasmetti alla seriale tutti loop si fermeranno fino a quando non ha finito, anche se in brevissimo tempo.

Quote

Dopo aver campionato 100 volte devo necessariamente interrompere ed inviare il buffer via seriale al PC
Nel caso non volessi interrompere il campionamento durante l'invio al PC sarebbe possibile??
E' possibile eseguire istruzioni in parallelo? Da quel che so nessun uC può eseguire istruzioni in parallelo come si può fare, invece, programmando con i thread su PC. Sbaglio?

questa richiesta come è espressamente desctitta non può essere soddisfatta se non usando due micro che eseguono 2 funzioni separate contemporaneamente.

Usando lo Scheduler Il micro riesce a gestire la trasmissione seriale e contemporaneamente contunuare a leggere gli input? oppure si ferma un attimino di leggere gli input?
se la seriale ha un timeout di 1 secondo il micro continua a prelevare dati dall'input?
Io dico che non risolve.
Questo è quello che chiede
 
L'esperienza è il tipo di insegnante più difficile ....
Prima ti fa l'esame e poi ti spiega la lezione.

Maurotec

Spiegato così non si può capire nel dettaglio quali sono le necessità. Io ho pensato che il problema non fosse superabile senza un RTOS, ma ciò non è detto.
Se prendiamo come esempio il convertitore usb to serial di Arduino vediamo che senza RTOS esso legge da
seriale e spedisce via usb e viceversa. Si dovrebbe sapere che non devono arrivare tutti i dati prima di iniziare a spedire, anche perché non si conosce a priori quanti dati si inviano via seriale, per cui c'è un buffer di dati di mezzo.

Solitamente si tratta di un ring buffer ciclico (i dati rimangono nel buffer rimangono ciò che cambia sono HEAD e TAIL). Un (ISP) interrupt <dato presente> in hardware buffer fa saltare il puntatore ad eseguire la isr che legge il dato e lo spinge nel buffer, la isr termina e viene eseguito codice in background che prende il dato nel buffer (se c'è) e lo invia sulla seriale. La velocità tra lettura ISP e scrittura su seriale determina la dimensione del buffer, un meccanismo può legare ISP e seriale in modo busy/ready. Però questo è semplice e codice da prendere in prestito c'è per cui forse non è questa la soluzione cercata, del resto anche arduino legge e scrive in seriale continuando a fare altre cose.

Con gli RTOS e la gestione delle risorse ci si può incasinare anche tanto a causa del fatto che una risorsa risulta bloccata da un task che la usa e se un altro task la vuole usare non può fintanto che risulta bloccata, ma ci sono le code e un gestore come il sistema di stampa che si riserva il diritto di usare la stampante e tutti i task (processi) stampano in area gestore di stampa.

Si potrebbe dire di più se si avesse un diagramma a blocchi funzionale o anche un descrizione complessiva di cosa deve fare il sistema oltre a leggere da ISP e inviare su seriale.

Ciao.

leo72

#8
May 21, 2014, 12:26 pm Last Edit: May 21, 2014, 12:54 pm by leo72 Reason: 1

questa richiesta come è espressamente desctitta non può essere soddisfatta se non usando due micro che eseguono 2 funzioni separate contemporaneamente.

Usando lo Scheduler Il micro riesce a gestire la trasmissione seriale e contemporaneamente contunuare a leggere gli input? oppure si ferma un attimino di leggere gli input?

La seconda che hai detto. Avendo un solo core con una unica pipeline, puoi eseguire solo un solo flusso di programma alla volta per cui o sei sul main oppure sulla lettura degli input.
Quote

se la seriale ha un timeout di 1 secondo il micro continua a prelevare dati dall'input?
Io dico che non risolve.

Essendo però la MCU composta da diverse periferiche semi-indipendenti, se parliamo di seriale questa è in grado di ricevere dei dati in modo indipendente. Essa ha un buffer hardware in cui mette i pin bit che riceve e compone i dati. Sull'Atmega328 il buffer contiene 1 carattere, per cui se non prelevi quel carattere prima che arrivi il successivo esso viene sovrascritto. E' ciò che infatti fa la gestione seriale dell'Arduino: grazie all'interrupt, quando un carattere è disponibile viene sollevato un interrupt e la relativa ISR prende questo carattere e lo deposita nel buffer software del core di Arduino.

Ora a mente non ricordo il buffer hardware della DUE ma penso che almeno 1 carattere lo tenga per cui se parliamo di seriale, il problema potrebbe non presentarsi.

pablos71

Te lo dirò appena mi arriva la DUE, era parcheggiata in Ungheria e ora in Jugoslavia ... mha, si fa 2 ferie prima di essere bruciata da me :) :)
L'esperienza è il tipo di insegnante più difficile ....
Prima ti fa l'esame e poi ti spiega la lezione.

gpb01


Ora a mente non ricordo il buffer hardware della DUE ma penso che almeno 1 carattere lo tenga per cui se parliamo di seriale, il problema potrebbe non presentarsi.


Sempre un carattere è ... e se non leggi, lo perdi perché viene sovrascritto  ]:D

A livello di registri vieni comunque avvisato con la solita flag di Overrun ...

Quote
"If UART_RHR has not been read by the software (or the Peripheral Data Controller or DMA Controller) since the last transfer, the RXRDY bit is still set and a new character is received, the OVRE status bit in UART_SR is set. OVRE is cleared when the software writes the control register UART_CR with the bit RSTSTA (Reset Status) at 1."
(pag 759 del datasheet)


Guglielmo
Search is Your friend ... or I am Your enemy !

leo72


Sempre un carattere è ... e se non leggi, lo perdi perché viene sovrascritto  ]:D

Difatti l'interrupt per prelevarlo e metterlo nel buffer software è indispensabile. Fortunatamente la RAM della DUE è tale e tanta per cui non sei limitato al buffer di 64 byte della UNO  :smiley-sweat: :smiley-sweat:

Go Up