Programowanie STM32 M0 z wykorzystaniem bibliotek LL - Cz. 1: Przygotowania

Tu możesz pisać o swoich problemach z pisaniem programów w języku C/C++ dla STM.
Awatar użytkownika
ZbeeGin
User
User
Posty: 492
Rejestracja: sobota 08 lip 2017, 17:16
Lokalizacja: Śląsko-Zagłębiowska Metropolia
Kontaktowanie:

Programowanie STM32 M0 z wykorzystaniem bibliotek LL - Cz. 1: Przygotowania

Postautor: ZbeeGin » poniedziałek 03 wrz 2018, 12:13

Wstęp

W zasadzie ten temat nie miał powstać, a przynajmniej nie z Mojej ręki, ale cóż... stało się. W tym szybkim kursie chciałbym przedstawić wszystkim nie tylko mikrokontrolery STM32 z rdzeniem Cortex-M0, ale też często pomijane, stąd mało znane biblioteki Low-layer Library (w skrócie zwane LL) jakie pojawiły się obok bibliotek HAL (Hardware Abstraction Layer), które zastąpiły nieco przestarzałe już biblioteki SPL (Standard Peripherial Library).

Jak dotąd tworzenie programów dla wielu mikrokontrolerów 8-bitowych było oparte na bezpośrednim odwoływaniu się do rejestrów procesora w celu skonfigurowania lub dostępu do wbudowanych peryferii. Niekiedy nawet bez wykorzystania języków wyższego poziomu, takich jak C lub nawet Basic, skupiając się na kodzie maszynowym z wykorzystaniem asebmlera. Dziś chyba nikt nie wyobraża sobie pisania kodu maszynowego dla całej aplikacji.

Sytuacja się nieco zmieniła gdy zaczęły na rynek wchodzić nieco bardziej rozbudowane mikrokontrolery: pierwsze jednostki z rdzeniami ARM, Atmel Xmega, STM32 Cortex-M3. Szybko zorientowano się, że pisanie kodu w języku maszynowym lub bezpośrednio z wykorzystaniem odwołań do rejestrów stało się nieco nieefektywne. Zaczęły pojawiać się namiastki lub gotowe, pełne biblioteki programistyczne. Dla mikrokontrolerów Atmel były to np. biblioteki ASF (Advanced Software Framework), dla STM32 zaś wspomniane już biblioteki SPL.

Biblioteki te ewoluowały i dla układów STM32, w związku z pojawieniem się nowych układów w rodzinie, szybko wprowadzono w życie ideę bibliotek HAL. Miały one na celu ujednolicenie tworzenia programu dla każdego mikrokontrolera STM32, tak by kod był jak najbardziej przenośny i niuanse związane z inną budową wewnętrzną poszczególnych mikrokontrolerów ukryć właśnie w treści bibliotek, tak by programista widział te same, dobrze znane mu funkcje.

Przy okazji tworzenia bibliotek HAL, inżynierowie z ST przygotowali też inną bardzo ciekawą gałąź bibliotek zwanych Low-layer Library. Stanowi ona część bibliotek HAL i gdyby narysować to na grafie to stoi ona niżej i odnosi się bezpośrednio do sprzętu. Dzięki temu nie mamy aż tak dużego poziomu abstrakcji jak w bibliotekach HAL, ale również nie odwołujemy się bezpośrednio do oceanu rejestrów i bitów w nich umieszczonych. Wszystko robią za nas biblioteki LL za pomocą prostych makr, struktur i zaledwie kilku funkcji, których nazwy mówią nam już więcej co dana funkcja lub makro robi.

Właśnie tym chciałbym się zająć w tym szybkim kursie.

Środowisko

Na początek, aby wogóle zacząć należy sobie przygotować odpowiednie środowisko. Dla mikrokontrolerów STM32 powstało ich kilkanaście. Moim zdaniem najważniejsze z nich to:

- Keil ARM-MDK, który w wersji Lite dla podstawowych procesorów jest bezpłatny. Ograniczeniem jest tu ilość generowanego kodu, która wynosi 32kB. Oprócz tego jest też specjalna wersja MDK for STM32L0 and STM32F0 dla układów STM32 z rdzeniem Cortex-M0(+).
- Atollic TrueStudio, który od wersji 9.0 jest całkowicie bezpłatny ale nie obsługuje już innych procesorów poza STM32. Wszystko dlatego, że projekt został przejęty przez ST. ST obecnie zaleca używanie TrueStudio jako podstawowego środowiska.
- AC6 System Workbench for STM32 (SW4STM32), który przed przejęciem TrueStudio przez ST miał szansę stać się domyślnym środowiskiem i był przez ST wspierany.

