Kurs STM32 LL cz. 1. Biblioteki Low Layer, Nucleo-G071RB, STM32CubeIDE

W sieci można znaleźć wiele materiałów na temat STM32. Większość bazuje jednak na bibliotekach HAL-a, które nie pozwalają w dobrym stopniu poznać budowy i działania mikrokontrolerów. Dlatego powstał ten kurs – moja propozycja na poznanie lub pogłębienie wiedzy o STM32. Dzięki kursowi poznasz pracę z STM32 na bazie rejestrów przy użyciu niskopoziomowych bibliotek Low Layer. W pierwszej lekcji przedstawię, czym są biblioteki LL oraz jakich narzędzi i oprogramowania będziemy używali w kursie. A zatem do dzieła!

Czym są biblioteki Low Layer

Low-Layer to biblioteka dedykowana do mikrokontrolerów STM32 zawierająca zestaw funkcji zorientowanych na sprzęt. To oznacza, że sterowniki zapewniają operacje na poziomie rejestrów – stanowią formę pośrednika pomiędzy użytkownikiem a rejestrami mikrokontrolera. Zapewniają jednolite nazwy i ułatwiają poruszanie się wśród rejestrów. 

Biblioteka LL nie wymaga, jak to jest w przypadku HAL-a, dodatkowych zasobów w postaci pamięci do obsługi buforów, liczników czy wskaźników. Pozwala programować na rejestrach, dając do dyspozycji użytkownikowi zestaw nazw przyjaznych dla programisty.

Istotną informacją jest to, że biblioteki LL zostały napisane w standardzie ANSI-C, czyli są niezależne od zastosowanego kompilatora czy IDE. Poza tym kod LL jest zgodny ze standardem MISRA C®:2004.

Biblioteka LL skupia się na dostarczeniu programiście przyjaznego interfejsu z bezpośrednim dostępem do rejestrów. Są dedykowane dla osób znających strukturę STM32, ponieważ wymagają wiedzy o działaniu mikrokontrolera. W przeciwieństwie do warstwy HAL, interfejsy LL nie są dostarczane dla urządzeń peryferyjnych, w których zoptymalizowany dostęp nie jest kluczową funkcją. Nie są dostępne także dla interfejsów wymagających ciężkiej konfiguracji oprogramowania lub złożonego stosu wyższego poziomu.

Co znajdziemy w dokumentacji do biblioteki LL

W przypadku bibliotek LL, wszystkie funkcje zaczynają się od prefiksu LL, a w nazwach plików znajdziemy frazę „_ll_” np. stm32g0xx_ll_system.h. W rozdziale „Overview of low-layer drivers” dokumentacji znajdziemy dokładny opis nazewnictwa analogiczny do warstwy HAL. Ze względu na to, że warstwa LL stanowi niejako most pomiędzy rejestrami a programistą, nie mamy tutaj tak rozbudowanych funkcjonalności jak callbacki, obsługa błędów czy inicjalizacja. Programista musi zadbać o to sam.

W kolejnych rozdziałach znajdziemy opis LL dla poszczególnych układów peryferyjnych. Przy korzystaniu z tej biblioteki warto również zapoznać się z tabelą, która przedstawia porównanie nazw rejestrów z odpowiadającymi im nazwami warstwy Low-Layer. Choć nazewnictwo LL jest intuicyjne, czasami znalezienie funkcji odpowiedzialnej za ustawienie danego rejestru może być problematyczne. Wtedy rozdział „Correspondence between API registers and API low-layer driver functions” może okazać się szybkim rozwiązaniem.

Pakiet STM32CubeG0

Chociaż w dokumentacji znajdziemy liczne przykłady oraz trochę kodu, na początku nauki poszukujemy gotowych programów, które moglibyśmy wrzucić na płytkę i przeanalizować ich działanie. Producent mikrokontrolerów STM32 i w tym obszarze nie pozostawia nas bez pomocy. Pakiet STM32Cube (STM32CubeG0 w przypadku procesorów z rodziny STM32G0), zawiera liczne przykłady z użyciem biblioteki LL dostępne na różne płytki deweloperskie producenta. Możemy je pobrać bezpośrednio ze strony producenta w zakładce „Get Software”.

