TT#8 Konfiguracja rozruchu – BOOT w STM32

Tworząc własną płytkę z mikrokontrolerem STM32 musimy zadbać o znacznie więcej elementów, niż przy prototypowaniu z użyciem płytek Nucleo. Aby mikrokontroler poprawnie pracował, powinniśmy dodać odpowiednie kondensatory filtrujące zasilanie, zadbać o prawidłowe podłączenie pinu resetującego, czy właściwie podłączyć zewnętrzny kwarc. Jednym z istotnych elementów jest również konfiguracja pinów BOOT. Za co one odpowiadają? O tym w dzisiejszym artykule.

Materiał jest częścią Tips and Tricks – serii artykułów dotyczących ciekawostek o STM32

czyli przydatnych, choć rzadko opisywanych elementów z ekosystemu STM32.

Piny BOOT (a właściwie piny i bity konfiguracyjne) to element konfiguracji mikrokontrolera, który odpowiada za wybór pamięci, z jakiej startuje układ po resecie. Zazwyczaj mamy do wyboru pamięć Flash (oznaczaną Main Flash memory), pamięć systemową (System memory), w której umieszczony jest fabryczny bootloader oraz pamięć SRAM.

Przy zwykłym użytkowaniu głównie korzystamy z pamięci Flash, jednak zdarzają się sytuacje, kiedy potrzebne jest uruchomienie bootloadera, aby zaktualizować program bez użycia programatora. Czasami w projektach wykorzystywana jest również pamięć SRAM do startu programu – z taką sytuacją można spotkać się np. w przypadku mikrokontrolerów z serii STM32H7, gdzie mamy do dyspozycji znacznie więcej pamięci RAM niż Flash i jesteśmy zmuszeniu wrzucać program do SRAM i z tego miejsca go uruchamiać.

Niezależnie jednak od tego, z której pamięci chcemy uruchomić program, zawsze musimy odpowiednio podłączyć i/lub skonfigurować Option Bytes tak, aby mikrokontroler startował zgodnie z naszymi założeniami. W każdej z serii STM32 sposób konfiguracji trybu BOOT wygląda trochę inaczej, dlatego przedstawię kilka przykładów, które powinny dać ogólny obraz omawianego problemu.

Najprostszymi pod względem trybów BOOT są najstarsze serie STM32 – F0, F1, F4, ale także niektóre L0, L1 i L4. W ich przypadku mamy do dyspozycji dwa piny BOOT0 oraz BOOT1 (przy obudowach z mniejszą liczbą wyprowadzeń pin BOOT1 może być zastąpiony przez bit konfiguracyjny nBOOT1). W zależności o ich stanu w momencie uruchamiania się mikrokontrolera, układ wystartuje z wybranego rodzaju pamięci.

Jak w takim razie ustawić piny i bity BOOT, aby wybrać odpowiedni rodzaj pamięci? Odpowiedź znajdziemy oczywiście w dokumentacji Reference Manual, a konkretnie w dziale „Boot configuration”. I tak w przypadku układów STM32L47x/L48x tabela przedstawia się następująco.

Jeżeli chcemy uruchomić program z pamięci głównej (Flash), wystarczy, aby na pinie BOOT0 być stan niski. Do uruchomienia bootloadera odpowiednio ustawiamy na BOOT0 stan wysoki, a na BOOT1 stan niski. W przypadku, gdy BOOT1 nie jest wyprowadzony na pinie mikrokontrolera, tabelka konfiguracyjna może wyglądać następująco (przykład dla STM32F070).

W takim przypadku, zamiast odpowiedniego stanu na pinie, musimy poprawnie skonfigurować bit nBOOT1 w obszarze Option Bytes. Warto zauważyć, że stan bitu nBOOT1 jest negacją stanu na pinie BOOT1 – stąd literka „n” przez nazwą.

Trochę więcej do analizy mamy w przypadku nowszych mikrokontrolerów z serii G0. Tutaj producent dał nam do dyspozycji możliwość korzystania zarówno z pinu zewnętrznego BOOT0, jak i z bitu konfiguracyjnego nBOOT0. Dodatkowo dostępny jest bit nBOOT1. Dlaczego tak to wygląda? Wiąże się to zazwyczaj z tym, że pin BOOT0 może być skonfigurowany jako pin funkcyjny (w starszych seriach np. F1 pin BOOT0 i BOOT1 nie miał takiej możliwości). Pracując np. jako pin I2C, stan na nim może być ciężki do ustalenia przy włączaniu układu – wówczas jeżeli nie potrzebujemy sterowania pinem BOOT0 (np. żeby uruchomić zdalnie bootloader) możemy ustawić bit nBOOT_SEL w stan wysoki i stan fizyczny na pinie BOOT0 nie będzie miał znaczenia – liczy się wtedy bit nBOOT0. Tabela konfiguracji rozruchu dla przykładowego STM32G071 przedstawia się następująco.

Jeszcze ciekawsze rozwiązanie zastosowano w procesorach z serii F7 i H7. W ich przypadku możemy skonfigurować dowolny adres startowy, który zapisujemy pod adresem BOOT_ADD0 oraz BOOT_ADD1 (wartości 16-bitowe) w Option Bytes, a następnie za pomocą stanu na pinie BOOT wybieramy jeden z adresów. Domyślnie przy BOOT0 program uruchamia się z pamięci Flash, czyli adresu 0x08000000.

W najnowszych procesorach z serii U5 mamy w dokumentacji opisane dwie tabelki konfiguracyjne do rozruchu. Tutaj interpretacja stanu pinu BOOT0 oraz bitów konfiguracyjnych zależna jest od tego, czy mamy włączony tryb TrustZone, czy nie. Przy wyłączonym trybie TZ tabela wygląda podobnie jak poprzednie – jest połączeniem konfiguracji za pomocą fizycznych wyprowadzeń i bitów konfiguracyjnych, ale z dodaną możliwością wpisania konkretnego adresu (znany już mechanizm z serii F7/H7).

W momencie włączonego trybu TrustZone, dodaną mamy możliwość rozruchu z obszaru „root security service” (RSS), czyli bezpiecznego rodzaju bootloadera stosowanego do aktualizacji oprogramowanie w niezaufanym środowisku.

W ten sposób omówiliśmy podstawowe konfiguracje związane z rozruchem („bootowaniem”) mikrokontrolerów z serii STM32. Nieprawidłowe podłączenie wyprowadzeń lub skonfigurowanie bitów w Option Bytes może skutkować m.in. tym, że mikrokontroler po wgraniu wsadu i resecie zasilania nie będzie prawidłowo działał pomimo, że bezpośrednio po zaprogramowaniu się uruchamia poprawnie. Mam nadzieję, że teraz uda Ci się uniknąć tego typu problemów przy tworzeniu własnej płytki z STM32.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *