Pisanie OTA-loadera dla ATmega128RFA1 (w składzie urządzenia Smart Response XE)

Pisanie OTA-loadera dla ATmega128RFA1 (w składzie urządzenia Smart Response XE)

Wszystko zaczęło się od zakupu przez autora ciekawego urządzenia na rynku wtórnym — Smart Response XE (krótkie opis). Jest ono przeznaczone dla szkół: każdy uczeń w klasie otrzymuje urządzenie przypominające elektroniczny notes lub translator z lat dziewięćdziesiątych, nauczyciel zadaje pytanie, a uczniowie wpisują odpowiedzi na klawiaturach urządzeń, które są przesyłane przez radiowy kanał (802.15.4) do odbiornika podłączonego do komputera nauczyciela.

Wsparcie dla tych urządzeń zostało przerwane kilka lat temu, a to, co szkoły kupowały za 100-200 dolarów za sztukę, teraz pojawia się na eBayu za 10 lub mniej. „Sprzęt” nadaje się idealnie do geekowskich eksperymentów:

  • klawiatura z 60 klawiszami
  • Wyświetlacz o rozdzielczości 384×136, 2 bity na piksel – analogicznie do BК, CGA, ale 4 nie kolory, a odcienie jasności.
  • mikrokontroler ATmega128RFA1 (128 kB pamięci flash, 4 kB pamięci EEPROM, 16 kB pamięci RAM, nadajnik/odbiornik zgodny ze standardem 802.15.4)
  • zewnętrzna (w odniesieniu do mikrokontrolera, a nie całego urządzenia) pamięć flash o pojemności 1 megabita (128 kilobajtów) z interfejsem SPI
  • komora na 4 elementy AAA.

Z nazwy mikrokontrolera wynika, że należy on do rodziny AVR, a zatem zrobienie urządzenia zgodnego z Arduino to zadanie bardziej niż trywialne…

Z wiadomości na Hackaday autor dowiedział się, że to już zrobiono (w tym samym linku jest opisane, gdzie podłączyć), uzyskując możliwość uruchamiania gier dla Arduboy:

Odtwarzaj wideo

Ale autora bardziej interesuje możliwości nauki, a nie grania na urządzeniu:
  • pamięć flash z interfejsem szeregowym SPI
  • bootloadery dla AVR
  • standard 802.15.4

Autor zaczął od napisania biblioteki (GPL v3), który umożliwia inicjalizację wyświetlacza, wyświetlanie tekstu i prostokątów, a także uzyskiwanie dostępu do pamięci flash z interfejsem SPI. Następnie zaczął wymyślać praktyczne zastosowania urządzenia: kieszeniowy terminal zgodny z VT-100, gry wieloosobowe. Przerabiając trzy urządzenia, postanowił

Pisanie OTA-loadera dla ATmega128RFA1 (w składzie urządzenia Smart Response XE)

To upload the Arduino bootloader is enough, but not the sketch — the serial port is not exposed, and you won't get around opening the case. Also, the TX0 and RX0 lines of the first serial port are combined with the lines for polling the keyboard matrix, specifically those that are used to poll the function keys on either side of the display. But what can you do — the author constructed this:

Pisanie OTA-loadera dla ATmega128RFA1 (w składzie urządzenia Smart Response XE)

He routed the JTAG lines there, so now there's no need to open the battery compartment. And to be able to upload sketches as well, he also brought out both serial ports to this same connector, adding a switch because it's physically impossible to turn off the device otherwise with installed batteries.

It took quite a long time to work with a soldering iron, utility knife, and glue gun. In general, uploading sketches "over the air" is significantly more convenient, and something must be urgently invented for this.

The Arduino IDE uses the program avrdude. It interacts with the microcontroller using the STK500protocol, which allows files to be transferred in both directions. It is poorly compatible with channels where variable delays, distortion, and data loss are possible. If something is failing or crackling in the serial channel, you can drive yourself crazy trying to find the cause. Once, the author struggled for half a day before realizing that the issue was a bad cable and a capricious CP2102 interface converter. Even a microcontroller with a built-in interface converter, such as the ATmega32u4, can sometimes act up like this. Every Arduino user has noticed that errors when uploading sketches are not so uncommon. Sometimes the write goes fine, but an error is found during the verification read. This doesn’t mean that there was a mistake during writing — the failure occurred during reading. And now imagine that when working "over the air" this same thing happens, but much more frequently.

After trying various ways to overcome this issue, the author came up with the following. The device has a 128-kilobyte flash memory with an SPI interface — accepting data via wires (remember, one device with a connector on the side is already available), using this memory as a buffer, and sending data to another device over the radio channel. A greeting from Cybiko.

Po napisaniu kodu do pracy z radiokanalem oraz czcionką, bootloader wydłużył się do 4 kilobajtów. Dlatego wartość HFUSE musiała zostać zmieniona z 0xDA na 0xD8. Teraz bootloader może mieć długość do 8 kilobajtów, a początkowy adres wynosi 0x1E000. Jest to odzwierciedlone w Makefile, ale należy to również uwzględnić podczas wgrywania. bootloadera z użyciem avrdude.

Nadajnik-odbiornik standardu 802.15.4 w ATmega128RFA1 został pierwotnie zaprojektowany do pracy w protokole ZigBee, który jest dość skomplikowany, dlatego autor postanowił zamiast tego po prostu przesyłać pakiety. W ATmega128RFA1 jest to realizowane sprzętowo, więc wymagana będzie ograniczona ilość kodu. Dla uproszczenia autor postanowił również użyć stałego kanału, nie pozwalając nawet na jego ręczny wybór. Standard 802.15.4 obsługuje 16 kanałów o numerach od 11 do 26. Są one dość zajęte, niektóre również pokrywają kanały WiFi (czerwonym zaznaczone kanały ZigBee, niebieskim, zielonym i żółtym — WiFi).

Pisanie OTA-loadera dla ATmega128RFA1 (w składzie urządzenia Smart Response XE)

Okazało się, że najmniej podatne na zakłócenia z WiFi są kanały 15 i 26. Autor wybrał drugi z nich. Zastrzeżenie: tłumacz nie wie, czy tak można upraszczać ZigBee. Może warto jeszcze trochę popracować nad kodem i zrealizować go w pełni?

Na pierwszym z urządzeń należy zrealizować automat skończony, przesyłający dane za pomocą protokołu STK500. W większości przypadków przesyłane i odbierane wiadomości są autonomiczne, ale niektóre są powiązane z tymi, które wcześniej przeszły przez kanał. Opis dialogu jest podany. tutaj.

Ważnym elementem tego dialogu jest przesyłanie pakietów przeznaczonych do zapisu w pamięci flash urządzenia docelowego. W prostych mikrokontrolerach rodziny AVR rozmiar strony wynosi 128 bajtów, ale w ATmega128RFA1 wynosi 256. A w tej pamięci flash, która podłącza się przez protokół SPI, jest taki sam. Program w pierwszym urządzeniu podczas wgrywania sketcha nie przesyła go od razu do drugiego, lecz zapisuje go w tej pamięci. Kiedy Arduino IDE sprawdza poprawność zapisu, wysyłane są dane, które tam zapisano. Teraz należy przesłać otrzymane dane przez kanał radiowy do drugiego urządzenia. Przełączanie z odbioru na nadawanie i z powrotem zdarza się dość często. Protokół STK500 jest obojętny na opóźnienia, ale nie toleruje utraty danych (dziwne, bo wcześniej powiedziano, że opóźnienia w przesyłaniu danych również mają wpływ). A utrata danych podczas bezprzewodowej transmisji jest nieunikniona. W ATmega128RFA1 wbudowano sprzętową implementację ponownych żądań w przypadku wątpliwości co do poprawności przesyłania, ale autor zdecydował się wdrożyć to samo programowo. Opracował protokół, w którym w jedną stronę przesyłane jest znacznie więcej danych niż w drugą.

Nie jest idealny, ale wszystko działa. 256-bajtowa strona jest dzielona na cztery segmenty, z których każdy przesyłany jest przez kanał radiowy w formie pakietu. Pakiet zawiera do 125 bajtów danych oraz jeden bajt - długość i dwa - CRC. Tak więc fragmenty o długości 64 bajtów wraz z numerami stron i segmentów (od 0 do 3) są tam umieszczane. W urządzeniu odbiorczym przewidziano zmienną, która pozwala śledzić, ile segmentów zostało odebranych, a gdy przychodzą wszystkie cztery, do urządzenia nadającego trafia potwierdzenie, że cała strona została odebrana. Brak potwierdzenia (CRC się nie zgadza) - wysyłamy całą stronę ponownie. Prędkość w tym przypadku jest nawet większa niż podczas przesyłania przez kabel. Zobacz:

Odtwarzaj wideo

Ale w ogóle, należałoby przewidzieć wygodny sposób podłączenia do urządzeń kabla do wgrywania sketche'ów. Na przykład umieścić wewnątrz taki konwerter interfejsów na CP2102, jak na zdjęciu, i przykleić go do płytki w taki sposób, aby wytrzymywał napięcie podczas podłączania i odłączania kabla Micro USB.

Pisanie OTA-loadera dla ATmega128RFA1 (w składzie urządzenia Smart Response XE)

W urządzeniu znajduje się również stabilizator 3,3-woltowy (a jak wykorzystać go w urządzeniu z 6-woltowym zasilaniem — jeśli tylko jest tam taki sam stabilizator, można dodać dwie diody, aby automatycznie wybierać, z którego z nich urządzenie będzie pobierać zasilanie). Z płytki przetwornika interfejsu należy wylutować wszystkie trzy diody LED, w przeciwnym razie będą one dodatkowo obciążać baterie podczas pracy z nimi, a także zakłócać odczyt klawiatury i pracę z pamięcią flash z interfejsem SPI.

Dążenie do celu okazało się nawet ciekawsze niż jego osiągnięcie (i nie ma potrzeby przytaczać tamtego dowcipu o autobusie). Autor dowiedział się wiele nowego o bootloaderach dla AVR, pamięciach flash z interfejsem SPI, protokole STK500 i standardzie 802.15.4.

Cały pozostały kod w dodatku do opisanej powyżej biblioteki — tutaj, i on również jest na licencji GPL v3. Twitter autora — tutaj.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster