Dlaczego potrzebujemy osobnego programu w tej samej pamięci programu flash mikrokontrolera, a konkretnie STM32F103, który nazywa się bootloaderem?
Czym wyróżnia się to, że jest oddzielone od głównego programu aplikacyjnego?
Ogólnie rzecz biorąc, czy bootloader systemu mikroprocesorowego (powiedzmy PowerPC MPC8270) wykonuje to samo zadanie, co mikrokontroler (powiedzmy ARM STM32F103), czy też wykonują zasadniczo różne zadania od siebie, a mimo to oba są nazywane „bootloaderem” ?
microcontroller
stm32
programming
flash
bootloader
alt-rose
źródło
źródło
Odpowiedzi:
Program ładujący mikrokontrolera jest odpowiedzialny za aktualizację głównego oprogramowania układowego za pośrednictwem kanału komunikacyjnego innego niż nagłówek programowania. Jest to przydatne do aktualizacji oprogramowania w terenie przez BLE, UART, I2C, karty SD, USB itp. Niezwykle niewygodne byłoby wymaganie od klientów zakupu programistów tylko w celu aktualizacji oprogramowania na swoich urządzeniach.
Powodem, dla którego bootloader jest oddzielny, jest niezawodność. Program ładujący i kod aplikacji są umieszczone w osobnych sekcjach pamięci flash, dzięki czemu kod aplikacji może zostać usunięty i ponownie napisany przez program ładujący bez zmiany czegokolwiek związanego z kodem programu ładującego.
Gdyby bootloader i aplikacja były trzymane razem, kod bootloadera musiałby zostać skopiowany do pamięci RAM, zanim będzie mógł działać, ponieważ każda aktualizacja oprogramowania układowego wymazałaby kod bootloadera we flashu. Gdyby odcięto zasilanie za pomocą kodu bootloadera w pamięci RAM, a pamięć flash została wymazana, urządzenie zostałoby zepsute.
źródło
main()
funkcją. Po włączeniu uruchamia się kod startowy bootloadera i wywołuje bootloadermain()
. Program rozruchowy sprawdza poprawność aplikacji, a następnie przeskakuje do kodu startowego aplikacji, który wywołuje program aplikacjimain()
. Kod startowy każdego programu inicjuje środowisko wykonawcze C dla odpowiedniego programu (tj. Inicjuje zmienne, stos itp.) I zazwyczaj żaden programmain()
nigdy nie wraca do kodu startowego.main
wcale.Aby proces ładowania mógł odzyskać po błędach. Załóżmy, że wystąpił błąd komunikacji lub odłączenie zasilania podczas aktualizacji. Jeśli moduł ładujący był częścią aktualizowanej aplikacji, użytkownik nie byłby w stanie spróbować ponownie bez użycia specjalnego sprzętu do ponownego załadowania modułu ładującego.
Niektóre mikrokontrolery nie mogą wykonać kodu z pamięci RAM. Jeśli moduł ładujący został zmieszany z resztą oprogramowania, nie byłoby możliwe uaktualnienie oprogramowania, ponieważ nie można usunąć stron flash, z których obecnie się uruchamiasz. Obejście polega na tym, aby najpierw wypalić nowy kod do drugiej połowy flasha, a następnie przejść do niego. Nowy kod następnie kopiuje się do pierwszej połowy flasha. Oczywiście wadą jest to, że nagrywanie flash jest zwykle powolne, a teraz, gdy musisz to zrobić dwa razy, proces ładowania może potrwać nawet dwa razy dłużej. Również to obejście ogranicza rozmiar aplikacji do nie więcej niż połowy całkowitej pamięci flash.
Dobrze napisane programy ładujące starają się sprawdzić, czy na urządzeniu istnieje prawidłowy kod, zanim spróbujemy go wykonać. Jeśli moduł ładujący i inny kod zostały zmieszane razem, to skąd masz pewność, że procedura sprawdzania poprawności zadziała, jeśli cały kod nie zostanie załadowany?
Poświadczenie. Bezpieczne moduły ładujące próbują sprawdzić, czy załadowana aplikacja odpowiada podpisowi cyfrowemu przed uruchomieniem. Ale jeśli moduł ładujący i inny kod zostały zmieszane razem, nie można kontrolować, co działa na urządzeniu, ponieważ po załadowaniu nowego kodu przez użytkownika nie można kontrolować, co dzieje się podczas uruchamiania.
źródło
Są one ogólnie dostępne, aby umożliwić aktualizację głównego programu aplikacji.
Potrzebujesz kodu, który wie, jak wymazać i przeprogramować część wewnętrznej pamięci flash, co nie może być głównym programem, ponieważ kiedy się skasuje, nie będzie mógł przeprogramować.
źródło
Bootloader pozwala MCU komunikować się z czymś innym, aby zaakceptować nowy program, zapisać go i uruchomić po resecie. Jeśli nie masz bootloadera, potrzebny jest programista, aby uzyskać dostęp do pamięci i umieścić program na swoim miejscu.
źródło
Oprócz innych poprawnych odpowiedzi na temat umożliwienia przeprogramowania głównego oprogramowania układowego z programu ładującego, kolejną zaletą oddzielenia programu ładującego jest to, że można logicznie oddzielić zadania „wykonaj raz po uruchomieniu” od kodu potrzebnego podczas działania. Następnie, gdy program ładujący zakończy swoje zadania początkowej konfiguracji, główne oprogramowanie układowe może eksmitować program ładujący z całym niepotrzebnym już kodem z pamięci, oszczędzając znaczną ilość pamięci RAM. Można to osiągnąć na inne sposoby, ale podział bootloadera / oprogramowania układowego znacznie ułatwia wiele architektur.
źródło
Krótka odpowiedź jest taka, że oprogramowanie jest niesamowite.
Możesz mieć wszystko, co bootloader jest „czystym sprzętem”. Ale o wiele łatwiej jest mieć zadania, które bootloader zapisuje jako oprogramowanie, a następnie interpretuje sprzętowo.
Zadania te mogą obejmować konfigurację sprzętu do uruchomienia „prawdziwego” oprogramowania (na przykład na Raspberry Pi (przez @ErikF)), posiadającego protokół zastępujący „prawdziwy” program przed jego uruchomieniem (sprawdź pin, jeśli ten pin jest ustawiany, a następnie ponownie flashowany prawdziwy program), a nawet konfigurowanie środowiska programowego dla „prawdziwego” programu.
W przypadku oprogramowania w mniejszej skali, po uruchomieniu pliku wykonywalnego program ładujący aplikacje przenosi takie rzeczy, jak ładowanie części danych do pamięci, czasami naprawia adresy, ustawia argumenty na główne lub inne globalne rzeczy, obraca biblioteki dostarczone przez system operacyjny i następnie przeskakuje na początek
_main
kodu. Niektóre z tych rzeczy można wykonać za pomocą programu ładującego.W mikrokontrolerze niektóre zadania, które wykonuje bootloader, można podzielić na program. Kompilator dla Twojej platformy może automatycznie wstrzykiwać kod „setup” do każdego pliku wykonywalnego.
Ale posiadanie go w bootloaderze oznacza, że ten sam kompilator może działać na innym sprzęcie, ponieważ bootloader może „ukryć” różnicę między platformami.
Do tego dochodzi fakt, że flashowanie programu głównego nie ryzykuje bootloadera (i możliwości reflashowania programu głównego), a posiadanie nietrywialnego bootloadera to świetna rzecz.
źródło
Jedną z odpowiedzi, która nie została uwzględniona, jest potrzeba oddzielenia problemów z powodu ograniczeń języka C.
Generalnie programy ładujące są napisane w połączeniu Asemblera i C, z bardzo wczesnym etapem uruchamiania w Asemblerze.
Robi się to, aby skonfigurować pewne rzeczy, takie jak:
Jest to bardzo przybliżone przybliżenie podjętych kroków i opisuję proces rozruchu ARM, znów jest inaczej dla x86 i innych architektur.
Jednak główny powód pozostaje ten sam: alokacja stosu C musi odbywać się od złożenia.
źródło
Jedną częścią pytania, na które dotychczas nie udzielono odpowiedzi, jest różnica między programami ładującymi na mikrokontrolerach i systemach mikroprocesorowych.
Mikrokontroler
Większość mikrokontrolerów ma wbudowaną pamięć ROM, która zawiera kod programu. Zmiana tego kodu zwykle wymaga urządzenia programującego, które łączy się z interfejsem programowania mikrokontrolera (np. ISP w ATMega). Ale te interfejsy programowania zwykle nie są zbyt wygodne w użyciu w porównaniu z innymi interfejsami, ponieważ mogą nie być łatwo dostępne w danym kontekście. Na przykład, chociaż prawie każdy komputer ma porty USB, interfejs SPI wymagany dla ISP jest znacznie rzadszy, a inne interfejsy, takie jak interfejs PID używany w ATXMega, są obsługiwane tylko przez dedykowany sprzęt do programowania.
Na przykład, jeśli chcesz zaktualizować oprogramowanie ze zwykłego komputera bez zewnętrznego sprzętu, możesz użyć programu ładującego, który odczytuje z innego rodzaju interfejsu (np. RS232, USB lub RS232 przez USB, jak na Arduino), aby zaprogramować urządzenie przez popularne interfejsy.
To powiedziawszy, jeśli nie potrzebujesz tej funkcji, bootloader jest całkowicie opcjonalny. Mikrokontroler nadal może uruchamiać swój kod całkowicie bez bootloadera.
Mikroprocesor
W mikroprocesorze sprawy wyglądają trochę inaczej. Podczas gdy większość mikroprocesorów jest wyposażona w pamięć ROM wystarczająco dużą dla bootloadera, te pamięci ROM nie są wystarczająco duże, aby pomieścić pełny system operacyjny. Celem bootloadera jest więc inicjalizacja sprzętu, poszukiwanie bootowalnego systemu operacyjnego, załadowanie go i uruchomienie. Bootloader jest więc kluczowy dla każdego rozruchu.
W systemach x86 / x64 ten moduł ładujący jest systemem BIOS lub UEFI (w zasadzie nowszą wersją systemu BIOS).
Czasami może nawet istnieć wiele programów ładujących działających w łańcuchu. Na przykład, jeśli masz system podwójnego rozruchu z systemami Windows i Linux, możesz skończyć z następującymi:
Tak więc w tym przypadku były trzy programy, które można uznać za bootloader. Zarówno GRUB, jak i Windows Bootloader są tam głównie po to, aby dać użytkownikowi wygodniejszą opcję wyboru rozruchu niż system BIOS / UEFI. Umożliwia także uruchamianie wielu systemów operacyjnych z tego samego dysku twardego lub nawet z tej samej partycji.
TLDR
Podczas gdy w obu systemach bootloader robi podobne rzeczy (pomagając użytkownikowi wybrać kod, który ma zostać uruchomiony), oba różnią się znacznie tym, jak to robią i co robią dokładnie.
źródło