Dzisiaj gościnny wpis mojego dobrego kolegi – Krzyśka. Dzięki wielkie za chęci i poświęcony czas. Jestem przekonany, że artykuł ten zaoszczędzi wielu nieprzespanych nocy wszystkim amatorom Cortex’ów.
Wprowadzenie
Celem dzisiejszego wpisu jest prześledzenie i opisanie kroków potrzebnych do konfiguracji Środowiska Eclipse do współpracy z pakietem CodeSourcery Lite. Efektem tego połączenia jest w pełni darmowe (open-source) środowisko programistyczne.
Instalacja Code Sourcery Lite
Na stronie http://www.codesourcery.com/ znajdujemy wersję Lite pakietu. Ponieważ nawigacja w poszukiwaniu pakietu w wersji darmowej jest jak zwykle „super łatwa” podaję bardziej bezpośredni link do pobierania: http://www.codesourcery.com/sgpp/lite/arm/portal/subscription?@template=lite
Po pobraniu i uruchomieniu aplikacji (w moim przypadku arm-2009q3-68-arm-none-eabi.exe) . W przypadku pakietu Lite wybór wersji (Typical/Custom etc.) jest bez znaczenia. Warto przy wybieraniu ścieżki unikać spacji – proponowane Program Files sprawia problemy w najmniej przewidywalnym momencie. Instalator proponuje nam również dodanie swojego katalogu binarek do zmiennej PATH – warto mu na to pozwolić, gdyż i tak konieczna będzie jego obecność w tej zmiennej. Alternatywa jest ręczna modyfikacja PATH za pomocą ustawień komputera, lub stworzenie pliku bat który modyfikuje PATH i uruchamia nasze środowisko. Biorąc pod uwagę iż pakiet CodeSourcery składa się z plików nie wprowadzających konfliktów nazw (np. cs-make, arm-none-eabi-gcc) zostawienie tego zadania instalatorowi to najlepsze wyjście. Program tworzy niezliczoną ilość ikon, więc najlepiej skierować te zapędy w stronę menu start :)
Instalacja Eclipse
Kolejny krok to pobranie Eclipse IDE ze zintegrowanymi narzędziami do programowania w C/C++. Dokładniejszy opis instalacji tego programu (m.in. instalacja wymaganej Javy, dotyczący użycia MinGW, a nie CodeSourcery) w środowisku Windows można znaleźć np. w tym wpisie: Eclipse CDT – środowisko C/C++ (nie należy się nim w tym przypadku dokładnie kierować, aczkolwiek pozwala poznać podstawowe informacje na temat konfiguracji wspomnianego IDE). W tym przypadku interesuje nas tylko środowisko, więc po prostu pobieramy i rozpakowujemy w wybrane miejsce. Po rozpakowaniu eclipse znalazł się w C:\eclipse, a skrót do eclipse.exe utworzyłem dla wygody na Pulpicie. Po uruchomieniu zostaniemy poproszeni o wybór Workspace – tradycyjnie przypominam o unikaniu spacji.
Wtyczka zarządzająca projektami
Za pomocą wymienionych wyżej narzędzi można już tworzyć projekty – jednak ręczna edycja plików makefile nie jest najwygodniejszym rozwiązaniem. Dlatego kolejnym etapem jest instalacja wtyczki która będzie je automatycznie tworzyć i zarządzać projektem.
Z pośród niewielu istniejących rozwiązań wybrałem GNU ARM Eclipse plugin. Aby go zainstalować wybieramy Help->Install New Software. Update site tego plugina to: http://gnuarmeclipse.sourceforge.net/updates, taki adres wklejamy w „Work with”. Należy zwrócić uwagę na odznaczenie „Group items by category”, ponieważ nasz plugin nie ma przypisanej kategorii. Zaznaczamy plugin kontynuujemy instalacje. Oczywiście godzimy się na niepodpisane oprogramowanie i restartujemy eclipse zgodnie z sugestią.
Tworzenie pierwszego projektu
Projekty dla platformy ARM są typowymi projektami C/C++. Wybieramy więc File->New->C++ Project. Po wpisaniu dowolnej nazwy wybieramy typ projektu – ARM Cross Target Application->Empty Project. W polu Toolchains wybieramy nasze Sourcery G++ Lite. Kolejnym etapem jest wybranie dwóch możliwych wersji w których nasz program będzie kompilowany – debug, przystosowanej do pracy z JTAG i debugowania na platformie docelowej, i release, działającej z pełną wydajnością ale pozbawionej powyższych możliwości.
Kolejnym etapem jest zebra
nie podstawowych elementów potrzebnych do kompilacji i linkowania. W zależności od użytego mikrokontrolera mogą występować różnice w poniższych plikach. Te zostały przygotowane dla uC STM32F103RB.
- skryptu linkera (pliku o rozszerzeniu *.ld, zawierającym informacje jak „poskładać” kolejne pliki *.o z kompilatora w nasz plik wynikowy – czyli elf /hex)
plik ten zawiera informacje o rozmieszczeniu danych w pamięci, oraz przede wszystkim informacje o samej pamięci – początek, koniec pamięci RAM, ROM etc.
Obszerną dokumentacje możemy znaleźć w plikach zainstalowanych z CodeSourcery (./share/doc/arm-arm-none-eabi/pdf/ld.pdf) - pliku startup (czyli pliku który po skompilowaniu będzie uruchamiany po zresetowaniu procesora. Jego zawartość to Reset_Handler, zajmujący się inicjalizacją zmiennych, kopiowaniem danych FLASH->RAM dla zmiennych zainicjalizowanych, oraz uruchomieniem konstruktorów obiektów globalnych (tylko C++), funkcji main, a na koniec destruktorów obiektów globalnych(tylko C++)).
Z uwagi na złożoność asemblera procesorów Cortex-M3 warto skorzystać z gotowego pliku – np. zamieszczonego tutaj, stworzonego przez Freddiego Chopina. - Informacje o położeniu głównego stosu i o wektorach przerwań
Mikrokontroler Cortex-M3 zaraz po uruchomieniu ładuje do rejestru MSP (Main Stack Pointer) wartość spod adresu 0×00000000. Kolejna niezbędna informacja to adres funkcji inicjalizującej – Reset_Handler pochodzącej z naszego startup’u. Adres ten musi znaleźć się pod adresem 0×00000004. Pozostałe adresy w tym wektorze to procedury obsługi przerwań. W naszym przypadku wykorzystaliśmy plik vectors.c, również stworzony przez Freddiego. Poprawiono tylko nazwy metod – teraz są w pełni zgodne (-; z standardem CMSIS.
Przydatne są rownież biblioteki – przede wszystkim CMSIS zawierający define’y rejestrów naszego mikrokontrolera, oraz biblioteka peryferiów STM32F10x_StdPeriph_Lib
Wszystkie powyższe pliki można pobrać klikając tutaj – Podstawowe pliki projektu ARM Cortex-M3 STM32
W tym momencie zakładam, że w Eclipse wyświetla nam się projekt C++, pliki po pobraniu zostały rozpakowane i przeciągnięte do naszego projektu. W tej chwili okno mojego projektu wygląda tak jak na obrazkach po lewej. Oczywiście samo dodanie plików do projektu to zbyt mało aby móc zacząć pracować nad samym programem. W celu czysto doświadczalnym w tej chwili stwórzmy plik main.cpp (File->New->Source File, zwróćmy uwagę aby umieścić ten plik w głównym katalogu projektu). Jedynym plikiem związanym z naszymi bibliotekami jaki będziemy include’ować jest plik stm32f10x_conf.h, znajdujący się w głównym katalogu projektu. Za jego pośrednictwem uzyskamy dostęp do całej reszty biblioteki pobranej ze strony ST. Podsumowując, stworzony plik main cpp wygląda teraz tak:
/*
* Podstawowy plik wykorzystujący biblioteki dla STM32
*/
#include
#include
int main() {
return 0;
}
Jego kompilacja generuje błędy, związane z includowaniem plików nie podając ich pełnych ścieżek. Na szczęście nazwy plików są na tyle jednoznaczne i unikalne ze można je bez obaw dodać do domyślnie w danym projekcie przeszukiwanych ścieżek (odpowiednik przełącznika -I przy kompilacji). Ponieważ przyszłe projekty chcemy stworzyć poprzez proste skopiowanie bieżącego „szablonu”, warto podać ścieżki w takiej formie aby nie nastręczało to trudności. W tym celu często będziemy korzystać z ręcznie wpisanych ścieżek, gdyż te uzyskane poprzez wybranie odpowiednich katalogów zawierają nazwę projektu.
Aby edytować wspomniane ścieżki oraz zmieniać ustawienia kompilatora/linkera należy kliknąć w Project->Properties, następnie wybrać C/C++ Build -> Settings. Na wstępie z bieżącej konfiguracji Debug warto przełączyć się w [ All configurations ], pozwoli to nie dublować opisanej niżej pracy.
- Ustawienia preprocesora C. W zakładce ARM Sourcery Windows GCC C Compiler->Preprocessor dodajemy symbole (plus przy opcjach -D): USE_STDPERIPH_DRIVER (jeśli chcemy używać bibliotek stm32) oraz STM32F10X_MD (obowiązkowo, definiujemy rodzaj mikrokontrolera – Medium Density Line w tym wypadku). Ustawienia które tu podajemy umożliwiaja nie edytowanie bibliotecznego pliku stm32f10x.h.
- Ustawienia kompilatora C. W zakładce ARM Sourcery Windows GCC C Compiler->Directories dodajemy (każdą osobno) następujace ścieżki:
„${CWD}/../”, „${CWD}/../Libraries/CMSIS/Core/CM3″ oraz „${CWD}/../Libraries/STM32F10x_StdPeriph_Driver/inc”. Zmienna CWD czyli Current Working Directory to przy kompilacji zawsze katalog Debug/Release projektu, więc taka konstrukcja pozwala zawsze skorzystać z właściwego katalogu.
Z kolei w zakładce ARM Sourcery Windows GCC C Compiler->Optimization zaznaczamy Function sections (-ffunction-sections) i Data Sections (-fdata-sections). Moja wersja wtyczki posiada błąd – zamiast Data Sections powtórzono Function Sections. - Powyższe kroki aplikujemy również dla kompilatora C++ (analogiczne zakładki w kategorii ARM Sourcery Windows GCC C++ Compiler)
- Skrypt linkera. Plik ten (stm32f103rb_rom.ld) znajduje się w katalogu Setup. Aby był używany Po przełączeniu wybieramy ARM Sourcery Windows GCC C++ Linker -> General i w pole „Script file -T” wpisujemy wpisujemy „..\Setup\stm32f103rb_rom.ld”. Dodatkowo zaznaczamy „Remove unused sections (-XLinker –gc-sections)” (pozwoli to usunąć zbędne sekcje które powstają z każdej kompilowanej a nie używanej funkcji).
Po zastosowaniu powyższych ustawień będzie można budować obie wersje projektu. Tworzenie przy kompilacji sekcji dla każdej funkcji, i usuwanie zbędnych przy linkowaniu gwarantuje nam rozsądną wielkość pliku wynikowego, także w trybie Debug – dzięki temu bez problemu przeprowadzimy testy za pomocą JTAGa na docelowym układzie.
Po zastosowaniu powyższych ustawień budowanie projektu (Ctrl+B) powinno przebiec bez zakłóceń.
Pliki projektu wraz z ustawieniami, do użycia np. na innym komputerze można wyeksportować. Wybieramy File->Export. Następnie zaznaczamy General->Archive File i przechodzimy dalej. Zgodnie z własnym uznaniem wybieramy nazwę i rodzaj tworzonego archiwum, po czym kończymy eksport.
Podsumowanie
Stworzyliśmy szablon projektu, integrując pliki dostarczone przez STMicroelectronic, z plikami z strony www.freddiechopin.info. Takie połączenie to solidna podstawa do budowania dowolnej wielkości aplikacji an platformę STM32. Gotowy szablon można pobrać stąd: Szablon projektu dla Cortex-M3 STM32 F103RB

Czy tak skonfigurowane środowisko posiada automatyczne uzupełnianie kodo tj. coś w stylu Intellisense ?
Tak, eclipse posiada Content Assist. Sam przekopuje wszystkie katalogi z include’ami, oraz pliki projektu i tworzy sobie własny indeks wszystkich funkcji, stałych, zmiennych, klas, namespace’ów itd. i potem automatycznie podpowiada (inteligentnie, czyli w zależności od położenia kursora w kodzie podpowiada tylko nazwy elementów które mogą być użyte w danym miejscu, ze względu na zakres ich ważności) w czasie pisania kodu. Jego ustawienia można znaleźć w „Window->Preferences…->C/C++->Editor->Content Assist”. Można tam ustawić np. po ilu milisekundach od wstawienia operatora „::”, „.”, „->” ma wyświetlać listę podpowiedzi. Listę podpowiedzi można zawsze wywołać samemu skrótem „Ctrl+Space”. Dodatkowo warto przejrzeć opcje Indexer’a w „Window->Preferences…->C/C++->Indexer”.
Dziękuje za odpowiedź.
Witam wszystko fajnie opisane tylko pytanie z mojej strony. Gdzie wpisać -lm żeby działały funkcje takie jak sqrt pow itd. no i czy ma ktoś jakiś taki zgrabny plik syscalls żeby można było normalnie korzystać z sprintf’a i jemu podobnych.
Proponuję aktualizację plików z moich przykładów na „nowszą” wersję (wraz z update’em powyższego opisu) [;
Dzięki wielkie za cynk Freddie :) Zaraz się wezmę za te Twoje nowe plikczki i zobacze co tam nowego w nich piszczy :)
A ja mam drobny problem. Przerobiłem krok po kroku opis i tak:
1. Przy budowaniu projektu wywalało mi masę błędów w startup-ie dla IAR. Wywaliłem folder bo i tak nie będzie używany.
2. Pojawiły się błędy w pliku startup_stm32f10x_ld: w g_pfnVectors: nie trawił wpisów ’0′, poprawiłem na .word 0 jak w pozostałych.
3. Wywaliłem pliki startup dla ARM.
4. W plikach startup dla GCC wywala mi błąd w kodzie:
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
bład: multiple definition of `Default_Handler’ dokładniena „b Infinite_Loop” i z tym już nie wiem co zrobić :)
Witam,
Mam pytanie jak duże zmiany należy wprowadzić aby ten template można było zastosować w procesorach STM32F105, STM32F106 (rodzina Connectivity Line). Przede wszsytkim mam na myśli dodatkowe wektory przerwań oraz inicjalizację PLL’a.
Poprawka oczywiście miałem na myśli STM32F107 zamiast STM32F106.
DZIĘKI za ten artykuł!!! Już traciłem nadzieje że uda mi się odpalić cokolwiek na STM32. Po przeczytaniu poradników jakie znalazłem na necie miałem ostry mętlik w głowie. A tutaj wszystko ładnie, pięknie, krok po kroku opisane. Szkoda że wcześniej na niego nie trafiłem. Jeszcze raz dzięki!!!!
Mam problem z kompilacja projektu dla mikrokontrolera LPC2148. Zainstalowałem dokładnie tak jak mówi przewodnik. Mam pliki .ld oraz .S dla tego mikrokontrolera. Błedy wyskakują przy kompilacji pliku startowego boot.S:
cs-make all
Building file: ../boot.S
Invoking: ARM Sourcery Windows GCC Assembler
arm-none-eabi-gcc -x assembler-with-cpp -I”C:\uC\Projects\3″ -I”C:\uC\Projects\3″ -Wall -Wa,-adhlns=../boot.lst -MMD -MP -MF”boot.d” -MT”boot.d” -mcpu=arm7tdmi -gstabs -o”boot.o” „../boot.S”
c:/uc/codesourcery/bin/../lib/gcc/arm-none-eabi/4.4.1/../../../../arm-none-eabi/bin/ld.exe: warning: cannot find entry symbol _start; defaulting to 00008018
C:\DOCUME~1\Malin\USTAWI~1\Temp\ccS0uCEx.o: In function `_startup’:
../boot.S:326: undefined reference to `_data’
../boot.S:326: undefined reference to `__ctors_start__’
../boot.S:326: undefined reference to `__ctors_end__’
../boot.S:326: undefined reference to `main’
../boot.S:326: undefined reference to `__dtors_start__’
../boot.S:326: undefined reference to `__dtors_end__’
collect2: ld returned 1 exit status
cs-make: *** [boot.o] Error 1
Próbowałem zmieniać różne flagi dla kompilacji jednak nic nie pomaga. Przy czym w środowisku YAGARTO projektu kompilują mi się poprawnie. Wie ktoś jak poprawnie skonfigurować środowisko pod ten uC? Bardzo będe wdzięczny za wszelką pomoc.
Ukazała się nowa wersja darmowego środowiska opartego na Eclipse dla wszystkich procesorów z rodziny Cortex M3 . Oparte jest o CodeSourcery i obecnie obsługuje Jtag Olimex .Można pabrać wszystko z :
http://www.coocox.org .Jeszcze brak jest obsługi ST-Link,ale to kwestia czasu .
Jak ustawić eclipse żeby program kompilował się w linuxie? Te kody działają ale na windowsie a jak próbuję uruchomić w linuxie to lipa. Oto błędy które wyskakują po ctr+b:
Libraries/STM32F10x_StdPeriph_Driver/src/misc.d \
Libraries/STM32F10x_StdPeriph_Driver/src/misc.o: \
../Libraries/STM32F10x_StdPeriph_Driver/src/misc.c \
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/misc.h \
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/CMSIS/Core/CM3/stm32f10x.h \
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/CMSIS/Core/CM3/core_cm3.h \
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/CMSIS/Core/CM3/system_stm32f10x.h \
C:\eclipseworkspace\stm32F103RB_template\Debug/../stm32f10x_conf.h \
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h \
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_fsmc.h \
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h \
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rcc.h \
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h \
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_usart.h
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/misc.h:
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/CMSIS/Core/CM3/stm32f10x.h:
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/CMSIS/Core/CM3/core_cm3.h:
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/CMSIS/Core/CM3/system_stm32f10x.h:
C:\eclipseworkspace\stm32F103RB_template\Debug/../stm32f10x_conf.h:
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h:
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_fsmc.h:
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h:
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rcc.h:
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h:
C:\eclipseworkspace\stm32F103RB_template\Debug/../Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_usart.h:
Jak zrobić żeby nie ustawiać za każdym razem w ustawieniach projektu tych bibliotek ?
Jest już dostępna wersja Coocox v.1.3
( http://www.coocox.org ) z obsługą ST-Link ,KT Link i popularnego Olimex OCD Link.Wersja IDE oparta o Eclipse oraz GCC ma wiele udogodnień dla projektantów tworzących we wszystkich odmianach Cortex M3 i M0.
do Andrzej. Właśnie zainstalowałem i nic z tego.
Klon ST-Link z Kamami nie działa.
Cześć,
Postanowiłem sobie wczoraj odkurzyć zestaw STM32 VLDiscovery, który zgarnąłem już jakiś czas temu na seminarium. Niestety mam problem z instalacją plugina GNU ARM pod eclipse. Próbowałem kilku wersji wtyczki z kilkoma wersjami eclipse i nic. W związku z tym mam prośbę, czy mógłbyś udostępnić plik makefila do twojego szablonu projektu?
Z góry dzięki. Pozdrawiam.
Witam.
Super Tutorial.
Mam dość dziwny problem, ponieważ : Projekt pobrałem z Twojej stony z podsumowania i Budowanie projektu z aktywnym Debug działa bez żadnego błędu, natomiast gdy chcę zbudować projekt z aktywnym Release to wyskakują mi 3 błędy:
1. make: *** [Libraries/CMSIS/Core/CM3/core_cm3.o] Error 1
2. registers may not be the same — ‘strexb r0,r0,[r1]‘
3. registers may not be the same — ‘strexb r0,r0,[r1]‘
Tutorial studiuję już od 2 dni, skonfigurowałem już kilka swoich projektów na wzór tego tutorialu i te same błędy mi wyskakują
Proszę o jakąś wskazówkę.
Z góry dzięki.
@maks.
Uaktualnij CMSIS do wersji 2.1 lub zobacz https://gist.github.com/1942280