Piszemy bootloader OTA dla ATmega128RFA1 (w ramach urządzenia Smart Response XE)

Piszemy bootloader OTA dla ATmega128RFA1 (w ramach urządzenia Smart Response XE)

Wszystko zaczęło się od zakupu przez autora ciekawego urządzenia na rynku wtórnym – Smart Response XE (krótki opis). Przeznaczony jest dla szkół: każdy uczeń w klasie otrzymuje urządzenie przypominające elektroniczny notatnik lub tłumacz z lat dziewięćdziesiątych, nauczyciel zadaje pytanie, a uczniowie wpisują odpowiedzi na klawiaturze urządzeń, które odbierane są za pośrednictwem kanał radiowy (802.15.4) do odbiornika podłączonego do komputera nauczyciela.

Urządzenia te zostały wycofane kilka lat temu, a to, co szkoły kupiły za 100–200 dolarów za sztukę, teraz pojawia się w serwisie eBay za 10 dolarów lub mniej. Znajdujący się tam sprzęt doskonale nadaje się do eksperymentów maniaków:

  • Klawiatura z 60 klawiszami
  • wyświetlacz o rozdzielczości 384×136, 2 bity na piksel - podobnie jak BC, CGA, ale 4 nie kolory, ale gradacja jasności
  • mikrokontroler ATmega128RFA1 (128 kB pamięci flash, 4 kB ROM, 16 kB RAM, transceiver 802.15.4)
  • zewnętrzna (w odniesieniu do mikrokontrolera, a nie całego urządzenia) 1 megabit (128 kilobajtów) pamięć flash z interfejsem SPI
  • przegródka na 4 elementy AAA.

Z nazwy mikrokontrolera jasno wynika, że ​​należy on do rodziny AVR, co oznacza, że ​​przystosowanie urządzenia do Arduino jest zadaniem więcej niż trywialnym...

Od wiadomości dalej Hackaday autor dowiedział się, co to jest już zrobione (ten sam link informuje co gdzie podłączyć), mając możliwość uruchamiania gier dla Arduboya:


Ale autora bardziej interesuje możliwość nie grania na urządzeniu, ale studiowania:

  • pamięć flash z interfejsem szeregowym SPI
  • bootloadery dla AVR
  • norma 802.15.4

Autor zaczął od pisania Biblioteka (GPL v3), która umożliwia inicjalizację wyświetlacza, wyświetlanie tekstu i prostokątów oraz dostęp do pamięci flash SPI. Potem zaczął pojawiać się pomysły na praktyczne wykorzystanie urządzenia: kieszonkowy terminal kompatybilny z VT-100, gry wieloosobowe. Po przebudowaniu trzech urządzeń postanowił „nauczyć” je odbierania szkiców „bezprzewodowo”. Co byłoby nie tylko ciekawe, ale i bardzo wygodne: obudowę urządzenia trudno za każdym razem otworzyć, a pod pokrywą komory baterii znajdują się jedynie otwory, które pozwalają na podłączenie programatora JTAG do płytki.

Piszemy bootloader OTA dla ATmega128RFA1 (w ramach urządzenia Smart Response XE)

Wystarczy wgrać bootloader Arduino, ale nie szkic - port szeregowy nie jest tam podłączony, więc i tak nie obejdzie się bez otwarcia obudowy. Również linie TX0 i RX0 pierwszego portu szeregowego są połączone z liniami odpytywania matrycy klawiatury, czyli tymi, które odpytują klawisze funkcyjne po bokach wyświetlacza. Ale co możesz zrobić - autor zbudował to:

Piszemy bootloader OTA dla ATmega128RFA1 (w ramach urządzenia Smart Response XE)

Przeniósł tam przewody JTAG i teraz nie ma potrzeby otwierania komory baterii. A żeby można było wgrać szkice, oba porty szeregowe podłączyłem do tego samego złącza, dodając też wyłącznik, bo przy założonych bateriach fizycznie nie da się wyłączyć urządzenia w żaden inny sposób.