Jeżeli korzystamy z STM32CubeIDE i uruchamialiśmy już jakiś projekt z danej serii, paczkę tą możemy znaleźć w repozytorium CubeMX (domyślnie C:\Users\_nazwa_użytkownika_\STM32Cube\Repository”).

Znajdziemy w niej dokumentację opisującą strukturę plików LL, pliki biblioteki, bibliotek dodatkowych, jak USB, FreeRTOS czy FatFs oraz liczne przykłady. W folderze „Projects” mamy dostępne projekty dla większości płytek ewaluacyjnych STMicroelectronics – zarówno Discovery, jak i Nucleo czy EVAL.

W przypadku serii STM32G0, która jest dość nową linią w ofercie ST, projekty z przykładami dostępne są także bezpośrednio pod najnowsze środowisko STM32CubeIDE. Dzięki temu możemy w łatwy i szybki sposób zaimportować projekt, uruchomić i przetestować czy zmodyfikować. W przypadku starszych serii STM32, które były tworzone w czasie, gdy głównym środowiskiem programistycznym do STM32 był SW4STM32 lub Attolic TrueStudio, importowanie i uruchomienie projektu może wymagać dodatkowej konfiguracji.

Płytka deweloperska Nucleo-G071RB

Do przygotowania kursu wybrałem jedną z nowszych serii dostępnych w ofercie STMicroelectronics. Wykorzystamy układ STM32G071RBT6, a właściwie płytkę deweloperską Nucleo-G071RB.

Płytki Nucleo to propozycja bezpośrednio od producenta. Ze względu na cenę oraz szeroką ofertę w portfolio ST, płytki Nucleo są najczęściej wybieraną platformą do nauki STM32.

Nucleo-G071RB to płytka z serii Nucleo-64. Wykorzystuje ona mikrokontroler w obudowie LQFP w wersji 64-pinowej. Jest to pośrednia wersja wśród płytek Nucleo (dostępne są jeszcze mniejsze Nucleo-32 oraz większe Nucleo-144).

Płytki Nucleo są stosunkowo “ubogie” pod względem dostępnych elementów zewnętrznych na płytce – znacznie więcej oferują nam płytki z serii Discovery, czy bardziej profesjonalnych EVAL-Board. Na Nucleo znajdziemy jednak najważniejsze elementy potrzebne do uruchomienia samego mikrokontrolera oraz wyprowadzone wszystkie wyjścia układu, dzięki czemu zestawy te znakomicie sprawdzają się jako baza do każdego projektu.

Płytka Nucleo składa się z dwóch głównych części: programatora ST-Link oraz części z mikrokontrolerem i złączami.

ST-LINK/V2-1 to programator i debugger dedykowany do mikrokontrolerów STM32. Wspiera programowanie za pomocą interfejsu SWD. Wersja V2-1 oferuje nam możliwość pracy programatora w kilku trybach:

  • jako port wirtualny COM, co daje możliwość komunikacji za pomocą programatora i złącza micro USB np. z komputerem
  • jako pamięć masowa
  • port do programowania/debugowania

ST-LINK to tak naprawdę inny mikrokontroler z rodziny STM32 z odpowiednio przygotowanym oprogramowaniem. Programator w Nucleo został pomyślany w ten sposób, aby mógł programować nie tylko układ znajdujący się na płytce, ale także zewnętrzne mikrokontrolery. Aby zaprogramować uC na innej płytce, wystarczy podłączyć piny programatora do złącza CN4 oraz zdjąć zworki na złączu CN2.

Istotnym elementem programatora jest trójkolorowa dioda LED umieszczona w prawym górnym rogu przy złączu USB. Informuje nas o stanie pracy ST-LINK-a oraz o ewentualnych błędach. Dioda może świecić się na jeden z poniższych sposobów:

  • Miga wolno na czerwono – po włączeniu zasilania przed inicjalizacją USB
  • Miga szybko na czerwono – po pierwszej poprawnej komunikacji między komputerem a ST-LINK/V2-1
  • Świeci na czerwono – po zakończeniu inicjalizacji między komputerem a ST-LINK/V2-1
  • Świeci na zielono – po pomyślnej inicjalizacji komunikacji docelowej
  • Miga na czerwono/zielono: podczas komunikacji z uC
  • Świeci na zielono – komunikacja zakończona i pomyślna
  • Świeci na pomarańczowo – błąd komunikacji

