Co to jest moduł ładujący i jak go opracować?

53

Spotkałem wiele projektów, w których mikrokontroler AVR korzysta z bootloadera (takiego jak Arduino), ale nie rozumiem tego pojęcia zbyt dobrze.

Jak mogę zrobić bootloader (dla dowolnego mikrokontrolera)?

Po napisaniu mojego programu ładującego, w jaki sposób jest programowany do mikrokontrolera (jak każdy program .hex wypalony na ROM ROM-ie AVR lub innej metody)?

mina_g
źródło
10
Oznaczono go tagiem bootloader , czy przeczytałeś to? Jeśli tak, to czy czytasz Arduino bootloadera , Arduino bootloadera następować , Arduino bootloadera , dobrych narzędzi i metod dla zrozumienia struktury bootloadera i Arduino bootloadera Szczegóły pytania? Wszystkie dotyczą części twojego pierwszego pytania. Skróciłem to do nowych rzeczy.
Kevin Vermeer
Artykuł na temat metody projektowania BootLoader: beningo.com/wp-content/uploads/images/Papers/...
yahya tawil
2
@KevinVermeer Myślę, że jego pytanie jest prostsze.
richieqianle,

Odpowiedzi:

103

Bootloader to program działający w mikrokontrolerze, który ma zostać zaprogramowany. Odbiera informacje o nowym programie zewnętrznie za pomocą niektórych środków komunikacji i zapisuje te informacje w pamięci programu procesora.

Jest to sprzeczne z normalnym sposobem wprowadzania programu do mikrokontrolera, który odbywa się za pomocą specjalnego sprzętu wbudowanego w mikro w tym celu. W przypadku PIC jest to interfejs podobny do SPI. O ile dobrze pamiętam, AVR-y używają Jtag, a przynajmniej niektóre z nich. Tak czy inaczej, wymaga to zewnętrznego sprzętu, który porusza pinami programującymi w sam raz, aby zapisać informacje w pamięci programu. Plik HEX opisujący zawartość pamięci programu pochodzi z komputera ogólnego przeznaczenia, więc sprzęt ten łączy się z komputerem z jednej strony, a specjalne piny programujące mikro z drugiej. Moja firma robi programistów PIC między innymi jako linię boczną, więc jestem całkiem zaznajomiony z tym procesem na PIC.

Ważnym punktem programowania zewnętrznego za pośrednictwem specjalistycznego sprzętu jest to, że działa niezależnie od istniejącej zawartości pamięci programu. Mikrokontrolery zaczynają się od skasowania pamięci programu lub w nieznanym stanie, więc programowanie zewnętrzne to jedyny sposób na przeniesienie pierwszego programu do mikro.

Jeśli masz pewność co do programu, który chcesz załadować do swojego produktu, a twoje wolumeny są wystarczająco duże, możesz poprosić o chipy producenta lub dystrybutora. Chip jest przylutowany do płyty, jak każdy inny układ, i jednostka jest gotowa do pracy. Może to być odpowiednie na przykład w przypadku zabawki. Gdy oprogramowanie układowe jest gotowe, jest prawie gotowe i będzie produkowane w dużych ilościach.

Jeśli woluminy są niższe lub, co ważniejsze, oczekujesz ciągłego rozwoju oprogramowania układowego i naprawiania błędów, nie chcesz kupować wstępnie zaprogramowanych układów. W takim przypadku puste płyty są montowane na płycie, a oprogramowanie układowe musi zostać załadowane na chip jako część procesu produkcyjnego. W takim przypadku linie programowania sprzętu muszą zostać w jakiś sposób udostępnione. Może to być za pomocą wyraźnego złącza lub padów pogo pin, jeśli chcesz stworzyć produkcyjne urządzenie testowe. Często takie produkty muszą zostać przetestowane i być może skalibrowane, więc dodatkowy koszt pisania programu na procesorze jest zwykle minimalny. Czasami, gdy używane są małe procesory, do procesora najpierw ładowane jest specjalne oprogramowanie testowe. Służy to do testowania i kalibracji urządzenia, wtedy prawdziwe oprogramowanie układowe jest ładowane po tym, jak sprzęt okaże się dobry. W tym przypadku istnieją pewne względy dotyczące projektowania obwodu, aby umożliwić dostęp do linii programowania w stopniu wystarczającym do działania procesu programowania, ale także nie nadmiernie utrudniać obwodu. Aby uzyskać więcej informacji na ten temat, zobacz mójzapis programowania w obwodzie.

Jak dotąd tak dobrze i nie jest potrzebny żaden program ładujący. Zastanów się jednak nad produktem ze stosunkowo złożonym oprogramowaniem układowym, który chcesz zaktualizować w terenie, a nawet pozwolić klientowi końcowemu na aktualizację. Nie można oczekiwać, że klient końcowy będzie miał gadżet programisty lub że będzie wiedział, jak prawidłowo go używać, nawet jeśli go dostarczyłeś. Tak naprawdę robi to jeden z moich klientów. Jeśli kupisz specjalną opcję dostosowywania pola, dostaniesz jednego z moich programistów z produktem.

Jednak w większości przypadków po prostu chcesz, aby klient uruchomił program na komputerze i magicznie zaktualizował oprogramowanie układowe. W tym miejscu pojawia się bootloader, szczególnie jeśli twój produkt ma już port komunikacyjny, który może łatwo łączyć się z komputerem, takim jak USB, RS-232 lub Ethernet. Klient uruchamia program na PC, który rozmawia z bootloaderem już w mikro. To wysyła nowy plik binarny do programu ładującego, który zapisuje go w pamięci programu, a następnie powoduje uruchomienie nowego kodu.

Brzmi prosto, ale nie jest tak, przynajmniej jeśli nie chcesz, aby ten proces był niezawodny. Co się stanie, jeśli wystąpi błąd komunikacji, a nowe oprogramowanie układowe zostanie uszkodzone, zanim dotrze do programu ładującego? Co się stanie, jeśli nastąpi przerwa w zasilaniu podczas rozruchu? Co się stanie, jeśli bootloader ma błąd i bzdury?

Uproszczonym scenariuszem jest to, że bootloader zawsze uruchamia się od resetu. Próbuje komunikować się z hostem. Jeśli host odpowie, to albo mówi programowi ładującemu, że nie ma nic nowego, ani wysyła mu nowy kod. Wraz z nadejściem nowego kodu stary kod jest zastępowany. Zawsze dołączasz sumę kontrolną z przesłanym kodem, aby bootloader mógł stwierdzić, czy nowa aplikacja jest nienaruszona. Jeśli nie, pozostaje w bootloaderze stale żądając przesłania, dopóki coś z prawidłową sumą kontrolną nie zostanie załadowane do pamięci. Może to być akceptowalne dla urządzenia, które jest zawsze podłączone i gdzie możliwe jest uruchomienie zadania w tle na hoście, który odpowiada na żądania bootloadera. Ten schemat nie jest dobry dla jednostek, które są w dużej mierze autonomiczne i tylko sporadycznie łączą się z komputerem hosta.

Zwykle prosty program ładujący, jak opisano powyżej, jest nie do przyjęcia, ponieważ nie jest bezpieczny w razie awarii. Jeśli nowy obraz aplikacji nie zostanie nienaruszony, chcesz, aby urządzenie kontynuowało działanie starego obrazu, aby nie było martwe do momentu pomyślnego przesłania. Z tego powodu zwykle w oprogramowaniu wbudowanym są dwa specjalne moduły: program ładujący i program ładujący. Program do przesyłania jest częścią głównej aplikacji. W ramach regularnej komunikacji z hostem można przesłać nowy obraz aplikacji. Wymaga to oddzielnej pamięci od głównego obrazu aplikacji, takiego jak zewnętrzna pamięć EEPROM lub użycie większego procesora, aby połowę miejsca w pamięci programu można było przeznaczyć na przechowywanie nowego obrazu aplikacji. Przesyłający zapisuje gdzieś otrzymany nowy obraz aplikacji, ale go nie uruchamia. Gdy procesor zostanie zresetowany, co może się zdarzyć na polecenie hosta po przesłaniu, bootloader działa. Jest to teraz całkowicie samodzielny program, który nie wymaga możliwości komunikacji zewnętrznej. Porównuje bieżące i przesłane wersje aplikacji, sprawdza ich sumy kontrolne i kopiuje nowy obraz do obszaru aplikacji, jeśli wersje różnią się, i sprawdza nową sumę kontrolną obrazu. Jeśli nowy obraz jest uszkodzony, po prostu uruchamia starą aplikację jak poprzednio.

Zrobiłem wiele programów ładujących i nie ma dwóch takich samych. Nie ma bootloadera ogólnego przeznaczenia, pomimo tego, w co niektóre firmy zajmujące się mikrokontrolerem chcą, abyś w to wierzył. Każde urządzenie ma swoje wymagania i szczególne okoliczności dotyczące obsługi hosta. Oto tylko niektóre konfiguracje bootloadera i czasami uploadera:

  1. Podstawowy program ładujący. To urządzenie miało linię szeregową i będzie podłączone do hosta i włączone w razie potrzeby. Program ładujący uruchomił się od resetu i wysłał kilka odpowiedzi na żądanie przesłania do hosta. Jeśli program do przesyłania działał, zareagowałby i wysłał nowy obraz aplikacji. Jeśli nie zareaguje w ciągu 500 ms, bootloader zrezygnuje i uruchomi istniejącą aplikację. Aby zaktualizować oprogramowanie wewnętrzne, musisz najpierw uruchomić aplikację aktualizującą na hoście, a następnie podłączyć i włączyć urządzenie.

  2. Program do przesyłania pamięci. Tutaj użyliśmy PIC o następnym rozmiarze, który miał dwa razy więcej pamięci programu. Pamięć programu została z grubsza podzielona na 49% głównej aplikacji, 49% nowego obrazu aplikacji i 2% bootloadera. Program ładujący uruchomiłby się od resetu i skopiował nowy obraz aplikacji na bieżący obraz aplikacji w odpowiednich warunkach.

  3. Zewnętrzny obraz EEPROM. Podobnie jak nr 2 z wyjątkiem tego, że do przechowywania nowego obrazu aplikacji użyto zewnętrznej pamięci EEPROM. W tym przypadku procesor z większą pamięcią byłby również fizycznie większy i należałby do innej podrodziny, w której nie było potrzebnych nam urządzeń peryferyjnych.

  4. Program ładujący TCP. To był najbardziej złożony ze wszystkich. Zastosowano duży PIC 18F. Ostatnia 1/4 pamięci zawierała bootloader, który miał własną kompletną kopię stosu sieciowego TCP. Program ładujący uruchomił się od resetu i próbował połączyć się ze specjalnym serwerem wysyłającym pod znanym portem pod wcześniej skonfigurowanym adresem IP. Dotyczyło to dużych instalacji, w których zawsze była dedykowana maszyna serwerowa dla całego systemu. Każde małe urządzenie po resecie zaloguje się na serwerze przesyłania i otrzyma nową kopię aplikacji. Program ładujący nadpisze istniejącą aplikację nową kopią, ale uruchom ją tylko wtedy, gdy zostanie zaznaczona suma kontrolna. Jeśli nie, wróci do serwera przesyłania i spróbuje ponownie.

    Ponieważ sam bootloader był skomplikowanym kodem zawierającym pełny stos sieciowy TCP, również musiał być możliwy do uaktualnienia w terenie. Sposób, w jaki to zrobiliśmy, polegał na tym, aby serwer wysyłający nakarmił go specjalną aplikacją, której jedynym celem było zastąpienie bootloadera po jego uruchomieniu, a następnie zresetowanie komputera, aby uruchomił się nowy bootloader, co spowodowałoby, że serwer uploadu wysłał najnowszy obraz głównej aplikacji. Technicznie usterka zasilania w ciągu kilku milisekund potrzebnych specjalnej aplikacji do skopiowania nowego obrazu za pomocą programu ładującego byłaby nie do naprawienia. W praktyce tak się nigdy nie stało. Byliśmy w porządku z bardzo mało prawdopodobną szansą na to, ponieważ te urządzenia były częścią dużych instalacji, w których już byli ludzie, którzy przeprowadziliby konserwację systemu, co czasami oznaczało wymianę urządzeń wbudowanych z innych powodów.

