Adăugarea de capabilitate de încărcare de boot în aplicaţiile embedded oferă sistemului posibilitatea de a actualiza în orice moment firmware-ul ce rulează pe un microcontroler (MCU). Această capabilitate este foarte benefică dacă firmware-ul curent conţine o problemă, dacă imaginea firmware-ului trebuie programată pe MCU după ce produsul final este asamblat sau dacă firmware-ul aplicaţiei trebuie actualizat în teren. Pentru bootloading poate fi utilizat orice protocol de comunicaţie atâta vreme cât MCU-ul are posibilitatea de a comunica utilizând protocolul ales şi suficient spaţiu de program pentru stocarea firmware-ului.
Autor: Evan Schulz
Protocoalele I2C (Inter-Integrated Circuit) sau SMBus (System Management Bus), utilizate uzual de microcontrolere, necesită numai două fire pentru comunicaţie şi pot fi implementate cu un program firmware mic, făcând ca aceste protocoale să fie ideale pentru a fi utilizate de bootloader.
Imaginile firmware bootloader-ready pot fi trimise direct către dispozitivul ţintă de către un MCU separat sau printr-o punte de comunicaţie cu funcţie fixă conectată la un PC.
Haideţi să analizăm consideraţiile generale de proiectare a unui bootloader, precum şi tehnicile de implementare specifice I2C/SMBus pentru aplicaţiile embedded cu MCU. Mai întâi vor fi discutate câteva informaţii de bază despre protocolul I2C, inclusiv consideraţii hardware şi firmware.
Pentru comunicarea cu alte circuite integrate din sistem, protocolul I2C necesită două semnale: date seriale (SDA) şi ceas serial (SCL). Ambele linii bidirecţionale necesită un rezistor pull-up, tipic în domeniul 1kΩ – 4,7kΩ şi sunt configurate în mod deschis. În această configuraţie, dispozitivul comandă linia (forţează linia în stare inferioară sau eliberează linia, ceea ce va avea ca rezultat trecerea semnalului în stare superioară). Dispozitivele I2C sunt “hot-swappable,” ceea ce înseamnă că dispozitivele pot fi adăugate sau îndepărtate liber din magistrală. De exemplu dacă două dispozitive dintr-un sistem embedded comunică prin magistrală I2C, un dispozitiv de bootloading extern poate fi ataşat magistralei pentru a comunica cu MCU-ul în acelaşi timp.
Unul dintre dezavantajele implementării unei magistrale comune este acela că traficul prin magistrală (după cum se poate observa în figura 1) poate conduce la creşterea timpului necesar pentru pornirea unui dispozitiv (bootload). Elemente suplimentare care pot creşte durata de timp necesară pornirii pot fi: perioada ştergerii unei pagini flash, viteza protocolului de comunicaţie şi a programului flash. Duratele pentru ştergerea paginii flash şi pentru program sunt parametri stabiliţi şi nu pot fi modificaţi. Trebuie luată însă în considerare frecvenţa de ceas a protocolului de comunicaţie a bootloader-ului, ca influenţând direct timpul necesar pentru trimiterea unei noi imagini firmware către MCU. Majoritatea dispozitivelor I2C suportă frecvenţe de ceas de până la 400KHz (mod rapid), iar unele dispozitive până la 2MHz (mod de mare viteză).
Un alt beneficiu al protocolului I2C este acela că pot comunica între ele dispozitive cu tensiuni de I/O diferite, deoarece toţi pinii de pe magistrala I2C sunt toleranţi la tensiunea de pe magistrală. Acest lucru permite ca o mare varietate de dispozitive să comunice pe aceeaşi magistrală. Fiecare dispozitiv de pe magistrală este preconfigurat cu o adresă unică slave ce suportă comunicaţia cu dispozitivele master. Dispozitivul master iniţiază toate transferurile de date de pe magistrală, putând exista mai multe dispozitive master pe aceeaşi magistrală. Protocolul implică o schemă de arbitraj ce oferă o cale deterministă de a soluţiona două sau mai multe transmisii master în acelaşi timp, precum şi o metodă de control a transmisiei care să permită sistemelor ce dispun de frecvenţe de ceas mai mici să comunice cu dispozitive ce operează la frecvenţe de ceas mai mari. Utilizând numai doi pini ai unui dispozitiv şi necesitând numai două componente externe pasive, magistrala I2C este ieftină prin prisma hardware-ului.
Rutina de ştergere a memoriei flash este necesară pentru ştergerea programului aplicaţiei în timpul procesului de bootload, iar rutina de scriere este necesară pentru scrierea byţilor recepţionaţi de MCU ţintă în timpul procesului de bootload.
Pentru reducerea posibilităţii de apariţie a oricăror erori flash, ambele rutine trebuie să dispună de verificări de margini pentru a fi siguri că zonele flash din afara spaţiului aplicaţiei nu sunt şterse sau scrise. Acest lucru este foarte important pentru sistem, deoarece prin implementarea interfeţei de comunicaţie va fi localizată zona protejată de bootload a programului.
Firmware-ul de pe dispozitiv gestionează protecţia zonei programului de boot prin prevenirea ştergerilor sau scrierilor în această zonă. Deşi o interfaţă de comunicaţie I2C comandată prin întreruperi este o opţiune validă, pentru sistem este suficientă şi mult mai simplă o interfaţă de comunicaţie I2C cu mod. Dacă programul de boot este situat în paginile de nivel cel mai scăzut ale memoriei flash, întreruperile trebuie să fie redirecţionate către spaţiul aplicaţiei firmware. Compilatoarele pentru microcontrolere compatibile 8051 vor genera un program în limbaj maşină ce plasează vectorii de întrerupere începând cu adresa 0x0003, dar pot fi configurate în schimb să plaseze instrucţiunile LJMP în tabelul vectorului de întreruperi începând cu poziţia 0x0003. Acest lucru face ca vectorii de întrerupere din spaţiul aplicaţiei firmware să fie actualizaţi la actualizarea firmware-ului pe MCU.
Un protocol de comunicaţie bootloader este necesar pentru definirea structurii de byţi trimişi între MCU ţintă şi dispozitivul bootloader.
Din perspectiva firmware-ului însă, adăugarea de capabilitate de bootload I2C pe un MCU va creşte dimensiunea programului aplicaţiei.
Sarcinile firmware-ului ce trebuie executate includ:
• Rutine de ştergere flash
• Rutine de scriere flash
• Implementare de interfaţă de comunicare în mod alegere
• Redirecţionare vector întrerupere
• Protocol de comunicaţie de bootloading
• Pin de activare bootload
• Calcul CRC pentru verificarea imaginii programului de actualizare
De exemplu, protocolul trebuie să specifice o comandă de scriere pe care dispozitivul bootloader o poate trimite către MCU ţintă pentru a iniţia actualizarea firmware. Figura 2 arată un exemplu de pachete de byţi trimişi către MCU ţintă de către un dispozitiv bootloader.
Primul byte transmis pe magistrală este adresa I2C a MCU ţintă. După ce MCU-ul ţintă recunoaşte adresa sa I2C, este trimisă o comandă de scriere de boot pentru a informa microcontrolerul ţintă ce date să aştepte de la dispozitivul bootloader. Apoi, este trimisă prin magistrală poziţia de început pentru scrierea programului de actualizare, urmată de chei flash (dacă sunt cerute de MCU) şi imaginea programului de actualizare. MCU ţintă necesită un buffer în spaţiu de date sau date externe (xdata) pentru a stoca byţii primiţi. Dacă MCU ţintă primeşte un byte pe magistrala I2C, acesta va trimite pe magistrală o confirmare, care va permite dispozitivului bootloader să trimită un alt byte. Această secvenţă există atâta vreme cât va exista spaţiu în bufferul MCU-ului ţintă. În final este trimis un CRC (Cyclic Redundancy Check) pentru a valida imaginea firmware actualizată. După ce bufferul microcontrolerului ţintă este plin, iar datele din acesta sunt validate prin CRC, MCU ţintă poate începe scrierea din buffer pe flash, iar MCU bootloader trebuie să oprească trimiterea datelor.
În Figura 2, cheile flash sunt trimise de dispozitivul bootloader către microcontrolerul ţintă. Deşi această metodă necesită timp de comunicaţie suplimentar, este mai sigură decât a avea cheile flash codate în firmware-ul ce rulează pe MCU ţintă. Acest din urmă lucru ar creşte posibilitatea de eroare flash pe MCU ţintă. După finalizarea operaţiei de scriere pe flash pe MCU ţintă, acesta ar trebui să trimită un pachet predefinit către bootloader, pentru a solicita trimiterea de noi byţi. Protocolul de comunicaţie bootloader şi firmware-ul I2C vor trebui să gestioneze condiţii de eroare I2C, precum erori indicând pierderi sau confirmări negative (NAK). Dacă sunt activate funcţiile de SCL low timeout (condiţii de pierdere de timp specifice SMBus), ele vor trebui manevrate atât de protocol, cât şi de firmware. Protocolul de comunicaţie bootloader şi firmware-ul vor manipula orice fel de erori de comunicaţie, dar nu vor gestiona modul de intrare manual al bootload sau imagini incorecte de firmware.
Ar trebui creat un pin de bootload pentru a oferi o metodă sigură de intrare în modul bootload. Acesta poate fi implementat cu un pin de intrare/ieşire de uz general (GPIO). De exemplu, când MCU ţintă este reiniţializat, prima condiţie ce ar trebui verificată este starea pinului de activare bootload. În funcţie de aceasta, firmware-ul va intra în modul bootload sau în modul aplicaţie. Este oferită astfel o cale sigură de intrare în modul bootload, putând fi utilizată pentru revenirea din erori firmware. După reiniţializare, înainte de rularea aplicaţiei firmware trebuie validată întreaga imagine a aplicaţiei printr-o verificare de semnătură sau CRC. Înainte de intrarea în modul de aplicaţie,este important de verificat dacă imaginea aplicaţiei este validă. Dacă acest lucru nu se întâmplă, firmware-ul ar putea fi periculos pentru sistem. Se recomandă utilizarea ambelor metode: CRC şi semnătură pentru a reduce riscul rulării unor programe defecte.
Cel din urmă aspect al procesului de bootload este determinarea modului de trimitere a firmware-ului actualizat către MCU ţintă. Dacă este selectat un bootloader I2C, poate fi
selectat ca dispozitiv de încărcare de boot un MCU de uz general sau o punte de comunicaţie cu funcție fixă. Cu microcontrolerul de uz general, firmware-ul va trebui dezvoltat pentru gestionarea comunicaţiei cu MCU ţintă. Suplimentar, dezvoltatorul va avea nevoie de o cale de a trece firmware-ul actualizat de pe computer pe MCU, ceea ce va necesita mai multă dezvoltare de cod. Această opţiune oferă cea mai mare flexibilitate, dar necesită şi cel mai mare timp de dezvoltare. În locul unui microcontroler poate fi utilizată o punte de comunicaţie cu funcţie fixă, ceea ce nu necesită dezvoltare firmware. De exemplu, dacă este utilizată o punte de comunicaţie HID-to-I2C sau HID-to-SMBus, nu este nevoie de dezvoltare de firmware şi instalare de driver. Pentru comunicarea cu puntea în vederea trimiterii firmware-ului actualizat către MCU ţintă este necesară o aplicaţie HID host-side. Figura 3 prezintă un exemplu de sistem ce utilizează o punte de comunicaţie cu funcţie fixă.
Sumar
În orice sistem embedded, abilitatea de actualizare a firmware-ului pe un MCU oferă flexibilitate dezvoltatorului. Dacă o imagine aplicaţie conţine o eroare, dacă firmware-ul trebuie programat pe MCU după ce produsul final este asamblat sau dacă firmware-ul aplicaţiei trebuie actualizat în teren, un dispozitiv bootloader oferă o unealtă de dezvoltare convenabilă.
Bootloader-ele I2C sau SMBus sunt excelente, opţiuni economice pentru dezvoltatori. Protocoalele I2C şi SMBus necesită două semnale şi două componente pasive externe (rezistenţe) şi pot fi implementate cu un program mic. Imaginile de actualizare de firmware pot fi trimise către dispozitivul ţintă printr-un MCU separat sau printr-o punte de comunicaţie cu funcţie fixă conectată la un computer. Interfeţele de comunicaţie I2C şi SMBus sunt periferice economice, prezente uzual pe MCU-uri, făcându-le candidate ideale pentru utilizare ca interfaţă de comunicare bootloader.
www.silabs.com
Despre autor
Evan Schulz este angajat ca inginer de aplicaţii în cadrul grupului Embedded-Mixed Signal de la Silicon Laboratories.
Evan s-a alăturat Silicon Laboratories în 2008 ca inginer de aplicaţii asociat. El este licenţiat în inginerie electrică la Universitatea din Texas la Austin.