Ja wybrałem SW4STM32 z kilku powodów. Po pierwsze, pozwala w miarę szybko rozpocząć pracę nad kodem bo samo proponuję i w dużym stopniu konfiguruje wykorzystanie biblotek SPL (jeśli są dostępne) lub HAL-LL. Ot, zaznaczamy odpowiednią opcję i biblioteki automatycznie są dołączane do projektu. Po drugie, mimo Moich prób nie udało mi się zmusić TrueStudio by korzystało z bibliotek HAL-LL bez tworzenia zalążku projektu przez specjalne narzędzie STM32CubeMX. Pomimo umieszczenia odpowiednich plików i ustawień we właściwych miejscach, kompilacja zawsze kończyła się błędami z brakiem dostępu do pewnych symboli. (Rozwiązano. Patrz niżej). Po trzecie, jest i było w pełni darmowe, i widać, że nadal się rozwija, choć brak wsparcia ze strony ST daje się już we znaki.

Oczywiście osoby znające ekosystem Eclipse lub Visual Studio jak swoją własną kieszeń mogą sobie samemu złożyć całe środowisko instalując potrzebne wtyczki i pobrać odpowiednie biblioteki.

Uwaga! SW4STM32 nie będzie działać w systemie Windows XP.

Instalacja

SW4STM32 możemy pobrać - po zalogowaniu - ze strony http://www.openstm32.org/Downloading%2B ... Binstaller Należy tylko wybrać odpowiedni instalator w zależności od tego jaki posiadamy system operacyjny. Piszę te słowa na komputerze z Windows 7 x64 więc wybiorę instalator "install_sw4stm32_win_64bits-v2.5.exe"

rys1.png

Przed instalacją należy się upewnić czy w systemie jest zainstalowana Java JRE. Bez tego instalator się nie uruchomi, ani też środowisko oparte na Eclipse nie będzie działać.

Proces instalacji jest dość prosty. Uruchamiamy instalator, akceptujemy licencję. Następnie wybieramy docelowy folder instalacji. Domyślnie będzie to "C:\Ac6\SystemWorkbench" i możemy to tak zostawić, z uwagi na mechanizmy ochrony systemów Windows.

rys2.png

Następnie program poprosi o wskazanie które składniki ma zainstalować. Jeśli już mamy w systemie zainstalowane wcześniej sterowniki do programatora ST-Link to możemy odznaczyć tą drugą opcję. Jeśli nie to zostawiamy tak jak jest.

rys3.png

Na koniec zostaje tylko wybór gdzie mają pojawić się ikony programu. Po kilku minutach ta część instalacji się zakończy i będzie można po raz pierwszy uruchomić środowisko by dokończyć proces jego tworzenia.

Podczas pierwszego uruchomienia program poprosi o wskazanie miejsca gdzie będzie przechowywał nasze projekty, tzw. workspace. W zasadzie lokalizacja może być dowolna, byle byśmy mieli pełne prawa dostępu. Ja wybrałem sobie zdecydowanie złą lokalizację w folderze "C:\Ac6\Workspace", ale na tym komputerze nie mam innego dysku i nie chciałem robić większego bałaganu. Taka lokalizacja spowoduje, że przy usuwaniu programu będziemy musieli uważać by nie skasować sobie całego dorobku razem z programem. Zatem jeśli macie inną możliwość skorzystajcie z niej.
Warto też zaznaczyć opcję poniżej by program ustawił ją jako domyślną i więcej nie pytał o wskazanie miejsca przechowywania projektów. Gdybyście chcieli przygotować kilka przestrzeni roboczych, np. jedną na gotowe projekty, a drugą na testowe to nie zaznaczajcie tej opcji. Będziecie mogli wybierać z jaką przestrzenią roboczą chcecie w danej sesji pracować.

rys4.png

Po kliknięciu OK program zostanie uruchomiony i od razu przystąpi do pobrania i instalacji minimalnego zestawu potrzebnych wtyczek. Po zakończeniu tej operacji okno Welcome możemy już zamknąć, gdyż nie będzie potrzebne.

Pierwsze co powinniśmy zrobić to przejść do menu Help -> Check for Updates, by sprawdzić czy nie ma aktualizacji od czasu wydania naszego instalatora. Jeśli są to pozwalamy je zainstalować. Teraz przechodzimy do Help -> Install new sofware bo chciałbym byście zainstalowali sobie jeszcze wtyczkę STM32CubeMX, która może okazać się przydatna.