Warto zwrócić uwagę i zapamiętać w szczególności kolor pomarańczowy – jeżeli nie działa nam program poprawnie to być może mikrokontrolerem się po prostu nie zaprogramował.

W trakcie pracy z zestawem Nucleo najczęściej będziemy sięgali do złączy. Pozwolą nam one w łatwy sposób dołączyć dodatkowe moduły do płytki. Producent przewidział dwa typy złącz: kompatybilne z Arduino Uno V3 oraz złącza ST morpho.

Złącza kompatybilne z Arduino Uno V3 to chyba najczęściej stosowany typ złącza w płytkach deweloperskich. Swoją popularność zawdzięcza platformie Arduino, ale jak możemy się domyślić, przydane jest nie tylko dla tego typu płytek. Złącza Arduino Uno V3 umieszczane są na innych zestawach deweloperskich, ponieważ dają możliwość korzystania z całej gamy modułów rozszerzeń (shieldów), jakie różni producenci tworzą z właśnie takim rozstawem pinów. Na Nucleo złącza Arduino Uno V3 wyprowadzone zostały w postaci dwóch rzędów czarnych goldpinów żeńskich i są oznaczone jako CN5, CN6, CN8 oraz CN9.

Złącza ST morpho są charakterystyczna dla zestawów Nucleo. Pod ich rozstaw tworzoną są shieldy projektowane przez firmę ST. Na złączu ST morpho mamy wyprowadzone wszystkie piny mikrokontrolera oraz dodatkowe piny 3,3 V oraz 5 V, z których możemy zasilić nasze zewnętrzne moduły.

Jak wspomniałem, płytki Nucleo nie są wyposażone w zbyt bogaty zestaw urządzeń peryferyjnych. Mimo to znajdziemy na niej kilka przydatnych elementów, o których sposobie działania warto wiedzieć.

Na początku warto wspomnieć o zasilaniu. Przy pracy z zestawem Nucleo mamy do dyspozycji dwa sposoby zasilania: przez złącze mini USB lub przez piny VIN lub E5V (podłączenie zasilania zewnętrznego). Należy pamiętać, że jeżeli chcemy skorzystać z zasilania przez źródło zewnętrzne (piny E5V lub VIN), należy zmienić położenie zworki JP5 na piny 2 i 3. Poprawne zasilanie uC sygnalizuje dioda LD3.

Opisując kwestię doprowadzanie napięcia, warto wspomnieć także o zworce IDD. Domyślnie jest ona założona, ale jej zdjęcie i podłączenie do pinów amperomierza pozwala w łatwy sposób kontrolować pobór prądu mikrokontrolera. Może to być przydatne, gdy korzystamy z trybów Low Power i chcielibyśmy zmierzyć pobór prądu.

Na płytce do dyspozycji użytkownik ma diodę LED (LD4) podłączoną do pinu PA5 oraz niebieski przycisk użytkownika (B1) podłączony do pinu PC13. Poza tym czarny przycisk pozwala na zresetowanie mikrokontrolera.

Na płytkach Nucleo producent przewidział dość elastyczny system korzystania z kwarców. Do dyspozycji mamy wewnętrzne oscylatory LSI oraz HSI, ale także zewnętrzny oscylator LSE o częstotliwości taktowania 32768 kHz. Poza tym oscylator LSE możemy podłączyć do pinu PC14 na złączu CN7. Jeżeli chodzi o oscylator HSE, możemy go podłączyć do dedykowanych pinów X3 lub przez piny PF0/PD0/PH0 na złączu CN7. Dodatkowo mamy możliwość skorzystania z sygnału taktującego z programatora (8 MHz). Przy wyborze oscylatorów należy zwrócić uwagę na odpowiednio skonfigurowane zworki Solder Bridges.

Ciekawą funkcjonalnością, jaką oferuje nam płytka Nucleo, jest możliwość korzystania z interfejsu USART2 za pomocą złącza USB. Jest on domyślnie w ten sposób skonfigurowany i znacznie ułatwia pierwsze uruchomienie komunikacji. Możemy w ten sposób użyć także innego interfejsu USART dostępnego na płytce, podłączając go do pinów TX i RX na złączu CN3 (część płytki związana z programatorem). Takie użycie wymaga właściwego skonfigurowania mostków SB13 i SB14.

