Vi skriver en OTA bootloader för ATmega128RFA1 (som en del av Smart Response XE-enheten)

Vi skriver en OTA bootloader för ATmega128RFA1 (som en del av Smart Response XE-enheten)

Allt började med att författaren köpte en intressant enhet på andrahandsmarknaden - Smart Response XE (kort beskrivning). Den är avsedd för skolor: varje elev i klassen får en enhet som liknar en elektronisk anteckningsbok eller en översättare från nittiotalet, läraren ställer en fråga och eleverna skriver in svaren på enheternas tangentbord, som tas emot via en radiokanal (802.15.4) till en mottagare kopplad till lärarens PC.

Dessa enheter lades ner för flera år sedan, och det som skolor köpte för $100-$200 vardera dyker nu upp på eBay för $10 eller mindre. Hårdvaran där är mycket lämplig för nördiga experiment:

  • 60 tangentbord
  • skärm med en upplösning på 384×136, 2 bitar per pixel - liknar BC, CGA, men 4 inte färger, utan graderingar av ljusstyrka
  • mikrokontroller ATmega128RFA1 (128 kB flashminne, 4 kB ROM, 16 kB RAM, 802.15.4 transceiver)
  • externt (i förhållande till mikrokontrollern, inte hela enheten) 1 megabit (128 kilobyte) flashminne med SPI-gränssnitt
  • fack för 4 AAA-element.

Av namnet på mikrokontrollern är det tydligt att den tillhör AVR-familjen, vilket betyder att göra enheten Arduino-kompatibel är en mer än trivial uppgift...

Från och med nyheterna Hackaday författaren fick reda på vad det är har redan gjort (samma länk talar om vad du ska ansluta var), med möjlighet att köra spel för Arduboy:


Men författaren är mer intresserad av möjligheten att inte spela på enheten, utan att studera:

  • flashminne med seriellt SPI-gränssnitt
  • bootloaders för AVR
  • standard 802.15.4

Författaren började med att skriva bibliotek (GPL v3), som låter dig initiera displayen, mata ut text och rektanglar och komma åt SPI-flashminne. Sedan började han komma med idéer för praktisk användning av enheten: en VT-100-kompatibel fickterminal, spel för flera spelare. Efter att ha byggt om tre enheter, bestämde han sig för att "lära" dem att ta emot skisser "över luften." Vad skulle inte bara vara intressant, utan också mycket bekvämt: enhetsfodralet är svårt att öppna varje gång, och under batterifackets lock finns det bara hål som gör att du kan ansluta en JTAG-programmerare till kortet.

Vi skriver en OTA bootloader för ATmega128RFA1 (som en del av Smart Response XE-enheten)

Detta räcker för att ladda upp Arduino bootloader, men inte skissen - serieporten är inte ansluten där, så du kan fortfarande inte göra utan att öppna fodralet. Dessutom kombineras TX0- och RX0-linjerna för den första seriella porten med pollinglinjerna i tangentbordsmatrisen, nämligen de som pollar funktionstangenterna på skärmens sidor. Men vad kan du göra - författaren byggde detta:

Vi skriver en OTA bootloader för ATmega128RFA1 (som en del av Smart Response XE-enheten)

Han tog med JTAG-linjerna dit, och nu finns det ingen anledning att öppna batterifacket. Och för att skisser skulle kunna laddas upp kopplade jag båda serieportarna till samma kontakt och lade även till en switch, för med batterierna installerade är det fysiskt omöjligt att stänga av enheten på något annat sätt.

Det tog ganska lång tid att arbeta med en lödkolv, en brukskniv och en limpistol. I allmänhet är det mycket bekvämare att ladda upp skisser "över luften", vi måste snarast uppfinna något för detta.

Arduino IDE använder programmet för att ladda upp skisser avrdude. Den interagerar med mikrokontrollern med hjälp av protokollet STK500, som låter dig överföra filer i båda riktningarna. Den är dåligt kompatibel med kanaler där varierande fördröjningar, distorsion och dataförlust är möjliga. Om något lossnar eller prasslar i seriekanalen kan du bli galen och leta efter orsaken. En gång led författaren i en halv dag tills han insåg att problemet var en dålig kabel, samt en nyckfull CP2102-gränssnittsomvandlare. Även en mikrokontroller med inbyggd gränssnittsomvandlare, till exempel ATmega32u4, kan ibland agera så här. Varje Arduino-användare har märkt att fel vid uppladdning av skisser inte är så sällsynta. Ibland går inspelningen bra, men under en testläsning upptäcks ett fel. Det betyder inte att det uppstod ett fel under skrivningen - det uppstod ett fel under läsningen. Föreställ dig nu att när du arbetar "över luft" kommer samma sak att hända, men mycket oftare.

Efter att ha provat olika sätt att övervinna detta problem kom författaren på följande. Enheten har ett 128 KB flashminne med ett SPI-gränssnitt - vi tar emot data över ledningarna (kom ihåg att författaren redan har en enhet med en kontakt på sidan), använder detta minne som en buffert och skickar data över radion kanal till en annan enhet. Hej från Cybiko.