Kierujemy przeglądarkę na adres https://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-configurators-and-code-generators/stm32cubemx.html i przechodzimy do sekcji TOOLS AND SOFTWARE klikamy na STSW-STM32095. Program przeniesie nas na inną stronę i tam na końcu strony w tabeli klikamy Get Software. Po zalogowaniu lub podaniu danych witryna udostępni nam link do odpowiedniego pliku w tabeli pod przyciskiem Download. Pobieramy archiwum ZIP, ale nie rozpakowujemy go!

rys5.png

Wracamy do System Workbench i w otwartym wcześniej oknie Install klikamy Add..., następnie w następnym oknie Archive.... Wybieramy pobrany plik "en.stsw-stm32095.zip" i OK. Teraz na liście powinno się dać zaznaczyć STM32CubeMX_Eclipse_Plugin. Po zaznaczeniu klikany dwa razy Next i po zaakceptowaniu licencji Finish. Po zainstalowaniu wtyczki restartujemy program.

rys6.png

Po ponownym uruchomieniu przechodzimy do menu Window -> Perspective -> Open perspective -> Other... i wybieramy STM32CubeMX. Jeśli wszystko zrobiliśmy dobrze to powinna się pokazać zakładka z STM32CubeMX.

rys7.png

Tam przechodzimy do Help -> Manage embeeded software packages. Dzięki niej zainstalujemy sobie już wcześniej biblioteki HAL-LL dla naszej docelowej rodziny STM32F0. Rozwijamy tą sekcję i zaznaczamy najnowszą paczkę.

rys8.png

Jeśli ktoś planuje też tworzenie kodu dla pozostałych lub innych rodzin to może od razu zaznaczyć więcej pakietów do instalacji. Teraz klikamy Install Now i czekamy aż proces się zakończy, po czym klikamy Close.

Pierwszy program

Teraz czas na to co tygrysy lubią najbardziej. "Napiszemy" pierwszy program, by sprawdzić czy wszystko działa. Aby wrócić do edycji kodu przełączamy perspektywę w prawym górnym rogu okna za pomocą ikony zaznaczonej na czerwono.

rys9.png

Na chwilę obecną Moją platformą docelową będzie płytka Nucleo z procesorem STM32F072RB. Choć założenie jest takie, by jednak stworzyć naszą µGeek-ową płytkę ewaluacyjną i na bazować na niej. Również, by nie przedłużać tej części nie będę się teraz wgłębiał w szczegóły i pokażę jak utworzyć projekt, skompilować go i uruchomić. Dzięki temu będziemy wiedzieli czy całość działa jak należy.

Wybieramy File -> New -> C Project. Otworzy się okno kreatora gdzie podamy wymagane informacje. Nazwę projektu wpiszę sobie "TUT01_01" - pierwszy program, pierwszej części - i jako typ projektu wybiorę Ac6 STM32 MCU Project. W następnym kroku zostawię wszystko tak jak jest. Teraz pora na wybór platformy docelowej. Mimo, że mam płytkę Nucleo i jest ona na liście w zakładce Board to przełączę się na zakładkę MCU i tam z listy wybiorę STM32F072RBTx, bo taki jest użyty na płytce. Chodzi o to, by podczas tworzenia projektu nie zostały dodane dodatkowe funkcje związane z tymi płytkami, bo są nam zbędne.

rys10.png
rys11.png

Pora teraz na ostatni, decydujący krok. Ponieważ chcemy użyć bibliotek HAL-LL to wybieramy je za pomocą przełącznika. Ponieważ odpowiednie pliki już pobraliśmy podczas konfigurowania STM32CubeMX to powinniśmy zauważyć tekst "Firmware xxx has been found.". Gdybyśmy tych plików nie mieli to program zaproponowałby pobranie ich udostępniając przycisk Download target firmware. Na razie resztę ustawień pozostawiamy tak jak jest i klikamy Finish.

rys12.png

W oknie Project Explorer powinien się pojawić nasz projekt. Rozwijamy go by była widoczna zawartość gałęzi "src" i tam mamy już dostępny plik "main.c". Klikamy na niego by otworzył się w edytorze obok. Na razie jest to podstawowy szablon jego zawartości z funkcja main() i pustą pętlą główną for(;;). Zaznaczamy wszystko i kasujemy, by zastąpić to naszym przykładowym kodem:

Code: Select all