Praca z lutownicą, nożem uniwersalnym i pistoletem do klejenia zajęła sporo czasu. Ogólnie rzecz biorąc, przesyłanie szkiców „bezprzewodowo” jest znacznie wygodniejsze, musimy pilnie coś w tym celu wymyślić.

Arduino IDE używa programu do przesyłania szkiców avrdude. Współpracuje z mikrokontrolerem za pomocą protokołu STK500, co umożliwia przesyłanie plików w obu kierunkach. Jest słabo kompatybilny z kanałami, w których możliwe są zmienne opóźnienia, zniekształcenia i utrata danych. Jeśli coś się poluzuje lub zaszeleści na kanale szeregowym, można szaleć w poszukiwaniu przyczyny. Pewnego razu autor męczył się przez pół dnia, aż zorientował się, że problemem jest zły kabel, a także kapryśny konwerter interfejsu CP2102. Nawet mikrokontroler z wbudowanym konwerterem interfejsu, na przykład ATmega32u4, może czasami tak działać. Każdy użytkownik Arduino zauważył, że błędy podczas przesyłania szkiców nie są tak rzadkie. Czasami zapis przebiega prawidłowo, lecz podczas odczytu testowego zostaje wykryty błąd. Nie oznacza to, że podczas zapisu wystąpił błąd - wystąpiła awaria podczas odczytu. Teraz wyobraź sobie, że podczas pracy „bezprzewodowo” stanie się to samo, ale znacznie częściej.

Po wypróbowaniu różnych sposobów rozwiązania tego problemu autor wpadł na następujący pomysł. Urządzenie posiada pamięć flash 128 kB z interfejsem SPI - dane odbieramy po przewodach (pamiętajmy, że autor ma już jedno urządzenie ze złączem z boku), wykorzystujemy tę pamięć jako bufor, a dane przesyłamy drogą radiową kanał do innego urządzenia. Pozdrowienia z Cybiko.

Po napisaniu kodu do współpracy z kanałem radiowym, a także czcionki, moduł ładujący stał się dłuższy niż 4 kilobajty. Dlatego wartość HFUSE musiała zostać zmieniona z 0xDA na 0xD8. Teraz bootloader może mieć długość do 8 kilobajtów, a adres początkowy to teraz 0x1E000. Znajduje to odzwierciedlenie w pliku Makefile, ale należy to również wziąć pod uwagę przy wypełnianiu program rozruchowy przez avrdude.

Transceiver 802.15.4 w ATmega128RFA1 został pierwotnie zaprojektowany do pracy przy użyciu protokołu ZigBee, co jest dość skomplikowane, dlatego autor zdecydował się zamiast tego po prostu przesyłać pakiety. Jest to zaimplementowane sprzętowo w ATmega128RFA1, więc wymagana jest niewielka ilość kodu. Również dla uproszczenia autor zdecydował się na zastosowanie stałego kanału, nie pozwalając na jego wybranie nawet ręcznie. Standard 802.15.4 obsługuje 16 kanałów o numerach od 11 do 26. Są one dość zatłoczone, niektóre także nakładają się na kanały WiFi (czerwony to kanały ZigBee, niebieski, zielony i żółty to WiFi).

Piszemy bootloader OTA dla ATmega128RFA1 (w ramach urządzenia Smart Response XE)

Okazało się, że najmniej podatne na zakłócenia ze strony WiFi są kanały 15 i 26. Autor wybrał drugi z nich. Zastrzeżenie: tłumacz nie wie, czy dozwolone jest upraszczanie ZigBee w ten sposób. Może powinniśmy trochę więcej zaprogramować i wdrożyć to całkowicie?