Mamy nadzieję, że zauważysz, że istnieje wiele innych możliwości, każda z własnymi kompromisami ryzyka, szybkości, kosztów, łatwości użytkowania, przestojów itp.

Olin Lathrop
źródło
1
Wszystkie AVR z wyjątkiem rodziny Xmega (która ma nowy interfejs 2-przewodowy) używają interfejsu SPI, gdy są resetowane. Większe mają również JTAG, niektóre mają programowanie równoległe, a mniejsze mogą wymagać wysokiego napięcia, jeśli reset został zrekonfigurowany jako I / O. Niektóre MCU, takie jak rodziny Parallax Propeller i Motorola / Freescale 68HC08, nie mają minimalnego sprzętu do programowania, ale bootloadery w pamięci ROM.
Yann Vernier
Porównuje bieżące i przesłane wersje aplikacji, sprawdza ich sumy kontrolne i kopiuje nowy obraz do obszaru aplikacji, jeśli wersje różnią się, i sprawdza nową sumę kontrolną obrazu. Tak, ale co jeśli zasilanie zostanie przerwane w środku tej akcji, w obszarze aplikacji pojawi się uszkodzony obraz. Podejrzewam, że lepszym rozwiązaniem może być aplikacja bootloadera-odporna na awarie, która zapisuje nową aplikację we flashu mcu, a jeśli suma kontrolna jest prawidłowa, zapisuje także „OK, aby uruchomić nową aplikację”. Na początku sprawdza, czy można uruchomić nową aplikację, jeśli nie, kontynuuje działanie (aplikacja bezpieczna w razie awarii)
Ervadac
@Erv: Jeśli zasilanie nie powiedzie się w trakcie kopiowania nowej wersji do bieżącej, suma kontrolna bieżącej wersji nie powiedzie się, gdy zasilanie wróci i bootloader uruchomi się ponownie. Zwykle umieszczam słowo sumy kontrolnej na samym końcu obrazu, aby każde częściowe zapisanie miało bardzo dużą szansę na błąd sumy kontrolnej.
Olin Lathrop,
Cześć. Mogę polecić Ci bootloader typu 5 - zamiast stosu TCP możesz zaimplementować UDP. Następnie użyj TFTP, aby pobrać aktualizację lub protokół macierzysty.
i486
22

Jaka jest koncepcja bootloadera?

Wyobraź sobie ten scenariusz: Masz wystarczająco dużo miejsca na mikrokontrolerze - wystarczająco dużo, aby przechowywać więcej niż 2-3 programy lub aplikacje, które są od siebie niezależne. Załóżmy, że podczas uruchamiania urządzenia możesz chcieć wybrać, które chcesz uruchomić. Czego więc potrzebujesz, żeby to wesprzeć? Będziesz potrzebował programu startowego, który pozwoli ci wybierać między innymi podczas rozruchu.

Jak to działa?

