Za namową Łukasza postanowiłem przedstawić cykl artykułów poświęconych mikrokontrolerom ARM na przykładzie ZL27ARM firmy KAMAMI, w której ulokowany jest mikrokontroler STM32 F1 03VBT6.
Obecnie na rynku można spotkać dwie pozycje książkowe, polskiego wydania, gdzie autorzy starają się w jasny i pełny sposób przedstawić programowanie mikrokontrolerów STM32. Zapewne, jak się domyślacie, treść książek pozostawia sobie wiele do życzenia mimo to, że wzajemnie się uzupełniały i tak nie obeszło się bez wielogodzinnej walki co autor miał na myśli.
Pozwólcie, że zacznę jak cała przygoda zaczęła się w moim przypadku. A było to około pół roku temu…
Wstęp
Na początek będzie wam potrzebne dobrze skonfigurowane stanowisko programistyczne. Systemem, w którym takie stanowisko stworzyłem był Windows 7 x64. Owe stanowisko składać się będzie z następujących części. Będzie to zintegrowane środowisko programistyczne czyli nasze IDE, zestaw narzędzi (kompilator, linker, zestaw bibliotek) umożliwiający poprawne debugowanie napisanego programu oraz potrzebne oprogramowanie programatora i debugera. Jeśli chodzi o środowisko programistyczne to w moim przypadku jest to Eclipse (wersja Helios), natomiast pakietem narzędzi (Toolchain) jest CodeSourcery Lite oraz debuger OpenOCD. Taki rodzaj stanowiska jest w pełni darmowy.
Toolchain
Pakiet narzędzi pobieramy ze strony producenta lub wchodzimy bezpośrednio STĄD i wybieramy EABI. Po pobraniu pakietu, przechodzimy do instalacji. Najlepiej będzie, jak zainstalujecie aplikację po prostu na dysk gdzie znajduje się system i do folderu Program Files. Jest to chyba najbezpieczniejsza lokalizacja. Warto również dodać katalog binarek do zmiennej PATH. Można na koniec sprawdzić czy Toolchain zainstalował się poprawnie. Dajemy:
Start -> Uruchom… (Run…) -> cmd
następnie wpisujemy
arm-none-eabi-gcc –version
jeśli wszystko działa poprawnie, a ścieżki dostępu do katalogu Toolchain’a nie zawierają spacji, to powinniśmy otrzymać informację zgodną z naszą wersją:
Drivery programatora
Tak się złożyło, że moim programatorem jest JtagKey2 (AndTech). Instalacja sterowników dla programatora oraz późniejsza konfiguracja debugera pod nasz programator wygląda podobnie dla wielu różnych programatorów. Najpierw pobieramy sterowniki oraz instrukcję instalacji. Instalując te sterowniki Windows powinien zapytać czy na pewno zainstalować niecertyfikowane sterowniki. Klikamy MIMO TO KONTYNUUJ. Czasami to nie wystarcza i trzeba uruchomić system ponownie w trybie niesprawdzania podpisów sterowników. Jeśli to by było mało, to można pobrać sterowniki USBFireWire_Win7, z którymi nie ma problemu.
Poprawne zainstalowanie programatora objawia się tym, że w menadżerze urządzeń pojawiają się dwie pozycje: libusb-win32 devices oraz AND-TECH JTAG adapter.
DEBUGER
Aby środowisko było darmowe, naszym debugerem będzie OpenOCD. Instalator dostępny jest TU. W Windows’ie należy odblokować OpenOCD w firewall’u. Sama instalacja nie wymaga jakiegoś szczególnego opisu. Rozpakuj plik .zip, kliknij prawym klawiszem myszy na pliku .msi i wybierz opcję zainstaluj. Postępuj zgodnie z instrukcjami instalatora.
Najważniejsze natomiast jest prawidłowe skonfigurowanie OpenOCD pod konkretny programator. Wchodzimy do folderu C:\Program Files\openocd-x64-0.5.0\interface. Znajdują się tu pliki konfiguracyjne dla obsługiwanych programatorów. Jeśli brak pliku dla naszego programatora, to należy taki plik stworzyć. W naszym przypadku będzie to jtagkey.cfg, który edytujemy notatnikiem i umieszczamy w nim następującą treść:
interface ft2232
ft2232_device_desc “Amontec JTAGkey”
ft2232_layout jtagkey
ft2232_vid_pid 0x0403 0xcff8
Oprócz konfiguracji interfejsu potrzebna jest konfiguracja target’u, czyli musimy wytłumaczyć OpenOCD jaką rodzinę mikrokontrolerów chcemy programować i tu akurat jesteśmy do przodu, bo OpenOCD posiada już gotową konfigurację dla STM32 i nie trzeba jej modyfikować. Poprawność instalacji również możemy sprawdzić. Należy jedynie wpisać w wierszu poleceń (cmd):
openocd –version
Po czym naszym oczom powinien się ukazać następujący obrazek:
ECLIPSE
Jak już wcześniej wspomniałem, osobiście korzystam z wersji Helios. Program w wersji Eclipse IDE for C/C++ Developers można ściągnąć z tej strony. Archiwum rozpakowujemy bezpośrednio na C:\eclipse, a skrót dla wygody umieszczamy na pulpicie. Przypomnę, żeby wyzbywać się spacji jeśli chodzi o ścieżkę dostępu do folderu Eclipse. Odpalamy Eclipse i czas nadszedł na doinstalowanie dodatków.
Najpierw przechodzimy do repozytorium czyli Help -> Install New Software. W pole “Work with” wpisujemy:
http://gnuarmeclipse.sourceforge.net/updates
i zaznaczamy plugin (Plug-in’y nie ma przypisanej kategorii). Odznaczamy “Group Item by Category”. Dalej postępujemy zgodnie z instalatorem. Po wszystkim restartujemy Eclipse.
Pierwszy projekt
Na początek organizujemy sobie miejsce na nasze projekty. Najlepszym wydaje się być folder Dokumenty, więc w nim tworzymy nowy folder o nazwie np. Eclipse i to będzie nasze tak zwane WORKSPACE, gdzie będą się znajdować wszystkie nasze projekty. Podobnie jak ma to miejsce dla Arduino. Potrzebne pliki postaram się dołączyć do artykułu. Jeśli już mamy zorganizowane nasze miejsce docelowe, odpalamy Eclipse i klikamy File->New->C Project.
Jako Project name niech będzie Pierwszy_projekt, jako lokacje wskazujemy wcześniej założony folder Eclipse (w moim wypadku jest to C:\Users\user\Documents\eclipse\Pierwszy_projekt), zaznaczamy typ projektu Empty Project, oraz wskazujemy na nasz Toolchain, czyli ARM Windows GCC (Sourcery G++ Lite) i od razu możemy dać Finish.
Na tym etapie minimalizujemy Eclipse’a i przechodzimy do wcześniej stworzonego folderu. Otwieramy folder naszego projektu, w którym powinny już się znajdować dwa pliki .cproject oraz .project. Uzupełniamy nasz folder o cztery dodatkowe foldery: inc, lib, scripts, src.
W folderze inc na początku powinny znajdować się dwa pliki: stm32f10x_conf.h oraz syscalls.c. Do folderu lib skopiujcie biblioteki CMSIS oraz STM32F10x_StdPeriph_Driver. Natomiast do folderu scripts należy skopiować cztery pliki: hdr_special_registers.h, startup.S, stm32f103rb_rom.ld oraz vectors.c (po długich poszukiwaniach są to jedyne pliki linkera, które mi działały – szacun dla Freediego Chopin’a). Przy ściąganiu plików linkera z internetu należy pamiętać o prawidłowym ustawieniu rozmiaru RAM oraz ROM dla naszego mikrokontrolera. Choć czasem i to nie pomaga, to zalecam skopiowanie plików, które podałem – przynajmniej dla ZL27ARM. W folderze src będzie znajdować się nasz plik main.c. W projekcie potrzebne są jeszcze dwa pliki, ale o nich później.
Przejdźmy zatem do konfiguracji projektu w Eclipse’ie. Klikamy PPM po lewej stronie na Project Explorer i dajemy Refresh. Zauważcie, że po rozwinięciu drzewka naszego projektu pojawiły się foldery oraz pliki, które przed chwilą tworzyliśmy i kopiowaliśmy. Wszystkie te pliki możemy edytować w dogodnej chwili w samym Eclipse’ie, ale na początek tego nie polecam ;P
Klikamy PPM na naszym projekcie i wybieramy Properties, a następnie ustawiamy wszystko zgodnie z poniższymi screen’ami. Dodam tylko, że większość rzeczy powinna już być ustawiona domyślnie.
Ustawiamy Preprocesor
W zakładce ARM Sourcery Windows GCC C Compiler -> Preprocessor dodajemy symbole:
- USE_STDPERIPH_DRIVER – jeżeli chcemy używać bibliotek stm32
- STM32F10X_MD – obowiązkowo, definiujemy rodzaj mikrokontrolera – Medium Density Line w przypadku STM32F103VBT6
- HSE_VALUE=8000000 – częstotliwość zegara zewnętrznego podłączonego do mikrokontrolera. Dzięki podaniu tych stałych nie będzie konieczne edytowanie pliku nagłówkowego pliku bibliotecznego stm32f10x.h
Następnie podajemy ścieżki do plików nagłówkowych. W zakładce ARM Sourcery Windows GCC C Compiler->Directories dodajemy (każdą osobno) następujące ścieżki do plików nagłówkowych:
- “${workspace_loc:/${ProjName}/lib/CMSIS/CM3/CoreSupport}”
- “${workspace_loc:/${ProjName}/lib/CMSIS/CM3/DeviceSupport/ST/STM32F10x}”
- “${workspace_loc:/${ProjName}/lib/STM32F10x_StdPeriph_Driver/inc}”
- “${workspace_loc:/${ProjName}/inc}”
Zwróćcie uwagę na kolejność (CoreSupport na samej górze itd.).
Zmienna workspace_loc zawiera ścieżkę do katalogu roboczego Eclipse, a zmienna ProjName zawiera nazwę projektu. Dzięki wykorzystaniu tych zmiennych można kopiować ustawienia. Powyższe ścieżki można zastosować również dla kompilatora C++ (analogiczne zakładki w kategorii ARM Sourcery Windows GCC C++ Compiler).
Ustawienie optymalizacji
W zakładce ARM Sourcery Windows GCC C Compiler->Optimization zaznacz Function sections (-ffunction-sections) oraz Data Sections (-fdata-sections). W niektórych wersjach wtyczki jest błąd – zamiast Data Sections powtórzono Function Sections. W czasie pracy nad projektem (Debugowanie) można wybrać poziom optymalizacji None (-O0) w celu ułatwienia debugowania, natomiast do wytworzenia kodu produkcyjnego można włączyć optymalizację kompilatora.
Ustawienia linkera
Ścieżkę do skryptu linkera można podać przy pomocy zmiennych. Wpisuje ją w pole Script file –T w zakładce ARM Sourcery Windows GCC C++ Linker -> General. Przykładowa ścieżka, to: “${workspace_loc:/${ProjName}/scripts/stm32f103rb_rom.ld}”. Dodatkowo można zaznaczyć opcję Remove unused sections (-XLinker –gc-sections), co pozwoli usunąć zbędne sekcje, które powstają z każdej kompilowanej a nie używanej funkcji.
I na koniec klikamy OK. Teraz powinniśmy mieć wszystko dobrze skonfigurowane. Czas przyszedł na dwa pliki, które powinny znaleźć się folderze projektu. Są to plik konfiguracyjny openocd.cfg oraz plik program_hardware_win.bat. Pliki można zrobić samemu, lub po prostu ode mnie skopiować. Najważniejsza jest modyfikacja powyższych plików. To wszystko, co robiliśmy wcześniej, jest jakby wytłumaczeniem co z czym się je, ponieważ każdy kolejny projekt można stworzyć bazując na ustawieniach poprzedniego pamiętając o modyfikacji dwóch wspomnianych plików. A modyfikować je można w łatwy sposób poprzez Eclipse. Pierwszy z nich openocd.cfg w moim przypadku brzmi tak:
#default ports
#wywolanie
openocd -f jtagkey.cfg -f stm32.cfg -f openocd.cfg
telnet_port 4444
init
jtag_khz 1000
init
reset
init
halt
flash write_image erase Debug/Pierwszy_projekt.hex
verify_image Debug/Pierwszy_projekt.hex
soft_reset_halt
reset run
#version
shutdown
# koniec pliku
oraz program_hardware_win.bat (klikamy na nim PPM i wybieramy Open With -> Text Editor):
#wywołanie
openocd -f interface/jtagkey.cfg -f target/stm32.cfg -f openocd.cfg
telnet_port 4444
#gdb_port 3333
#tcl_port 6666
init
jtag_khz 1000
init
reset
init
halt
flash write_image erase /Debug/Pierwszy_projekt.hex
verify_image /Debug/Pierwszy_projekt.hex
soft_reset_halt
reset run
#version
shutdown
W jednym i drugim przypadku jedyną modyfikacją jest wprowadzenie naszej nazwy projektu. Czas na pierwsze programowanie STM32. Klikamy po lewej stronie na nasz projekt PPM i wybieramy NEW -> Source File ->, wprowadzamy nazwę main i klikamy OK. Efektem będzie pojawienie się nowego pliku w folderze src. Podstawowym szkieletem każdego programu dla STM32 podobnie, jak to miało miejsce dla Arduino, jest:
1 2 3 4 5 6 7 8 9 10 |
#include "stm32f10x.h" //implementacja podstawowych bibliotek #include int main(void){ //zainicjowanie głównego programu while(1){ //główna pętla nieskończona } return 0; } |
Program nasz nie robi właściwie nic, ale już na tym etapie możemy sprawdzić czy nasze środowisko programistycznie poprawnie kompiluje kody źródłowe i w tym celu (po wprowadzeniu podstawowego szkieletu) klikamy na zakładkę tytułową naszego programu z napisem main.c, a następnie Project -> Build Project. Jeśli wszystko zadziałało jak trzeba i nie wyskoczył żaden błąd, to po lewej powinniśmy w naszym projekcie ujrzeć dwa foldery Binaries (tu znajduje się nasz plik wynikowy w formacie .elf) oraz folder Debug gdzie, jak nazwa wskazuje, znajduje się nasz projekt już zdebugowany wraz z plikiem wynikowym (może lepiej nazwać go wsadem do naszego mikrokontrolera) w rozszerzeniu .hex.
Następnie wsad trzeba wsadzić ;P i do tego użyjemy naszego pliku wsadowego program_hardware_win.bat. Programator JTAG podłączamy do ZL27ARM, w programatorze usuwamy zworkę lub przestawiamy w pozycję neutralną (to tak na wszelki wypadek), podłączamy również zasilacz i przestawiamy włącznik na ON. Programator łączymy z PC poprzez USB i jeśli wszystko gra, wchodzimy do folderu z naszym projektem i klikamy na program_hardware_win.bat dwa razy LPM. Powinno się otworzyć okno wiersza poleceń gdzie przed oczami powinna przelecieć nam masa na razie nieistotnych dla nas informacji. Jeśli nie wyskoczy błąd znaczy, że nasz program został poprawnie wgrany i mimo to, że nic nie robi, jest już na pokładzie STM32. Czasami potrzebna jest dwukrotna próba wrzucenia programu, aby wszystko działało, ale o tym to następnym razem.
I to by było na tyle. Można znaleźć w sieci wiele podobnych artykułów lepiej lub gorzej napisanych. Niewiele będą się różnić od tego, bo konfiguracja stanowiska oraz samego środowiska wygląda podobnie, natomiast to jest mój pierwszy artykuł dla Majsterkowa, którym chciałbym rozpocząć cykl artykułów o zabawie z STM32 tak, żeby było od samego początku do niekończącej się przygody. Dlatego proszę was o wyrozumiałość, oczywiście bardzo chętnie przyjmę wasze wszelkie sugestie oraz postaram się wyjaśnić ewentualne problemy.
Życzę udanej zabawy.
Przykładowy pierwszy projekt (tu macie spakowany w *.rar przykładowy pierwszy projekt)
Hmm, a czym będzie się to różniło od STM32F0Discovery? :)
Jeszcze się Discovery nie bawiłem, więc dokładnie nie wiem, ale już mogę powiedzieć, że biblioteki będą nieco inne bo tam jest procek F0, programator jest na pokładzie chyba ST-link o ile dobrze pamiętam, więc będzie trzeba odpowiednio skonfigurować OpenOCD i ewentualnie CodeSourcery. Ogólnie rzecz biorąc wszystko będzie bardzo podobne.
A masz może ten zestaw? Jeżeli tak, to dobrze by było, gdybyś zrobił jakiś poradnik dla początkujących – niestety w sieci jest bardzo mało informacji o STM32F0Discovery :/.
Pozdrawiam
Na razie mam tylko ZL27ARM, ale poza bibliotekami, linkerem i wyposażeniem procków to przykłady nie wiele będą się różniły. To jest chyba jedyna zaleta bibliotek, że w większości przypadków są uniwersalne. Jak będę pisał o przykładowych aplikacjach to postaram się wyjaśnić mechanizm działania i wtedy sobie poradzisz z każdym STM32
Trochę się może różnić, na discovery masz inny programator (ST Link), nie wiem czy wspiera to JTAGA (chyba tylko SWD) a w konsekwencji nie wiadomo czy będzie toto chodzić. Wg tego tematu: http://www.elektroda.pl/rtvforum/topic2099956.html nie będzie chciało. Sam nie próbowałem jeszcze uruchomić, może jakoś się da.. Na razie zostaję z Keil-em i 32kB ograniczeniem wsadu… :/ Gdyby komuś udało się skonfigurować Eclipse z Discovery byłbym wdzięczny za informacje.
Piotr, Raphaw – korzystajcie z “odpowiedz”, bo się bałagan zaraz zrobi w komentarzach :)
Link na końcu artykułu nie działa. – 404
Już działa :)
Doczytałem, z dokumentacji Open OCD wynika, iż nie wspiera ST-Link-a. :(
Wersja Beta chyba już wspiera, ale nie jestem pewien
http://www.chibios.org/dokuwiki/doku.php?id=chibios:guides:stlink_eclipse
http://www.elektroda.pl/rtvforum/topic2156758.html
OpenOCD można zastąpić serwerem GDB z darmowej wersji TrueStudio.. Przepraszam, że sieję zamęt w komentarzach i obiecuję poprawę. :)
OpenOCD w wersji 0.6.1 wspiera obydwie wersje ST-link. Właściwie chyba tylko na tym programatorze nie ma problemu z SWD.
W artykule użyto zabytkowej już wersji 0.4.0
Co do wyłączania optymalizacji na etapie tworzenia to może się zdarzyć, że program po włączeniu optymalizacji tajemniczo przestaje działać wedle oczekiwać, i vice versa. Zdarzają się funkcje które zostały napisane wyłącznie dla optymalizacji 0s, co powoduje ich błędne działanie w innych przypadkach.
Całkiem ładny artykuł. Pokładam jednak w wątpliwość słuszność prezentowania kontrolerów opartych o ARM do hobbystycznych projektów małej złożoności. Włączanie światełek, przekaźników czy serwomechanizmów nie wymaga procesora 32bit z rozwiniętym zapleczem peryferyjnym. Więcej z tym problemu niż pożytku.
Faktycznie “support for STM32F3-DISCOVERY board.” Świeży news (7.10). Dziękuję!
A ja wam powiem, że artykuł bardzo fajnie napisany ale… No właśnie. Zawsze jest to ale. Łukasz zyskał sobie ogromną popularność nie tylko tym, że pisze o ciekawych rzeczach, ale też pisze do czego się te rzeczy mogą przydać. W tym artykule jest duuuużo o ARM, ale ani słowa o tym po co na co i dlaczego(a przynajmniej nie w pierwszych akapitach. Z tematu zrobiło się forum elektrody – Tylko dla specjalistów. Poza tym ceny. Wiem, że można wszystko wygóglac i wyallegrować, tyle tylko, że takie podejście odstrasza czytelników. W szczególności mobilnych. Tematy Łukasza łykam w całości, nie ważne czy mnie interesują czy nie. Ten po kilku akapitach przescrollowałem. I tu pytanie: Ile osób zrobiło tak samo?
Pozdrawiam. :)
Artykuł powstał głównie z myślą o początkujących w STM32. Jak za pewne zauważyliście mowa w nim głównie o skonfigurowaniu środowiska i niestety tyle tego jest ;P Sam również korzystam z Arduino i do prostych prototypów pakuje Nano v3. Na chwile obecną robię elektronikę pod hamownię podwoziową i tu zwykła Atmega mi nie wystarczy. Następnym razem wskaże Wam dwie aplikacje o takim samym działaniu i jedna będzie na Arduino, a druga na STM32, co nie zmieni faktu, że np. robiąc Quadcoptera na bazie Arduino będziecie mieli kupa zabawy ale i bedzie trzeba trochę wydać, natomiast Quadcopter na bazie STM32F3DISCOVERY za 80 zł to już trochę inna bajka, a efekt podobny ;]
aby bylo darmowo, to wypadalo by sie pozbyc Windowsa :)
O ile się nie mylę większość z tego oprogramowania da się odpalić na linuksie.
windowsa sponsoruje uczelnia (MSDNAA) więc jest za darmo
Witam.
Testował ktoś może OpenOCD z LPC-linkiem ?
Hej,
Najnowszy OpenOCD obsługuje całą listę LPC’eków. Rozumiem, że masz problem ze skonfigurowaniem?
Czy możesz rozwinąć porównanie budowy Quadcoptera na STM i Arduino? Czemu z arduino trzeba więcej wydać? STM jest trudniejszy w ogarnięciu?
https://www.youtube.com/watch?v=t61A5Woq_-8
https://www.youtube.com/watch?v=s1rNtl9LEFs
https://www.youtube.com/watch?v=7LAQi4vgStM
mój kurs c++ 3 części
znaczy kurs nagrałem od końca !!! na początku chciałem pokazać jak posługiwać się klasami !!! w części drugiej objaśniłem klasy użyte w części pierwszej !!! a na koniec budowa środowiska programistycznego !!! zapraszam (można hejtować jeśli kurs do bani !!! :))
nie chce być hejterem ale keipskie