Na pierwszym urządzeniu należy zaimplementować maszynę skończoną, która przesyła dane poprzez protokół STK500. W większości wiadomości przesyłane i odbierane są samowystarczalne, ale niektóre są powiązane z tymi, które przeszły wcześniej przez kanał. Podano opis dialogu tutaj.

Ważnym elementem tego dialogu jest transmisja pakietów przeznaczonych do zapisania w pamięci flash urządzenia docelowego. Dla prostych mikrokontrolerów z rodziny AVR rozmiar strony wynosi 128 bajtów, ale dla ATmega128RFA1 jest to 256. A dla pamięci flash podłączonej poprzez protokół SPI jest to samo. Program w pierwszym urządzeniu wgrywając szkic nie przenosi go od razu na drugie, lecz zapisuje do tej pamięci. Kiedy Arduino IDE sprawdza poprawność wpisu, przesyłane jest to, co tam zostało zapisane. Teraz musimy przesłać odebrane dane kanałem radiowym do drugiego urządzenia. Jednocześnie przełączanie z odbioru na nadawanie i z powrotem następuje dość często. Protokół STK500 jest obojętny na opóźnienia, ale nie toleruje utraty danych (dziwne, ale jak wspomniano powyżej, opóźnienia wpływają również na transfer danych). A straty podczas transmisji bezprzewodowej są nieuniknione. ATmega128RFA1 posiada wbudowaną sprzętową implementację powtarzających się żądań w przypadku wątpliwości co do poprawności transferu, jednak autor zdecydował się samodzielnie zaimplementować to samo w oprogramowaniu. Opracował protokół, w którym w jedną stronę przepływa znacznie więcej danych niż w drugą.

Nie jest to idealne rozwiązanie, ale działa. Strona o wielkości 256 bajtów jest podzielona na cztery segmenty, z których każdy jest przesyłany drogą bezprzewodową w postaci pakietu. Pakiet może pomieścić do 125 bajtów danych plus jeden bajt długości i dwa bajty CRC. Umieszczane są więc tam fragmenty o długości 64 bajtów wraz z numerami stron i segmentów (od 0 do 3). Urządzenie odbiorcze posiada zmienną, która pozwala mu śledzić, ile segmentów zostało odebranych, a kiedy dotrą wszystkie cztery, urządzenie wysyłające otrzymuje potwierdzenie, że cała strona została odebrana. Brak potwierdzenia (CRC nie pasuje) - wyślij ponownie całą stronę. Prędkość jest jeszcze większa niż przy transmisji kablowej. Widzieć:


Ale ogólnie rzecz biorąc, konieczne byłoby zapewnienie wygodnego sposobu podłączenia kabla do urządzeń w celu przesyłania szkiców i przez niego. Przykładowo umieść w środku taki konwerter interfejsu na CP2102 jak na zdjęciu i przyklej go do płytki tak aby wytrzymał siłę przy podłączaniu i odłączaniu kabla Micro USB.

Piszemy bootloader OTA dla ATmega128RFA1 (w ramach urządzenia Smart Response XE)

Ma też stabilizator 3,3 V (a jak go zastosować w urządzeniu z zasilaniem 6 V - byle miał ten sam stabilizator, a można dodać dwie diody, żeby automatycznie wybrać, która z nich będzie zasilać urządzenie) . Wszystkie trzy diody LED należy wylutować z płytki konwertera interfejsu, w przeciwnym razie podczas pracy na nich dodatkowo ładują akumulatory, a także zakłócają odpytywanie klawiatury i pracę z pamięcią flash z interfejsem SPI.

Dążenie do celu okazało się jeszcze ciekawsze niż jego osiągnięcie (i niepotrzebny mi ten żart o autobusie). Autor dowiedział się wiele o bootloaderach AVR, pamięci flash SPI, protokole STK500 i standardzie 802.15.4.

Cały inny kod oprócz biblioteki opisanej powyżej to - tutaji jest także objęty licencją GPL v3. Twitter autora - tutaj.

Źródło: www.habr.com

Dodaj komentarz