Newsgroup: it.hobby.elettronica.digitale
Titolo: Micro con UART e DMA?

Devo mettere su un sistema di schede a microcontrollore (diciamo una
decina) che comunicano
con un master tramite un bus seriale RS485. Come al solito, il Master
inizia la comunicazione
con uno slave e lo slave risponde. Fin qui tutto ok.
Ogni slave, oltre a rispondere ai comandi del Master, si occupa di
acquisira un certo numero di
segnali analogici (una decina) sfruttando il suo ADC interno e qualche
commutatore analogico
esterno oppure sfruttando ADC esterni (non ho ancora ben deciso).
In base al valore di questi segnali analogici e di altri ingressi
digitali, lo slave pilota delle uscite.
Quello che vorrei fare è ridurre ai minimi termini l'occupazione della
CPU durante la risposta al
Master e, contemporaneamente, massimizzare la velocità sul bus.
Il primo passo sarà cercare di aumentare il bitrate sul bus, sperando
di poter arrivare ai 115200bps,
rimanendo nel set di velocità standard della RS232.
A questa velocità, ogni 87us scatterebbe l'interrupt di trasmissione
di un byte. Se il pacchetto
di risposta è di 100 byte, per circa 9ms il micro sarà impegnato a
trasmettere. Il tempo tra un
interrupt e l'altro (appunto 87us) può essere troppo piccolo per poter
fare un numero sufficiente
di operazioni.
Allora stavo pensando ad una soluzione più performante, per esempio al
DMA. Esiste qualche
microcontrollore con DMA per l'UART? Non ho mai usato DMA, ma penso
che l'unica cosa che
la CPU dovrà fare è impostare un puntatore in RAM ed una dimensione
del buffer e la periferica
UART si occuperà di inviare tutti i byte fino ad esaurimento.
Che tipo di microcontrollore potrebbe fare al caso mio?
Naturalmente, per mantenere una coerenza tra i vari byte della
risposta, non posso permettere
alla CPU di modificare la zona di memoria che magari viene usata dal
DMA. Allora avevo pensato
di allocare due buffer identici ed usarli alternativamente. Con un
flag (istruzione atomica) passo
da un buffer all'altro. Anche se non sarà facile perchè potrebbero
arrivare due richieste da parte
del Master ancora prima che l'altro buffer sia stato riempito con
valori coerenti.
Ma su questo ci ragioniamo sopra dopo..

Ma su questo ci ragioniamo sopra dopo..
--
ciao
  Stefano

 Che tipo di microcontrollore potrebbe fare al caso mio?
Non li ho ancora usati, ma i dsPic sembrano soddisfare la domanda.
ciao
S

 di operazioni.
Dipende dalla velocità di gestione della ISR, che se deve fare operazioni
elementari difficilmente sarà maggiore di qualche microsecondo. Se
viceversa la ISR durasse più a lungo perché deve fare operazioni complesse
(es. impacchettare/spacchettare i dati oppure interpretarli mentre
arrivano), allora non potresti comunque usare il DMA, che lavora con buffer
già pronti e cucinati.
In ogni caso le MCU dotate di DMA più piccole che ho visto sono i MSP430.
-- 
emboliaschizoide.splinder.com

 di operazioni.
Perché dici questo? Dalla descrizione sembra una classica applicazione 
embedded I/O bound. Sei sicuro di aver davvero bisogno di quei pochi 
cicli di clock spesi nell'ISR ogni 87uS? Puoi descrivere in dettaglio 
la questione?
Secondo me il problema è solo posto male, in ogni caso, quasi tutti i 
micro ARM7 che conosco hanno un DMA nell'UART, puoi vedere le serie 
AT91SAM7 di Atmel o i cortex-m3 (Stellaris) di Luminary.
-- 
  _|/ Francesco Sacchi - Develer S.r.l., R&D dept.
   |\ 
http://www.develer.com/
 - 
http://www.bertos.org

 Mi sa che ti ci vuole ram esterna, allora. 
Per due buffer da un centinaio di byte? Mi sembra esagerato...

 In ogni caso le MCU dotate di DMA più piccole che ho visto sono i MSP430.
Grazie del suggerimento, proverò ad indagare.

 AT91SAM7 di Atmel o i cortex-m3 (Stellaris) di Luminary.
Sinceramente volevo rimanere su una semplice tecnologia a 8 bit. Gli 
Xmega della Atmel mi sembrano molto buoni a tale scopo.

 Xmega della Atmel mi sembrano molto buoni a tale scopo.
Sono d'accordo, infatti io sostengo la tesi che non hai bisogno di un 
DMA e ti basterrebbe un mega qualunque.
Ciao!


 molto elevata), passa tutto il tempo nell'ISR, piuttosto che a fare altro.
Il mio discorso prescinde completamente da quanto spesso i bytes vengano
spediti, potrebbero anche essere spediti in maniera continua. Il punto è
stabilire qual è il tempo di servizio della ISR, ossia il tempo per
rilevare l'interrupt, salvare il contesto, fare il branch alla ISR,
eseguire il codice che prende il byte dalla RAM e lo trasferisce nel buffer
dell'USART e ripristinare il contesto. E' questo tempo che io stimavo come
irrilevante (qualche microsecondo) rispetto agli 87 che passano da un
interrupt all'altro. Di solito con i tipici microcontrollori da almeno una
decina di MHz i problemi iniziano a sorgere con frequenze di interrupt un
ordine di grandezza superiori a quella che serve a te (circa 11 kHz).
-- 
emboliaschizoide.splinder.com

Per due buffer da un centinaio di byte? Mi sembra esagerato...
Se i buffer sono così corti allora ti conviene ragionare sulla gestione.
Ad esempio se hai un carattere ETX che termina il pacchetto ti conviene
verificarlo all'interrupt della seriale, poi scarichi sul buffer e nel caso di
fine pacchetto avvii il processo di verifica CRC ecc..
Il DMA potrebbe avere senso ma con cose più lunghe, per roba da 100 bytes non so
se ne vale la pena, anche se qualche ciclo macchina lo risparmieresti.
--
ciao
  Stefano

>Per due buffer da un centinaio di byte? Mi sembra esagerato...
Ho visto adesso la risposta a Sacchi.
Se devi velocizzare la trasmissione di sequenze di bytes già pronti allora
effettivamente con un DMA risparmieresti cicli macchina alla cpu.
Se usi uno xMega anche per altre caratteristiche (ADC a 12 bits per esempio)
allora ci sta, ma se devi metterlo apposta tieni presente che in trasmissione la
cpu perde poco tempo.
In fondo deve salvare i registri usati (3 o 4), caricare il puntatore, leggere
il carattere, metterlo sulla UART, ripristinare ed uscire, roba da 10 cicli in
assembler, forse 20 in C.
--
ciao
  Stefano

 DMA e ti basterrebbe un mega qualunque.
In realtà io intendevo l'Xmega con 4 canali DMA...

 ordine di grandezza superiori a quella che serve a te (circa 11 kHz).
Ok, speriamo bene...

 In realtà io intendevo l'Xmega con 4 canali DMA...
Sì, avevo capito. Io intendevo che basta un qualsiasi AVR senza DMA 
(non Xmega).
