STM32 CubeMX w Eclipse

Napisano dnia 9.02.2019 r. o godzinie 12:00
Autor: Piotr Sperka

Wstęp

CubeMX jest ciekawym narzędziem pozwalającym szybko wygenerować kod inicjalizujący działanie wybranych peryferiów mikrokontrolera z rodziny STM32 z wykorzystaniem biblioteki HAL, a także kilku innych, jak na przykład FreeRTOS, FatFS, czy też LwIP. Zamiast mozolnie pisać „z palca” całą inicjalizację, możemy sobie szybko wyklikać konfigurację i wygenerować gotowy kod. Rozwiązanie na pewno nie idealne, jednak często szybkie i wygodne. Ma ono jednak zdecydowaną wadę dla osób wykorzystujących popularny zestaw środowiska Eclipse z toolchainem arm-none-eabi – nie generuje projektów działających bezpośrednio z takim środowiskiem. Nie znalazłem również w 100% skutecznego i działającego rozwiązania w jednym miejscu, więc poniższy opis jest syntezą kilku opisów znalezionych w Internecie. Zapraszam do lektury.

Co będzie potrzebne?

Do uruchomienia projektu wykorzystałem:

Zakładam również, że osoba, która tu trafiła, zna podstawy obsługi Eclipse, więc nie będę tłumaczył zupełnych podstaw (na przykład jak wejść w ustawienia projektu).

Tworzenie projektu

Pierwszym krokiem na naszej drodze będzie stworzenie dwóch projektów: projektu z CubeMX, oraz projektu w Eclipse, do którego zaimportujemy wygenerowane pliki z CubeMX. Tworzenia i konfiguracji projektu w CubeMX nie będę szczegółowo opisywał – jest to intuicyjne, a dodatkowo w Internecie jest pełno opisów. W skrócie wybieramy nasz mikrokontroler z obszernej listy, wyklikujemy konfigurację, i generujemy projekt. W zasadzie jedyne istotne zmiany wprowadzamy na zakładce „Project Manager”, gdzie wybieramy toolchain SW4STM32.

Teraz przejdziemy do stworzenia nowego projektu w Eclipse. Wybieramy tworzenie nowego projektu w języku C (File → New → C/C++ Project, a następnie C Managed Build), a następnie z listy po lewej wybieramy interesujący nas szablon. W moim wypadku było to Executable → STM32F2XX C/C++ Project. Na liście po prawej wybieramy ARM Cross GCC, wpisujemy nazwę projektu i opcjonalnie wybieramy lokalizację, w której zostanie zapisany. Na następnej stronie wpisujemy ilość dostępnej pamięci FLASH oraz RAM. Kolejne dwie karty pozostawiamy bez zmian, natomiast na karcie GNU ARM Cross Toolchain wybieramy Toolchain name na GNU MCU Eclipse ARM Embedded GCC (arm-none-eabi-gcc), a także wskazujemy ścieżkę do katalogu /bin naszego toolchaina. Po kliknięciu na Finish projekt zostanie wygenerowany.

Nim zaczniemy cokolwiek zmieniać, proponuję sprawdzić, czy projekt się kompiluje. W moim wypadku środowisko zgłaszało, że polecenie make nie istnieje. Rozwiązaniem jest dopisanie ścieżki do Build Tools do zmiennej PATH w ustawieniach projektu (C/C++ Build → Environment). Jeżeli projekt skompilował się bez błędów, możemy przejść dalej.

Dodawanie plików wygenerowanych przez CubeMX

Dodawanie nowych plików zaczniemy od… usunięcia niepotrzebnych z wygenerowanego (w Eclipse) projektu. Usuwamy:

  • Zawartość katalogu src (main.c oraz _write.c w moim przypadku)
  • Katalog system/src/stm32f2-stdperiph wraz z zawartością
  • Katalog system/include/stm32f2-stdperiph wraz z zawartością
  • Całą zawartość katalogu system/src/cmsis (system_stm32f2xx.c oraz vectors_stm32f2xx.c)
  • Zawartość katalogu system/include/cmsis poza plikiem cmsis_device.h
  • Całą zawartość katalogu include

Następnie przechodzimy do przekopiowania odpowiednich plików z projektu wygenerowanego przez CubeMX do naszego oczyszczonego projektu Eclipse:

  • Zawartość Drivers/CMSIS/Device/ST/STM32F2xx/Include wrzucamy do katalogu system/include/cmsis
  • Zawartość Drivers/CMSIS/Include również wrzucamy do system/include/cmsis
  • W /system/include tworzymy katalog hal i wrzucamy do niego zawartość Drivers/STM32F2xx_HAL_Driver/Inc
  • W /system/src tworzymy katalog hal i wrzucamy do niego zawartość Drivers/STM32F2xx_HAL_Driver/Src
  • Do katalogu /system/src/cmsis wrzucamy plik startup_stm32f207xx.s i zmieniamy mu rozszerzenie na „S” (wielka litera „S”).
  • Do katalogu /include wrzucamy zawartość katalogu /Inc
  • Do katalogu /src wrzucamy zawartość katalogu /Src

Nazwy katalogów i plików mogą się oczywiście nieco różnić, zależnie od tego, którą rodzinę STM32 wykorzystujemy. Podobnie katalogów może być więcej, gdy wykorzystujemy jakieś dodatkowe biblioteki, jednak tym tematem zajmę się w przyszłości. Na poniższym screenie widać, jak w moim przypadku wyglądała gotowa struktura plików.

Struktura plików projektu

Konfiguracja projektu

Ostatnim krokiem przed nami jest nieznaczna modyfikacja ustawień projektu. W ustawieniach przechodzimy do C/C++ Build → Settings → GNU ARM Cross C Compiler i zmieniamy w Includes../system/include/stm32f2-stdperiph” na „../system/include/hal„. Następnie w opcjach Preprocessor definicję USE_STDPERIPH_DRIVER zamieniamy na USE_HAL_DRIVER, natomiast definicję STM32F2XX na STM32F207xx (istotna jest wielkość liter!). Lista możliwych do wykorzystania definicji typu mikrokontrolera jest dostępna w pliku stm32f2xx.h (w przypadku rodziny STM32F2). Wybieramy odpowiednią dla naszego układu.

Takie same zmiany robimy również dla GNU ARM Cross C++ Compiler oraz GNU ARM Cross Assembler, a także dla konfiguracji Release, jeśli zmian dokonywaliśmy w konfiguracji Debug (lub odwrotnie). Czyli innymi słowy te same zmiany wprowadzamy w sześciu miejscach.

Teraz kompilujemy projekt. Jeśli wszystko wykonaliśmy poprawnie, projekt powinien zbudować się bez problemów. Jeśli nie, musimy przejrzeć zwracane błędy, zaczynając od pierwszego. Najczęściej będzie to albo brakujący plik (którego zapomnieliśmy wrzucić), albo brakująca definicja w konfiguracji.

Podsumowanie

Postępując zgodnie z powyższym opisem powinno nam się udać w kilka minut skompilować i uruchomić projekt wygenerowany z CubeMX w środowisku Eclipse z toolchainem arm-none-eabi. Mam nadzieję, że opis był wystarczająco jasny, i zaoszczędzi komuś nieco czasu i nerwów. Co prawda nie poruszyłem tematu projektu z wykorzystaniem zewnętrznych bibliotek, ale mam nadzieję, że będzie ku temu okazja w jednym z kolejnych artykułów w najbliższym czasie.