
Il microcontrollore Freescale (ora NXP) MCF5213 è dotato di un controller DMA a 4 canali per velocizzare le operazioni di accesso diretto alla memoria. MCF5213 rappresenta una famiglia di microcontrollori a 32 bit ad alta integrazione basata su un'architettura ColdFire e core V2 di Freescale Semiconductor (ora NXP). Ecco una descrizione dettagliata del modulo con i relativi segnali, registri e modalità di trasferimento dati.
Introduzione
I micro di questa famiglia dispongono di SRAM interna fino a 32KB e 256 KB di memoria Flash oltre a quattro timer a 32 bit in grado di inoltrare richieste in DMA, un controller DMA a quattro canali, un modulo CAN, un modulo I2C, tre UART ed una periferica SPI con accodamento. Di seguito un elenco delle caratteristiche dei micro di questa famiglia:
- Core ColdFire V2 con unità MAC;
- 32KB di SRAM interna;
- 256KB di Flash on-chip;
- 3 moduli UART;
- Modulo FlexCAN 2.0;
- Controller per comunicazione I2C;
- Convertitore AD a 12 bit;
- Modulo QSPI;
- Controller DMA a 4 canali;
- 4 timer a 32 bit con supporto DMA;
- 2 timer a 16 bit con interrupt programmabili;
- Watchdog timer programmabile;
- Controller di interrupts fino a 63 interruzioni;
- Modulo oscillatore a 8MHz con PLL.
Per queste caratteristiche il microcontrollore è indicato per applicazioni di controllo industriale general-purpose. Nella presente trattazione verrà esaminato nei dettagli il controller DMA illustrando i registri relativi alla gestione e configurazione del modulo ed i processi con cui avviene un trasferimento dati in DMA.
STRUTTURA E REGISTRI COINVOLTI
Il controllore DMA costituisce un modo efficiente per il trasferimento di blocchi di memoria minimizzando l’intervento della CPU con conseguente incremento delle prestazioni in termini di velocità ed efficienza. Il controllore DMA del microcontrollore MCF5213 ha la struttura di figura 1 ed è costituito da 4 canali indipendenti che consentono il trasferimento di dati a blocchi di byte, word, longword o 16-byte.
Nella presente trattazione il suffisso n indicherà il riferimento al generico canale n (n=1..3). Ad ogni canale sono associati cinque registri: Source Address Register (SARn), Destination Address Register (DARn), Byte Count Register (BCRn), Control Register (DCRn) e Status Register (DSRn). Il processore genera internamente le richieste DMA portando ad livello alto il bit START del registro DCR, mentre il modulo UART ed i timer possono scatenare una richiesta di trasferimento in DMA utilizzando il segnale interno DREQ. Il controller DMA supporta trasferimenti dual-address ovvero una lettura seguita da una scrittura coinvolgendo quindi un indirizzo sorgente ed un indirizzo destinatario. Una operazione che coinvolge il modulo DMA prevede sempre i seguenti passi:
- inizializzazione del canale: prevede il caricamento dei registri associati al canale DMA con tutte le informazioni necessarie (controllo, indirizzi e numero di byte da trasferire);
- trasferimento dati: accettazione della richiesta di trasferimento in DMA e conseguente occupazione del bus per il trasferimento dei dati;
- chiusura del canale: avviene una volta completato il trasferimento dati sia che questo sia avvenuto correttamente, sia che si siano verificati eventuali errori.
I registri associati a ciascun canale DMA sono riportati in tabella 1.
Registro DMAREQC
Il registro DMAREQ (Dma REQuest Control) trasferisce le richiesta DMA dalle periferiche (timers o UART) ai canali del controller DMA e la sua struttura è quella di figura 2.
La parte alta di questo registro (i 16 bit più significativi) sono riservati, mentre la parte bassa può essere pensata costituita da 4 gruppi di quattro bit ciascuno che determinano l’associazione tra il canale DMA e l’evento sulla periferica. L’associazione viene fatta in accordo alla tabella 2, valori diversi da quelli specificati non producono richieste DMA.
Registri SAR
I registri SAR (uno per ciascun canale e identificati come SAR0, SAR1, SAR2 e SAR3) contengono l’indirizzo a partire dal quale il controller DMA andrà a prelevare i dati. La struttura di questi registri è riportata in figura 3 ed al reset viene inizializzato con il valore 0.
Registri DAR
Analogamente ai registri SAR, contengono l’indirizzo di destinazione a partire dal quale il trasferimento DMA memorizzerà i dati trasferiti. Le figure 3 e 4 riportano la struttura di tali registri che contengono 0 al reset.
Registri BCR e DSR
BCR (Byte Count Register) e DSR (Dma Status Register) sono in realtà campi di un unico registro a 32 bit la cui struttura è riportata in figura 5.
BCR contiene il numero di byte che dovranno essere trasferiti per un dato blocco. Il campo BCR viene decrementato (di 1, 2, 4, 16, 32 o 64 byte) ogni volta che un trasferimento viene completato con successo. Il campo DSR è costituito da 8 bit la cui struttura è riportata in figura 6.
Esso costituisce un registro di stato in cui ogni bit fornisce informazioni sullo stato del trasferimento DMA.
In particolare:
- CE (Configuration Error): viene messo ad 1 quando BCR, SAR o DAR contengono informazioni discordanti per il trasferimento del blocco o se BCR=0 all’inizio di un trasferimento. Viene azzerato con un reset hardware o automaticamente scrivendo un 1 nel bit DONE.
- BES (Bus Error on Source): se è 1 significa che il trasferimento DMA relativo allo specifico canale è stato terminato a seguito di un errore durante la fase di lettura del sorgente.
- BED (Bus Error on Destination): vale 1 quando il trasferimento viene interrotto a seguito di un errore durante la fase di scrittura in uno degli indirizzi destinatari.
- REQ (REQuest): vale 1 se il canale ha una richiesta di trasferimento pendente e non è selezionato.
- BSY (BuSY): viene messo a 1 la prima volta che viene abilitato il canale. Se vale 0 significa che il canale è inattivo e viene azzerato al termine di un trasferimento dati.
- DONE: viene messo a 1 quando sono state effettuate tutte le trasizioni richieste. Se usato in scrittura il bit DONE può essere impiegato per annullare un trasferimento in corso. Una volta completato un trasferimento il bit DONE deve essere azzerato manualmente dal software.
Registri DCR
Sono i registri di controllo usati per la configurazione del controller DMA. Le informazioni fornite da questo registro sono le seguenti:
- INT (INTerrupt on completion of transfer): se 1 abilita una interruzione al termine di un trasferimento sia che questo sia avvenuto correttamente sia che si sia completato con errori.
- EEXT (Enable EXternal request): se 1 abilita l’avvio di un trasferimento mediante una richiesta esterna (la richiesta interna avviene settando il bit START ed è sempre abilitata).
- CS (Cycle Steal): se vale 0 il controller DMA effettua cicli di lettura/scrittura per completare il trasferimento fintanto che BCR non raggiunge il valore 0. Se questo bit vale 1 ad ogni richiesta corrisponde un solo ciclo di lettura/scrittura.
- AA (Auto-Align): questo bit insieme ai campi SIZE determina se sorgente e destinatario sono auto-allineati e in questo caso il trasferimento avviene in modo ottimizzato.
- BWC (BandWidth Control): Indica il numero di byte in un blocco. In dettaglio:
- SINC (Source INCrement): permette di incrementare o meno il registro SAR dopo ogni trasferimento. Se vale 1 il registro SAR viene incrementato di 1, 2, 4 o 16 a seconda dell’ampiezza del trasferimento.
- SSIZE (Source SIZE): è l’ampiezza di un blocco sorgente (00=longword, 01=byte, 10=word, 11=16byte).
- DINC (Destination INCrement): ha la stessa funzione del bit SINC ma riferito all’indirizzo di destinazione.
- DSIZE (Destination SIZE): vedi SSIZE ma riferito al blocco destinazione.
- START: se 1 il DMA avvia un trasferimento. Il bit START viene automaticamente azzerato dopo un ciclo ci clock e viene sempre letto come 0.
- SMOD (Source address MODulo): definisce la dimensione del buffer circolare sorgente usato dal controller DMA in accordo alla seguente tabella:
- DMOD (Destination address MODulo): definisce la dimensione del buffer circolare di destinazione usato dal controller DMA in accordo alla seguente tabella:
- D_REQ (Disabile REQuest): se ad 1 il controlle DMA provvede ad azzerare il bit EEXT quando BCR si azzera.
- LINKCC (LINK Channel Control): Consente di collegare i trasferimenti dei canali DMA in accordo alla seguente tabella:
- LCH1 (Link CHannel 1): Indica il canale DMA da associare al link1: 00=ch0, 01=ch1, 10=ch2, 11=ch3.
- LCH2 (Link CHannel 2): analogo al precedente.
TRASFERIMENTO IN DMA
Prima di iniziare un trasferimento in dual-address, il controller DMA verifica che SSIZE e DSIZE siano consistenti con l’indirizzo sorgente e destinatario. Se non sono consistenti viene settato il bit CE e non avviene alcun trasferimento. Il trasferimento consiste nella lettura di dati dall’indirizzo sorgente e conseguente scrittura all’indirizzo destinatario. Al completamento di un trasferimento per uno specifico indirizzo, viene decrementato BCR e quando BCR raggiunge il valore zero, significa che è stato completato il trasferimento di tutti i byte richiesti.
Modalità di trasferimento DMA
Come già accennato le richieste DMA possono essere interne o esterne. In generale una richiesta può essere fatta settando il bit START o direttamente da una periferica UART o Timer. Alla richiesta di trasferimento deve essere sempre associata la modalità con cui il trasferimento dati dovrà essere effettuato: Cycle-steal o Continuous. Nel primo caso (CS=1) il trasferimento coinvolge il solo indirizzo sorgente e destinatario, mentre nel secondo caso (CS=0) vengono effettuati una serie di trasferimenti consecutivi fino a che BCR non si azzera. È evidente che nel secondo caso il trasferimento di un blocco dati avviene più velocemente a scapito di una maggiore occupazione di banda sul bus.
Trasferimento dual-address
Ciascun canale supporta un trasferimento detto dual-address. Questo comporta un indirizzo sorgente da cui vengono letti i dati ed un indirizzo destinatario al quale i dati vengono trasferiti. Il trasferimento avviene quindi in due fasi:
Dual-address Read: il controller DMA preleva il valore dal registro SAR e legge i dati sorgenti incrementando SAR del valore opportuno in accordo ai parametri di configurazione. Una volta acquisiti i dati sorgente, si passa alla seconda fase che prevede la scrittura all’indirizzo di destinazione. In caso di errori viene interrotto il trasferimento settando i bit BES e DONE.
Dual-address write: Il controller DMA carica l’indirizzo destinazione dal registro DAR quindi inizia la scrittura dei dati incrementando opportunamente il registro DAR e decrementando il registro BCR che tiene conto del numero di dati ancora da trasferire. Quando BCR raggiunge zero, vene settato il bit DONE a notificare che il trasferimento è stato completato. In caso di errori viene interrotto il trasferimento portando a 1 i bit DES e DONE.
Inizializzazione dei canali
Prima dell’inizio di un trasferimento in DMA è necessario inizializzare i registri di ogni canale con gli opportuni valori. I canali hanno priorità diversa, in particolare il canale 0 è quello a più alta priorità ed il canale 3 è quello a priorità più bassa. Alternativamente è possibile impostare la priorità tra i canali agendo sul campo BWC: se BWC=000 il canale ha priorità solo su quello immediatamente precedente. Grazie alla gestione delle priorità, è possibile gestire richieste DMA simultanee. Per inizializzare correttamente il modulo DMA, è necessario seguire i seguenti passi:
- Configurare il registro DMAREQC assegnando ciascuna periferica ad uno specifico canale DMA;
- Caricare SAR con il giusto valore per l’indirizzo sorgente;
- Caricare DAR con il corretto valore per l’indirizzo di destinazione;
- Inizializzare BCR con il corretto numero di byte da trasferire;
- Avviare il trasferimento scrivendo 1 nel bit START.
Controllo della banda
È possibile forzare il controllore DMA a liberare il bus per consentirne l’accesso da parte di altri dispositivi. In questo modo è possibile controllare il livello di occupazione del bus. Il campo BWC del registro DCR, permette di definire sette possibili dimensioni dei blocchi di trasferimento. Se il decremento di BCR raggiunge un valore multiplo di uno dei sette livelli previsti da BWC, la richiesta DMA viene negata fintanto che non è terminato il ciclo di bus. Se BCW=000 la richiesta viene servita fino all’azzeramento di BCR.
Condizioni di blocco del trasferimento
Un trasferimento in DMA può terminare prematuramente per una della seguenti ragioni:
- Errore: La terminazione avviene per un errore durante la lettura dei dati sorgenti (BES=1) o durante la scrittura all’indirizzo di destinazione (BED=1);
- Interruzione: questo avviene, ovviamente, solo nel caso in cui siano abilitate le interruzioni (INT=1 nel registro DCR).
Leggendo il registro DCR la CPU è in gradi di determinare la causa della terminazione del trasferimento.
Sincronizzazione e consistenza dei dati
Condividere strutture dati con dispositivi operanti in DMA non è cosa semplice. È possibile che una operazione in DMA abbia inizio durante l’esecuzione di una istruzione e la cosa diviene particolarmente critica se l’istruzione e l’operazione in DMA interessano lo stesso dato. Il miglior meccanismo per agire su strutture dati in modo atomico è utilizzare cicli di tipo read-modify-write ovvero un ciclo di lettura seguito da un ciclo di scrittura allo stesso indirizzo senza rilasciare il bus. In questo modo si rende atomica l’operazione (sia essa una trasferimento in DMA o una istruzione eseguita della CPU) rendendo consistente il dato per tutta la durata dell’operazione. L’alternativa è disabilitare il trasferimento in DMA per tutta la durata dell’istruzione in esecuzione negando l’autorizzazione all’accesso in DMA da parte dei dispositivi. Impiegando queste tecniche si deve prestare sempre molta attenzione. Alcuni processori supportano la disabilitazione delle operazioni in DMA usando un sistema di bloccaggio del bus: l’istruzione di bloccaggio non consente l’accesso al bus da parte di dispositivi esterni fintanto che non viene eseguita una istruzione di unlock che sblocca il bus. Il problema è del tutto analogo a quello che avviene durante un interrupt e l’esecuzione di una ISR (Interrpt Service Routine): è buona norma disabilitare le interruzioni per consentire l’operazione sulla struttura dati critica in modo atomico prevenendo l’intervento sulla stessa struttura da parte di altre routine ISR.
Riferimenti
Informazioni generali:
http://it.wikipedia.org/wiki/DMA
G.Frosini, P.Corsini – “Architettura degli elaboratori”
ed. Mc Graw Hill, 1997
DMA nei microcontrollori Freescale:
MCF52xx Datasheet – www.freescale.com
Altre risorse utili:
www.freepatentsonline.com/4901234.html

Direct Memory Access (DMA) è una tecnica per il trasferimento di dati per ottenere una maggiore velocità di trasmissione. Fornisce generalmente un miglioramento significativo rispetto a interrupt, sia in termini di latenza che throughput.