Efter att ha skrivit koden för att fungera med radiokanalen, såväl som typsnittet, blev laddaren längre än 4 kilobyte. Därför måste HFUSE-värdet ändras från 0xDA till 0xD8. Nu kan starthanteraren vara upp till 8 kilobyte lång, och startadressen är nu 0x1E000. Detta återspeglas i Makefilen, men bör också beaktas vid fyllning bootloader via avrdude.

802.15.4-sändtagaren i ATmega128RFA1 är ursprungligen utformad för att fungera med protokollet ZigBee, vilket är ganska komplicerat, så författaren bestämde sig för att bara överföra paket istället. Detta är implementerat i hårdvara i ATmega128RFA1, så lite kod krävs. För enkelhetens skull bestämde författaren sig också för att använda en fast kanal, så att du inte ens kunde välja den manuellt. Standarden 802.15.4 stöder 16 kanaler med nummer från 11 till 26. De är ganska trånga, vissa överlappar även WiFi-kanaler (röd är ZigBee-kanaler, blå, grön och gul är WiFi).

Vi skriver en OTA bootloader för ATmega128RFA1 (som en del av Smart Response XE-enheten)

Det visade sig att kanalerna 15 och 26 är minst känsliga för störningar från WiFi. Författaren valde den andra av dem. Ansvarsfriskrivning: översättaren vet inte om det är tillåtet att förenkla ZigBee på detta sätt. Vi kanske borde göra lite mer programmering och implementera det helt?

På den första enheten är det nödvändigt att implementera en finita tillståndsmaskin som sänder data via STK500-protokollet. För det mesta är de meddelanden som sänds och tas emot självförsörjande, men vissa är knutna till de som passerat genom kanalen tidigare. Beskrivning av dialogen ges här.

En viktig komponent i denna dialog är överföringen av paket avsedda att skrivas till destinationsenhetens flashminne. För enkla mikrokontroller av AVR-familjen är sidstorleken 128 byte, men för ATmega128RFA1 är den 256. Och för flashminnet som är anslutet via SPI-protokollet är det samma sak. Programmet i den första enheten, när du laddar upp en skiss, överför den inte omedelbart till den andra, utan skriver den till detta minne. När Arduino IDE kontrollerar att posten är korrekt skickas det som skrevs där. Nu måste vi överföra mottagna data via radiokanal till den andra enheten. Samtidigt sker byte från att ta emot till att sända och tillbaka ganska ofta. STK500-protokollet är likgiltigt för förseningar, men tolererar inte dataförlust (konstigt, men det sades ovan att förseningar också påverkar dataöverföringen). Och förluster under trådlös överföring är oundvikliga. ATmega128RFA1 har en inbyggd hårdvaruimplementering av upprepade förfrågningar när det finns tvivel om överföringens korrekthet, men författaren bestämde sig för att implementera detsamma i programvaran själv. Han utvecklade ett protokoll där mycket mer data flödar åt det ena hållet än på det andra.

Det är inte perfekt, men det fungerar. Sidan på 256 byte är uppdelad i fyra segment, som vart och ett sänds via luften som ett paket. Ett paket kan innehålla upp till 125 byte data plus en byte för längd och två byte för CRC. Så fragment 64 byte långa tillsammans med sid- och segmentnummer (från 0 till 3) placeras där. Den mottagande enheten har en variabel som gör att den kan spåra hur många segment som har tagits emot, och när alla fyra anländer får den sändande enheten en bekräftelse på att hela sidan har tagits emot. Ingen bekräftelse (CRC matchade inte) - skicka om hela sidan. Hastigheten är till och med högre än vid sändning via kabel. Ser:


Men i allmänhet skulle det vara nödvändigt att tillhandahålla ett bekvämt sätt att ansluta kabeln till enheterna för att ladda upp skisser och genom den. Placera till exempel inuti en sådan gränssnittsomvandlare på CP2102, som på bilden, och limma fast den på kortet så att den tål kraften när du ansluter och kopplar ur Micro USB-kabeln.

Vi skriver en OTA bootloader för ATmega128RFA1 (som en del av Smart Response XE-enheten)

Den har också en 3,3-volts stabilisator (och hur man använder den i en enhet med en 6-volts strömförsörjning - om den bara har samma stabilisator, och du kan lägga till två dioder för att automatiskt välja vilken av dem som ska driva enheten) . Alla tre lysdioderna måste vara olödda från gränssnittsomvandlarkortet, annars kommer de att ladda batterierna ytterligare när de arbetar på dem, och även störa tangentbordets polling och arbeta med flashminne med ett SPI-gränssnitt.

Att jaga ett mål visade sig vara ännu mer intressant än att uppnå det (och behöver inte det där skämtet om bussen). Författaren lärde sig mycket om AVR-startladdare, SPI-flashminne, STK500-protokollet och 802.15.4-standarden.

All annan kod utöver biblioteket som beskrivs ovan är − här, och det är också under GPL v3. Författarens Twitter - här.

Källa: will.com

Lägg en kommentar