Integracja Eclipse CDT z CodeSourcery dla ARM Cortex-M3

02-21-2010 przez kwesoly Zostaw odpowiedź »

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

„${CWD}/../
Reklama

20 komentarzy

  1. Rychu pisze:

    Czy tak skonfigurowane środowisko posiada automatyczne uzupełnianie kodo tj. coś w stylu Intellisense ?

  2. admin pisze:

    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”.

  3. Rychu pisze:

    Dziękuje za odpowiedź.

  4. FAzi pisze:

    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.

  5. Proponuję aktualizację plików z moich przykładów na „nowszą” wersję (wraz z update’em powyższego opisu) [;

  6. admin pisze:

    Dzięki wielkie za cynk Freddie :) Zaraz się wezmę za te Twoje nowe plikczki i zobacze co tam nowego w nich piszczy :)

  7. wilku pisze:

    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ć :)

  8. sebastian pisze:

    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.

  9. sebastian pisze:

    Poprawka oczywiście miałem na myśli STM32F107 zamiast STM32F106.

  10. Paweł pisze:

    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!!!!

  11. marcin pisze:

    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.

  12. Andrzej pisze:

    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 .

  13. Adam pisze:

    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:

  14. Grzesiek pisze:

    Jak zrobić żeby nie ustawiać za każdym razem w ustawieniach projektu tych bibliotek ?

  15. Andrzej pisze:

    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.

  16. autechrak pisze:

    do Andrzej. Właśnie zainstalowałem i nic z tego.
    Klon ST-Link z Kamami nie działa.

  17. r06er pisze:

    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.

  18. Maks pisze:

    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.

  19. cieslo pisze:

    @maks.
    Uaktualnij CMSIS do wersji 2.1 lub zobacz https://gist.github.com/1942280

Dodaj komentarz