Stiamo scrivendo un bootloader OTA per ATmega128RFA1 (come parte del dispositivo Smart Response XE)

Stiamo scrivendo un bootloader OTA per ATmega128RFA1 (come parte del dispositivo Smart Response XE)

Tutto è iniziato con l'acquisto da parte dell'autore di un dispositivo interessante sul mercato secondario: Smart Response XE (breve descrizione). È destinato alle scuole: ogni studente della classe riceve un dispositivo simile a un quaderno elettronico o a un traduttore degli anni Novanta, l'insegnante pone una domanda e gli studenti digitano sulle tastiere dei dispositivi le risposte, che arrivano tramite un canale radio (802.15.4) ad un ricevitore collegato al PC del docente.

Questi dispositivi sono stati interrotti diversi anni fa e ciò che le scuole hanno acquistato per $ 100- $ 200 ciascuno ora spunta su eBay per $ 10 o meno. L'hardware è molto adatto per esperimenti geniali:

  • Tastiera da 60 tasti
  • display con una risoluzione di 384×136, 2 bit per pixel - simile a BC, CGA, ma 4 non colori, ma gradazioni di luminosità
  • microcontrollore ATmega128RFA1 (memoria flash 128 kB, ROM 4 kB, RAM 16 kB, ricetrasmettitore 802.15.4)
  • memoria flash esterna (relativa al microcontrollore, non all'intero dispositivo) da 1 megabit (128 kilobyte) con interfaccia SPI
  • scomparto per 4 elementi AAA.

Dal nome del microcontrollore è chiaro che appartiene alla famiglia AVR, il che significa che rendere il dispositivo compatibile con Arduino è un compito più che banale...

Dalle notizie in poi metaltech l'autore ha scoperto di cosa si tratta ho già fatto (lo stesso collegamento ti dice cosa connettere e dove), avendo l'opportunità di eseguire giochi per Arduboy:


Ma l'autore è più interessato all'opportunità non di giocare sul dispositivo, ma di studiare:

  • memoria flash con interfaccia seriale SPI
  • bootloader per AVR
  • norma 802.15.4

L'autore ha iniziato scrivendo Biblioteca (GPL v3), che consente di inizializzare il display, produrre testo e rettangoli e accedere alla memoria flash SPI. Poi ha iniziato a elaborare idee per l'uso pratico del dispositivo: un terminale tascabile compatibile con VT-100, giochi multiplayer. Dopo aver ricostruito tre dispositivi, ha deciso di "insegnare" loro a ricevere schizzi "via etere". Cosa sarebbe non solo interessante, ma anche molto comoda: la custodia del dispositivo è difficile da aprire ogni volta, e sotto il coperchio del vano batteria ci sono solo fori che permettono di collegare un programmatore JTAG alla scheda.

Stiamo scrivendo un bootloader OTA per ATmega128RFA1 (come parte del dispositivo Smart Response XE)

Questo è sufficiente per caricare il bootloader di Arduino, ma non lo schizzo: la porta seriale non è collegata lì, quindi non puoi ancora fare a meno di aprire la custodia. Inoltre, le linee TX0 e RX0 della prima porta seriale vengono abbinate alle linee di polling della matrice della tastiera, cioè quelle che interrogano i tasti funzione ai lati del display. Ma cosa puoi fare: l'autore ha costruito questo:

Stiamo scrivendo un bootloader OTA per ATmega128RFA1 (come parte del dispositivo Smart Response XE)

Ha portato lì le linee JTAG e ora non è necessario aprire il vano batteria. E per poter caricare gli schizzi ho collegato entrambe le porte seriali allo stesso connettore, aggiungendo anche un interruttore, perché con le batterie installate è fisicamente impossibile spegnere il dispositivo in altro modo.

Ci è voluto un po' di tempo per lavorare con un saldatore, un taglierino e una pistola per colla. In generale, caricare schizzi "via etere" è molto più conveniente, dobbiamo urgentemente inventare qualcosa per questo.

L'IDE di Arduino utilizza il programma per caricare schizzi avrdude. Interagisce con il microcontrollore utilizzando il protocollo STK500, che consente di trasferire file in entrambe le direzioni. È scarsamente compatibile con i canali in cui sono possibili ritardi variabili, distorsioni e perdita di dati. Se qualcosa si allenta o fruscia nel canale seriale, puoi impazzire cercando la causa. Una volta l'autore ha sofferto per mezza giornata finché non si è reso conto che il problema era un cavo difettoso, oltre a un capriccioso convertitore di interfaccia CP2102. Anche un microcontrollore con un convertitore di interfaccia integrato, ad esempio ATmega32u4, a volte può comportarsi in questo modo. Ogni utente Arduino ha notato che gli errori durante il caricamento degli schizzi non sono così rari. A volte la registrazione va bene, ma durante la lettura di prova viene rilevato un errore. Ciò non significa che si sia verificato un errore durante la scrittura: si è verificato un errore durante la lettura. Ora immagina che quando si lavora "via etere" accadrà la stessa cosa, ma molto più spesso.

Dopo aver provato diversi modi per superare questo problema, l'autore ha ideato quanto segue. Il dispositivo ha una memoria flash da 128 KB con un'interfaccia SPI: riceviamo i dati tramite cavi (ricorda che l'autore ha già un dispositivo con un connettore sul lato), utilizziamo questa memoria come buffer e inviamo i dati via radio canale su un altro dispositivo. Ciao da Cybiko.

Dopo aver scritto il codice per funzionare con il canale radio e il carattere, il caricatore è diventato più lungo di 4 kilobyte. Pertanto, il valore HFUSE doveva essere modificato da 0xDA a 0xD8. Ora il bootloader può essere lungo fino a 8 kilobyte e l'indirizzo iniziale è ora 0x1E000. Ciò si riflette nel Makefile, ma dovrebbe essere preso in considerazione anche durante il riempimento boot loader tramite avrdude.

Il ricetrasmettitore 802.15.4 nell'ATmega128RFA1 è originariamente progettato per funzionare utilizzando il protocollo ZigBee, il che è piuttosto complicato, quindi l'autore ha deciso di trasmettere semplicemente i pacchetti. Questo è implementato nell'hardware nell'ATmega128RFA1, quindi è richiesto poco codice. Inoltre, per semplicità, l'autore ha deciso di utilizzare un canale fisso, non permettendo di selezionarlo nemmeno manualmente. Lo standard 802.15.4 supporta 16 canali con numeri da 11 a 26. Sono abbastanza affollati, alcuni si sovrappongono anche ai canali WiFi (il rosso sono i canali ZigBee, il blu, il verde e il giallo sono i WiFi).

Stiamo scrivendo un bootloader OTA per ATmega128RFA1 (come parte del dispositivo Smart Response XE)

Si è scoperto che i canali 15 e 26 sono i meno suscettibili alle interferenze del WiFi e l'autore ha scelto il secondo. Disclaimer: il traduttore non sa se è consentito semplificare ZigBee in questo modo. Forse dovremmo programmare un po' di più e implementarlo completamente?

Sul primo dispositivo è necessario implementare una macchina a stati finiti che trasmette i dati tramite il protocollo STK500. Per la maggior parte, i messaggi trasmessi e ricevuti sono autosufficienti, ma alcuni sono legati a quelli che sono passati attraverso il canale in precedenza. Viene fornita la descrizione del dialogo qui.

Una componente importante di questo dialogo è la trasmissione di pacchetti destinati ad essere scritti nella memoria flash del dispositivo di destinazione. Per i microcontrollori semplici della famiglia AVR, la dimensione della pagina è di 128 byte, ma per l'ATmega128RFA1 è di 256. E per la memoria flash collegata tramite il protocollo SPI, è la stessa cosa. Il programma nel primo dispositivo, quando carica uno schizzo, non lo trasferisce immediatamente al secondo, ma lo scrive in questa memoria. Quando l'IDE di Arduino verifica la correttezza dell'immissione, gli viene inviato ciò che è stato scritto lì. Ora dobbiamo trasmettere i dati ricevuti tramite canale radio al secondo dispositivo. Allo stesso tempo, il passaggio dalla ricezione alla trasmissione e viceversa avviene abbastanza spesso. Il protocollo STK500 è indifferente ai ritardi, ma non tollera la perdita di dati (strano, ma si è detto sopra che i ritardi influiscono anche sul trasferimento dei dati). E le perdite durante la trasmissione wireless sono inevitabili. L'ATmega128RFA1 ha un'implementazione hardware integrata di richieste ripetute quando ci sono dubbi sulla correttezza del trasferimento, ma l'autore ha deciso di implementare lo stesso nel software. Ha sviluppato un protocollo in cui fluiscono molti più dati in un modo che nell'altro.

Non è perfetto, ma funziona. La pagina da 256 byte è divisa in quattro segmenti, ciascuno dei quali viene trasmesso via etere come pacchetto. Un pacchetto può contenere fino a 125 byte di dati più un byte per la lunghezza e due byte per il CRC. Quindi vengono posizionati lì frammenti lunghi 64 byte insieme ai numeri di pagina e di segmento (da 0 a 3). Il dispositivo ricevente ha una variabile che gli consente di tenere traccia di quanti segmenti sono stati ricevuti e, quando arrivano tutti e quattro, il dispositivo mittente riceve la conferma che l'intera pagina è stata ricevuta. Nessuna conferma (CRC non corrispondeva): invia nuovamente l'intera pagina. La velocità è ancora maggiore rispetto alla trasmissione via cavo. Vedere:


Ma in generale, sarebbe necessario fornire un modo conveniente per collegare il cavo ai dispositivi per caricare gli schizzi e attraverso di esso. Ad esempio, posizionare all'interno un convertitore di interfaccia sul CP2102, come nella foto, e incollarlo sulla scheda in modo che possa resistere alla forza quando si collega e si scollega il cavo Micro USB.

Stiamo scrivendo un bootloader OTA per ATmega128RFA1 (come parte del dispositivo Smart Response XE)

Ha anche uno stabilizzatore da 3,3 volt (e come usarlo in un dispositivo con un alimentatore da 6 volt - se solo ha lo stesso stabilizzatore e puoi aggiungere due diodi per selezionare automaticamente quale di essi alimenterà il dispositivo) . Tutti e tre i LED devono essere dissaldati dalla scheda del convertitore di interfaccia, altrimenti caricheranno ulteriormente le batterie quando vengono utilizzati e interferiranno anche con il polling della tastiera e funzioneranno con la memoria flash con un'interfaccia SPI.

Perseguire un obiettivo si è rivelato ancora più interessante che raggiungerlo (e non c’è bisogno di quella battuta sull’autobus). L'autore ha imparato molto sui bootloader AVR, sulla memoria flash SPI, sul protocollo STK500 e sullo standard 802.15.4.

Tutto il resto del codice oltre alla libreria sopra descritta è − qui, ed è anche sotto GPL v3. Twitter dell'autore - qui.

Fonte: habr.com

Aggiungi un commento