W dokumentacji na stronie 26. znajdziemy także pełną tabelę z opisem konfiguracji zworek (Solder Bridges). Warto się z nią zapoznać, gdy chcemy użyć zestawu Nucleo w niestandardowy sposób.

Dokumentacja do STM32G071RB

W kursie będziemy intensywnie używali dokumentacji do mikrokontrolera. Bez niej programowanie na rejestrach nie jest możliwe. Potrzebne będą nam trzy dokumenty: Datasheet, Reference Manual i Errata. Wszystkie potrzebne pliki znajdziemy na stronie producenta.

Datasheet to najbardziej szczegółowa dokumentacja. Obejmuje kilka układów o tym samym oznaczeniu (np. STM32LG071xx) w różnych obudowach i z różnymi konfiguracjami pamięci Flash i RAM. W pliku tym znajdziemy dokładne informacje o napięciu zasilania układu, poborze prądu w różnych trybach oraz dokładna listę urządzeń peryferyjnych dostępnych w układzie.

Reference Manual to najobszerniejsza dokumentacja mikrokontrolera. Jest to absolutny niezbędnik w przypadku, jeśli chcemy programować STM32 na bazie rejestrów. W instrukcji znajdziemy opis funkcjonalności wszystkich elementów, układów peryferyjnych i interfejsów dostępnych w mikrokontrolerze. W rozdziałach dotyczących poszczególnych części uC znajdziemy informacje, w jaki sposób może być użyty dany układ oraz jak przebiega proces konfiguracji i inicjalizacji. Na końcu każdego rozdziału znajdziemy opis wszystkich rejestrów i poszczególnych bitów danego interfejsu.

Errata sheet do dokument, który zawiera błędy występujące na poziomie krzemu danego układu. Jeżeli nam coś nie działa, a sprawdziliśmy już wszystkie możliwości i jesteśmy pewni, że konfigurujemy mikrokontroler poprawnie, warto zajrzeć do Erraty. Znajdziemy tam informacje odnośnie występujących błędów w uCobostrzenia dla używania kilku interfejsów jednocześnie, ale co najważniejsze w wielu przypadkach sposób na rozwiązanie naszego problemu (Workaround). W przypadku STM32G071RB takich błędów nie ma zbyt wiele – są to raczej pewne ograniczenia, które warto mimo wszystko znać.

Środowisko STM32CubeIDE

STM32CubeIDE to zaawansowane środowisko programistyczne C/C++ dedykowane do układów z rodziny STM32. Ma wbudowaną funkcję konfiguracji urządzeń peryferyjnych, generowanie kodu, kompilację i możliwość debugowania. Opiera się na frameworku Eclipse/CDT i narzędziu GCC (kompilacja) oraz GDB (debugowanie). 

Środowisko integruje funkcje ST MCUFinder i STM32CubeMX, oferując kompleksowe rozwiązanie dla programistów STM32. Jest wygodne w obsłudze i łatwe w instalacji. Ułatwia tworzenie nowych projektów dla MCU lub płytek STM32 i budowania za pomocą dołączonego zestawu narzędzi GCC.

STM32CubeIDE ma wbudowanych wiele narzędzi, które znacznie ułatwiają pracę z mikrokontrolerami STM32. Są to m.in. analizator kompilacji i statyczny analizator stosu, które dostarczają użytkownikowi przydatnych informacji o stanie projektu i wymaganiach dotyczących pamięci. Aplikacja zawiera również standardowe i zaawansowane funkcje debugowania, w tym podgląd rejestrów rdzenia procesora, pamięci i rejestrów układów  peryferyjnych, a także podgląd zmiennych na żywo i interfejs SWV. Analizator błędów wyświetla informacje o ewentualnych problemach, jeśli błąd zostanie wyzwolony przez procesor STM32 podczas sesji debugowania.