/**
******************************************************************************
* @file main.c
* @author Ac6
* @version V1.0
* @date 01-December-2013
* @brief Default main function.
******************************************************************************
*/

#include "stm32f0xx.h"
#include "stm32f0xx_ll_bus.h"
#include "stm32f0xx_ll_cortex.h"
#include "stm32f0xx_ll_utils.h"
#include "stm32f0xx_ll_gpio.h"

int main(void)
{
/* konfigurujemy SysTick by można użyc funkcji opóźniającej */
/* domyślnie procesor w pełni pracuje na częstotliwosci 8MHz!! */
LL_Init1msTick(8000000);

/* włączamy zegar dla GPIOA */
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);

/* definiujemy strukturę konfiguracji portu GPIO */
LL_GPIO_InitTypeDef gpio;

/* i wypełniamy ją potrzebnymi danymi */
gpio.Pin = LL_GPIO_PIN_5;
gpio.Mode = LL_GPIO_MODE_OUTPUT;
gpio.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

/* teraz przekazujemy gotową konfigurację */
LL_GPIO_Init(GPIOA, &gpio);

for(;;){
/* ustawiamy stan wysoki na PA5 i czekamy sekundę */
LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_5);
LL_mDelay(1000);

/* ustawiamy stan niski na PA5 i czekamy sekundę */
LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_5);
LL_mDelay(1000);
}
}


Edytor wykaże w nim ok. 10 błędów, ale to normalne, gdyż jeszcze nie wie, że będziemy używać bibliotek LL zamiast HAL. Przechodzimy do Project -> Properites i w sekcji C/C++ Build zaznaczamy Settings. Tam na otwartej zakładce odnajdujemy sekcję Preprocesor. Zamieniamy symbol "USE_HAL_DRIVER" na "USE_FULL_LL_DRIVER" by uaktywniły się odpowiednie fragmenty w plikach nagłówkowych biblioteki.

rys13.png

Klikamy na Apply i poniżej na OK. Teraz wszystkie błędy powinny już zniknąć. Możemy spróbować skompilować nasz program. Klikamy na pasku narzędzi ikonę młotka - polecenie Build. Po pozytywnym zakończeniu operacji w dolnym oknie w zakładce Console powinniśmy zobaczyć raport z kompilacji z tabelą zajętości i wiadomość "<godzina> Build Finished (took <czas>)".

rys14.png

Teraz pozostało tylko wgrać nasz program do podłączonej płytki Nucleo. W tym celu odnajdujemy przycisk strzałeczki w okrągłym zielonym kółku - polecenie Run. Program zapyta nas jeszcze jaki typ aplikacji chcemy uruchomić. Wybieramy pierwszy od góry: "Ac6 STM32 C/C++ Application". Rozpocznie się proces wgrywania kodu za pomocą wbudowanego w płytkę Nucleo programatora ST-LINK. Dioda programatora zamiga na zielono i po chwili nasz program rozpocznie migać zieloną diodą połączoną z pinem PA5, co sekundę. To oznacza, że program został skompilowany poprawnie i wszystko działa jak należy.


W następnej części rozłożymy nasz pierwszy program na części pierwsze i poznamy co tam tak naprawdę się dzieje, i po co tyle linii kodu by to działało. Jak ktoś nie chce czekać na pełen opis to niech spojrzy na komentarze w kodzie.

Fin
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Ostatnio zmieniony sobota 27 paź 2018, 14:21 przez ZbeeGin, łącznie zmieniany 2 razy.

Awatar użytkownika
ZbeeGin
User
User
Posty: 492
Rejestracja: sobota 08 lip 2017, 17:16
Lokalizacja: Śląsko-Zagłębiowska Metropolia
Kontaktowanie:

Re: Programowanie STM32 M0 z wykorzystaniem bibliotek LL - Szybki kurs - Cz. 1

Postautor: ZbeeGin » czwartek 06 wrz 2018, 22:50

Dla osób które wolą środowisko Atollic TrueStudio

Po kilku bojach i przedzieraniu się przez różne źródła informacji, udało Mi się zmusić TrueStudio (wersja 9.0.1) do współpracy. Dlatego też przygotowałem krótkie uzupełnienie dla tych, którzy woleliby to środowisko. Zakładam, że w TrueStudio też została doinstalowana wtyczka STM32CubeMX i pobrane zostały już odpowiednie biblioteki. Robi się to dokładnie tak samo jak w przypadku System Workbench.

