JTAG è l’acronimo di Join Test Action Group, un consorzio di oltre un centinaio di produttori di circuiti integrati e circuiti stampati che tra il 1985 ed il 1990 ha dato vita allo standard IEEE1149.1 che regola il test funzionale di circuiti integrati e circuiti stampati. Gli Atmel megaAVR® con più di 8KB di flash sono dotati di una versatile interfaccia JTAG. Ecco come funziona e come la configurazione dei fuses agisce su di essa.
1. Introduzione
Non è difficile fare confusione utilizzando i termini JTAG Programming, OCD, IEEE 1149.1 e BoundaryScan. Per questo motivo è bene fare un po’ di chiarezza nella terminologia prima di affrontare in dettaglio il funzionamento dell’interfaccia JTAG dei megaAVR®. L’interfaccia JTAG degli AVR è conforme allo standard IEEE1149.1 ed attraverso tale interfaccia è possibile accedere a diversi servizi quali Memory Programming, Boundary-Scan e On-Chip Debug (OCD). Rispettivamente i tre servizi consentono, attraverso l’interfaccia JTAG, di programmare la memoria interna, di verificare la corretta saldatura del dispositivo e di eseguire un debug dell’applicazione direttamente sul chip. Dal punto di vista hardware l’interfaccia JTAG prevede l’uso di quattro segnali:
TCK: è il TestCLock, un ingresso che controlla la temporizzazione delle interfacce di test indipendentemente dal clock di sistema;
TMS: Test Mode Select, un ingresso che controlla le transizione della macchina a stati interna;
TDI: Test Data Input, è l’ingresso che alimenta il contenuto dei registri interni dedicati al JTAG;
TDO: Test Data Output, è l’uscita attraverso la quale i dati interni raggiungono l’hardware esterno.
Questi segnali sono gestiti dal cosiddetto TAP Controller (Test Access Port Controller), una macchina a stati adibita al controllo dei segnali JTAG che interagisce con le varie periferiche interne. In figura 1 è riportato lo schema a blocchi di un ATmega128 in cui sono evidenziate le periferiche connesse all’interfaccia JTAG.
2. CONFIGURAZIONE DEI FUSES
Il comportamento dell’interfaccia JTAG è determinato dalla configurazione dei fuses e, in run-time, da un opportuno pin di I/O (JTD) che permette di disabilitare il servizio OCD. I fuses sono sostanzialmente due: JTAGEN e OCDEN. Schematicamente questi fuses possono essere pensati connessi come in figura 2.
Tale figura mostra anche la relazione tra i fuses ed il bit JTD. Nella tabella 1 è riportato invece lo stato dell’interfaccia JTAG per ciascuna combinazione dei due fuses e del pin JTD. Con riferimento alla tabella 1, il termine NP indica che il fuses è Non Programmato (o JTD non attivo) mentre P indica che il relativo fuses è programmato (o JTD è attivo).
È sconsigliato lasciare il chip nella configurazione indicata nella riga in rosso (riga 4) in quanto in questa modalità il consumo è notevole ed il micro è aperto dal punto di vista della sicurezza. D’altronde questo è l’unico modo per abilitare il servizio OCD che può essere comunque controllato da due Lock Bit (LB1 ed LB2).
3. ON-CHIP DEBUGGING (OCD)
Il servizio OCD consente di verificare il corretto funzionamento del programma eseguito dal micro. Ovviamente questo servizio non ha tutte le caratteristiche di un vero e proprio emulatore, ma ha una caratteristica particolare che nessun emulatore esterno può offrire: il codice viene testato direttamente nel micro quindi non esiste nessun comportamento emulato dal momento che sono presenti fisicamente tutte le connessioni e tutte le condizioni del funzionamento reale. Usando il JTAGICE, tool ufficiale Atmel per la programmazione/debug dei propri micro, in realtà non si ha una emulazione in-circuit (ICE) ma si ha a che fare con un protocollo di comunicazione tra l’interfaccia JTAG del micro e AVRstudio. La figura 3 mostra il flusso dei dati all’interno del micro nel caso di On-Chip Debugging.
Quando il fuse OCDEN è programmato, viene mantenuto attivo un segnale di clock anche quando il micro è in modalità sleep e questo comporta consumi significativi anche in questa modalità.
4. BOUNDARY-SCAN
Il Boundary-Scan è un modo molto efficiente per verificare la corretta saldatura del dispositivo e la corretta connessione con le altre periferiche del circuito. Questa caratteristica viene sfruttata dai numerosi tools che leggendo i file di descrizione del PCB (gerber o altri formati) permettono la verifica delle connessioni. La figura 4 mostra le connessioni interne dell’interfaccia JTAG nel caso in cui sia attivato il servizio Boundary-Scan.
Per abilitare il Boundary-Scan deve essere programmato il fuse JTAGEN mentre JTD deve essere inattivo. Lo standard IEEE1149.1 prevede quattro istruzioni dedicate alle operazioni di Boundary-Scan: EXTEST, IDCODE, SAMPLE_PRELOAD, BYPASS. Eccole descritte in dettaglio:
EXTEST: permette la selezione del Boundary-Scan Chain come registro dati per il test della circuiteria esterna al package. IDCODE: è l’istruzione di default allo startup del sistema e permette di selezionare l’ID register (32 bit) come registro dati. L’ID register contiene il numero di versione, il numero identificativo del dispositivo e il codice del costruttore. SAMPLE_PRELOAD: questa istruzione consente un pre-caricamento dei registri latch di uscita in modo da influire il meno possibile sulle prestazioni del sistema. BYPASS: Permette di gestire il contenuto del Bypass Register, in particolare consente di caricare nel registro lo zero logico o di scorrere il contenuto. I micro AVR prevedono anche una istruzione dedicata (AVR_RESET) che consente di forzare il microcontrollore nello stato di reset senza resettare il controller TAP.
5. PROGRAMMAZIONE IN JTAG
Come già accennato l’interfaccia JTAG consente anche di programmare la memoria interna del microcontrollore. Per utilizzare la JTAG come porta di programmazione è necessario impostare correttamente lo stato dei lock bit LB1 ed LB2 in accordo alla tabella 2.
La figura 5 mostra le connessioni interne nel caso in cui sia abilitata la modalità programmazione.
6. JTAG E LA SICUREZZA
Nel caso in cui su una stessa scheda vi siano connesse più periferiche dotate di interfaccia JTAG, la loro interconnessione è quella di figura 6, ovvero una connessione seriale sincrona in cui tutte le periferiche condividono il clock ed il segnale di controllo.
Come già visto l’unico modo per abilitare il servizio OCD è quello di disattivare i lock bit ed abilitare sia JTAGEN che OCDEN. In questo stato il dispositivo è piuttosto debole dal punto di vista della sicurezza e, utilizzando un semplce In-Circuit Programmer, risulterà piuttosto semplice acquisire il programma memorizzato in flash. Fortunatamente settando uno dei lock bit viene disabilitato l’OCD impedendo così la lettura della memoria interna garantendo un maggiore margine di sicurezza rispetto ad una normale interfaccia ISP. Per quanto riguarda la sicurezza sul Boundary-Scan questa è garantita dal fatto che questo servizio non prevede il coinvolgimento di segnali interni ma solamente informazioni relative alle connessioni con il package per cui non è possibile acquisire informazioni quali program counter, istruzioni ed altre risorse interne.
L’interfaccia JTAG ha un segnale di reset che comunque in molti casi non viene utilizzato ed è opzionale: TRST. Lo standard permette di avere tante funzionalità aggiuntive di collaudo, oltre a facilitare la programmazione e l’implementazione di test automatici definiti come BIST.
Non può essere, è un fake… TRST in sloveno è TRIESTE 🙂 Sul serio! Ottimo articolo, come sempre, complimenti
Lasciato così l’articolo muore, lo si legge anche ma non rende l’idea delle potenzialità senza fare esempi pratici.
Consiglio, se non già previsto, una seconda puntata dove si fanno tre esempi pratici di programmazione, ocd, bs.
Rimanendo su Avr su può usare una mega o una micro della serie Genuino, in modo da avere comodamente i pin necessari gia su connettore esterno.