Pierwszym krokiem do rozpoczęcia pracy z STM32CubeIDE jest pobranie i instalacja. Środowisko możemy pobrać ze strony STmicroelectronics. Przechodzimy na dół, do obszaru pobierania, gdzie wybieramy wersję odpowiednią dla naszego systemu i klikamy „Get Software”. Akceptujemy warunki licencji – STM32CubeIDE jest na wolnej licencji i można go używać także do celów komercyjnych. ST wprowadziło system pobierania plików, w którym za każdym razem, gdy chcemy pobrać jakąś aplikację lub dokumentację, musimy się zalogować (automatycznie włącza się pobieranie, wygodniejsza wersja, jeśli pobieramy pliki dosyć często) lub wpisać swoje dane w formularzu (dostajemy link do pobrania na e-mail).

Pierwszą rzeczą, o jaką zapyta nas środowisko po uruchomieniu, będzie wybór obszaru pracy, czyli tzw. ”workspace”. Bardzo ogólnie mówiąc jest to zbiór projektów umieszczonych w jednym folderze, do których mamy jednocześnie dostęp z poziomu środowiska. Otwarcie projektu spoza workspace-u będzie wymagało jego zaimportowania, albo przełączenia na innych obszar pracy. Ma to znaczenie, gdy mamy na dysku bardzo dużo projektów – pomaga utrzymać wśród nich porządek.

Podczas pracy z STM32CubeIDE mamy do dyspozycji kilka perspektyw. Zawierają one pasek menu, pasek narzędzi, widoki i edytory. Każda perspektywa jest zoptymalizowana pod kątem szczególnego rodzaju pracy. Na przykład perspektywa C/C++ jest przeznaczona do tworzenia, edytowania i budowania projektów. Perspektywa debugowania jest przeznaczona do użycia podczas debugowania kodu na sprzęcie. Każdą perspektywę można dostosować do potrzeb użytkownika. Perspektywę można zresetować w dowolnym momencie, jeśli na przykład otwarto zbyt wiele widoków lub zmieniono ich kolejność. Możliwe jest również tworzenie nowych perspektyw. Między perspektywami możemy się przełączać za pomocą ikon w prawym górnym rogu aplikacji.

A jak wyglądają podstawowe widoki w perspektywie C/C++, w której spędzamy większość czasu podczas pisania kodu?

U góry po lewej stronie znajdziemy nazwę aktualnie otwartego workspace-u oraz projektu. Poniżej widzimy menu oraz pasek narzędzi z ikonkami do kompilowania i budowania projektu, załadowania go na mikrokontroler oraz debugowania.

W lewej części okna głównego znajduje się “Project Explorer” czyli okno nawigacji projektów, gdzie dostępne mamy wszystkie projektu zaimportowane do otwartego obszaru roboczego. Tutaj możemy m.in. otworzyć, tworzyć, usuwać i kopiować pliki. 

Środkowe, a zarazem największe okno to “Editor area”. W nim wyświetlana jest zawartość plików. Tutaj piszemy kod programu.

Po prawej stronie umieszczone zostało okno “Outline view”, gdzie mamy szybki dostęp do funkcji oraz zmiennych globalnych umieszczonych w aktywnym pliku.

Na dole pod “Editor area” znajduje się “Console view”, czyli konsola robocza. Wyświetlane są w niej błędy wykryte podczas kompilacji, a także status aktualnie wykonywanych operacji – mamy w nim dostęp do logów z pracy środowiska.

W oknie obok “Console view” znajdziemy dostęp do kilku dodatkowych narzędzi wbudowanych w środowisko STM32CubeIDE – Build Analyer i Statick Stack Analyzer, gdzie mamy możliwość podejrzenia m.in. objętości wygenerowanego kodu.

Chciałbyś otrzymywać na bieżąco informacje o nowych artykułach z kursu? Zapisz się do newslettera!

TO NIE TYLKO MAIL Z INFORMACJĄ O NOWEJ LEKCJI, ALE TAKŻE DODATKOWE MATERIAŁY. NIE PRZEGAP NOWEJ TREŚCI I DODATKOWYCH BONUSÓW. PRZEJDŹ DO STRONY KURSU I PODAJ SWÓJ ADRES E-MAIL. NIE ZAPOMNIJ POTWIERDZIĆ CHĘCI DOŁĄCZENIA W PIERWSZEJ WIADOMOŚCI!

Dodaj komentarz

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