Program ładujący to ten program - jest pierwszą rzeczą do uruchomienia i może ładować inne aplikacje do określonych miejsc w pamięci (trwałych, takich jak FLASH lub niestabilnych, takich jak RAM), a następnie przeskakuje do tego pożądanego programu, skąd następnie przejmie wykonanie .

Jak zrobić program ładujący AVR (lub dowolny mikrokontroler)?

Nigdy nie stworzyłem bootloadera, ale myślę, że właśnie tak bym to zrobił: zacznij pisać oprogramowanie układowe tak, jak zwykle - ale upewnij się, że jest ono umieszczone w takim miejscu, aby zawsze było pierwszą rzeczą do uruchomienia, gdy urządzenie uruchamia się. Z góry głowy, niektóre funkcje, których chciałbym z tego małego programu: możliwość wgrania nowego programu do dostępnego miejsca w pamięci, kasowanie wcześniej przesłanego programu, wybór programu do uruchomienia (jeśli jest więcej niż jeden) i mieć jakąś strukturę danych do przechowywania (rosnącą tabelę skoków?), aby móc zapamiętać, gdzie są inne programy i przejść do nich. Interakcja może odbywać się za pośrednictwem UART, gdzie może prezentować bardzo proste menu terminala i możliwość przesyłania oprogramowania układowego przez ten sam kanał.

Jak jest zaprogramowany w mikrokontrolerze (jak każdy program .hex wypalony na ROM ROM AVR lub w inny sposób)?

Jeśli jest to całkowicie pusty układ bez istniejącego programu ładującego, który mógłby się sam zaktualizować, należy nagrać do FLASH w sposób podobny do opisanego przy użyciu dowolnej techniki wymaganej do osiągnięcia tego (ICSP w przypadku AVR).

Nie jest to w pełni wyczerpujące określenie „programów ładujących”. W zależności od tego, czego chcesz od jednego lub systemu, dla którego są zaprojektowane, możesz zaprojektować taki, aby przesyłać rzeczy do określonej lokalizacji w pamięci RAM zamiast FLASH i rozpocząć wykonywanie w dowolnym dowolnym miejscu w pamięci. A może chcesz taki, który może wybrać system operacyjny, który ma zostać załadowany podczas uruchamiania komputera (patrz np. Grub ). Programy ładujące dla 8-bitowych mikrokontrolerów są zwykle bardzo proste.

Uwaga na temat Arduino: Ten bootloader zarządza tylko jednym programem AFAIK, przejmuje również port szeregowy do zarządzania przesyłaniem oprogramowania układowego i innymi rzeczami .

Jon L.
źródło
Do twojej wiadomości, odpowiedź została napisana, aby odnieść się do oryginalnych punktów kuli, które zostały już zredagowane.
Jon L
3

Koncepcja modułu ładującego „boot” jest podobna do koncepcji „zalewania” pompy. Innymi słowy, potrzebujesz „czegoś”, co spowoduje załadowanie programu pod dany adres, a następnie rozpoczęcie wykonywania programu pod tym adresem. Tym czymś jest program ładujący. W najprostszym przypadku moduł ładujący „pojawia się” pod wyznaczonym adresem początkowym procesora (zero, najprawdopodobniej), ładuje program do wymaganego segmentu pamięci, przekazuje mu kontrolę i „znika”. Wygląd i zniknięcie kontrolowane są przez „zewnętrzny” sprzęt. Jedną z możliwych implementacji byłoby użycie pamięci ROM, która jest aktywowana przez reset „sprzętowy” i dezaktywowana przez reset „programowy”. Moduł ładujący w pamięci ROM może być tak prosty lub tak złożony, jak to konieczne, i musi być napisany w postaci binarnej, którą rozumie dany procesor. Jeśli przestrzeń adresowa używana przez ROM nie jest potrzebna, dezaktywacja ROM nie będzie wymagana. Oczywiście zamiast pamięci ROM można użyć EEPROM, ePROM, flash PROM itp.

Guill
źródło