Tworzenie projektu odbywa się tam mniej więcej tak samo jak w przypadku System Workbench. Najpierw z menu File przechodzimy do New -> C Project. Otwiera się okno gdzie wprowadzamy nazwę naszego projektu TUT01_01. Wybieramy Embedded C Project i Atollic ARM Tools.
rys20.png

W następnym kroku wybieramy nasz mikrokontroler z listy dostępnych lub wpisujemy część jego nazwy by program go wyszukał.
rys21.png

W następnym kroku kreatora zostawiłem wszystkie opcje domyślnie. Na koniec został tylko wybór debuggera. W płytce Nucelo dostępny jest domyślnie ST-LINK zatem ten wybieramy.
rys22.png

Rozpocznie się proces tworzenia podstawowej struktury projektu. Teraz najważniejsza część. Przygotowanie bibliotek i plików startowych na podstawie aktualnej ich wersji z pobranej wcześniej biblioteki HAL-LL.

Właśnie przez to, że nawet w najnowszej obecnie wersji TrueStudio 9.0.1 domyślnie są tworzone pewne pliki związane z CMSIS w nieco starszej rewizji (v2.3.0) niż ta która znajduje się w najnowszych bibliotekach (v2.3.3) to pewne symbole - które i tak podobno są błędne - nie są dostępne i zostaje wygenerowana lawina błędów podczas budowania.

Jak widać na następnym zrzucie, struktura projektu pozbawiona jest plików biblioteki HAL-LL i musimy je tam umieścić samodzielnie.
rys23.png

Odnajdujemy zatem pobrane biblioteki. Domyślnie CubeMX umieszcza je w folderze <folder_użytkownika>\STM32Cube\Repository\STM32Cube_FW_F0_V1.9.0 (dla wersji 1.9.0 bibliotek). Tam odnajdujemy folder Drivers\STM32F0xx_HAL_Driver. Jego zawartość - w całości - przeciągamy do folderu STM32F0xx_HAL_Driver w strukturze projektu, zgadzając się na skopiowanie ich i nadpisanie istniejących plików, i folderów.
rys24.png

Teraz możemy postąpić dwojako by pliki związane z bibliotekami HAL nam nie przeszkadzały.

  1. Kasujemy wszystkie pliki które mają _hal_ w nazwie i zostawiamy tylko te które zawierają _ll_.
  2. Dokonujemy pewnych zmian, które pozwolą egzystować obu bibliotekom. Aby to zrobić należy:
    • w folderze Inc przemianować nazwę pliku stm32f0xx_hal_conf_template.h na stm32f0xx_hal_conf.h,
    • zmienić nazwę stm32_assert_template.h na stm32_assert.h,
    • w folderze Src przemianować nazwę pliku stm32f0xx_hal_msp_template.c na stm32f0xx_hal_msp.c,
    • w tym samym folderze usunąć pliki: stm32f0xx_hal_timebase_rtc_alarm_template.c stm32f0xx_hal_timebase_rtc_wakeup_template.c stm32f0xx_hal_timebase_tim_template.c.

Teraz rozwijamy folder CMSIS. Odnajdujemy w bibliotekach z CubeMX ten sam folder STM32Cube_FW_F0_V1.9.0\Drivers\CMSIS. Kopiujemy zwartość STM32Cube_FW_F0_V1.9.0\Drivers\CMSIS\Device\ST\STM32F0xx\Include w to samo miejsce w strukturze projektu.
rys25.png


Przechodzimy wyżej do STM32Cube_FW_F0_V1.9.0\Drivers\CMSIS\Device\ST\STM32F0xx\Source\Templates gdzie powinniśmy znaleźć plik system_stm32f0xx.c, którym zastępujemy ten sam plik w strukturze projektu w folderze src.

Wchodzimy do folderu STM32Cube_FW_F0_V1.9.0\Drivers\CMSIS\Device\ST\STM32F0xx\Source\Templates\gcc i stamtąd kopiujemy startup_stm32f072xb.s, również w to samo miejsce.
rys26.png


Pozostały tylko drobne zmiany w konfiguracji. Wchodzimy w ustawienia projektu, a tam w C/C++ Builds -> Settings, w zakładce Tool Settings odnajdujemy Symbols w sekcji Assembler oraz C Compiler i korzystając z ikony dodawania nowego symbolu, dopisujemy USE_FULL_LL_DRIVER. Następnie Apply i OK.
rys27.png

Wklejamy nasz przykładowy kod do main.c i budujemy. Tym razem wszystko powinno się zakończyć bez błędów.
rys28.png


Już naprawdę Fin (dla tej części)
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.


Wróć do „Programowanie STM w C/C++”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 2 gości