AVR w Visual Studio

Visual Studio jest najlepszym środowiskiem IDE pod Windowsem. I nie tylko do windowsowych projektów czy współpracy z kompilatorami dołączonymi w zestawie. Samo IDE może być wykorzystane na różne sposoby, a szczególnie przy użyciu projektu typu Makefile, gdzie można podpiąć dowolne skrypty czy pliki make, używane do budowania projektu.

Dosyć często z tej metody korzystałem w różnych projektach. Czy to przy budowaniu sterowników do Windowsa, w czasach kiedy WinDDK dostarczał własny toolkit do tego celu, a nikt nawet nie myślał, że kiedyś będzie można wprost z Visuala tworzyć projekty kernelowe. Czy to przy zabawach z mikrokontrolerami, najczęściej AVR-ami oraz z projektami z NMake-ami i GNU Make-ami…

A wszystko dlatego, że nie wyobrażam sobie obecnie pracy z kodem, szczególnie C i C++, w innym środowisku deweloperskim. Przyzwyczaiłem się do VS, zauroczył mnie swoją funkcjonalnością i wygodą. Choć obecnie używam wersji z 2k13 to od wydania wersji 2k15 myślę o migracji. Przed obecną wersją używałem dosyć długo wersji 2k8, którą ciągle posiadam, przydaje się w różnych starszych projektach. To jednak nie mogłem nigdy się przekonać do wersji jakie wychodziły pomiędzy tymi wydaniami. Wersje .NET, 2k10, strasznie mi się nie podobały.

Może dlatego nie potrafiłem również długo popracować w Atmel Studio w wersji 6, która bazowała na wersji VS 2k10. Dokuczała mi ślamazarność, ale to głównie przy odpalaniu, poniżej już działało całkiem fajnie. Ale to głównie brak różnych możliwości i funkcji usprawniających prace z kodem i projektem, do jakich przyzwyczaiło mnie obcowanie z wersją z roku 2013, było głównym powodem niechęci do tego środowiska. Jakiś czas temu pojawiła się nowa wersja atmelowskiego środowiska oznaczona numerem 7, ale nie miałem jeszcze okazji z niej skorzystać i sprawdzić co tam nowego wymyślili, ale ponoć zaktualizowali silnik do VS 2k15.

Próbując jakieś nowe eksperymenty z kodem dla mikrokontrolerów AVR, postanowiłem nieco uporządkować środowisko i skrypty do tego używane. Do tej pory używałem różnych kombinacji plików makefile i skryptów konsolowych, edytowanych, przerabianych, na jakiś fragmentach bazujących na starym WinAVR-rze, ich modyfikacjach przeplatanych własnymi wstawkami itp.

Ostatecznie uznałem, że to dobry moment, aby wreszcie napisać własnego Makefile i kilka skryptów, a do tego przy okazji jakiś prosty project template dla Visuala. Co uwolni mnie od każdorazowego ustawiania i powtarzania tej samej pracy przy różnych projektach.

Oczywiście, jak wspomniałem, projekt oparty na plikach make idealnie daje się wkomponować w Visual C++, które to ma adekwatny typ projektu – Makefile Project, w którym podajemy linie poleceń do wywołania przy odpowiednich krokach.

vs-avr-make

Jak na załączonym obrazku, ja wywołuję prosty skrypt konsolowy, a można tutaj bezpośredni podać make-a albo cokolwiek innego.

Używany przeze mnie skrypt build.cmd w locie konwertuje format komunikatów GCC na styl akceptowany i interpretowany przez microsoftowy IDE. Dzięki temu odpowiednio interpretowane komunikaty ostrzeżeń i błędów będą prezentowane w IDE na liście błędów (jeśli ktoś używa) a także dwuklik na danym komunikacie od razu przeniesie w odpowiadające miejsce w kodzie źródłowym.

Format linii komunikatów poszczególnych środowisk wygląda tak:

gcc: <file>:line[:column]: type: <text>
vc:  <file>(line[,column]): type: <text>

A konwersji dokonuje sed, co można prosto zapisać w postaci:

make 2>&1 | sed -e "s/:\([0-9]\+\):\([0-9]\+\):/(\1,\2):/" -e "s/:\([0-9]\+\):/(\1):/"

W sumie można byłoby to dorzucić do pliku Makefile, ale że używany jest ten skrypt w wielu innych projektach, to pozostało jako osobne narzędzie.

Całym sercem jest plik Makefile, to on jest głównym powodem tego zamieszania. Udało mi się napisać własną wersję, na bazie doświadczeń, różnych wersji i fragmnetów znalezionych na dysku. W większości przewija się podobna cześć wspólna i te same standardowe, domyślne ustawienia oraz flagi, jakie używane są w większości projektów. To te części stały się fundamentem nowej wersji, gdzie zgeneryzowałem i ujednoliciłem reguły oraz ustawienia.

Finalnie powstały plik Makefile można podzielić na dwie części – cześć z ustawieniami i konfiguracją danego projektu i cześć stałą zawierającą podstawowe ustawienia oraz reguły niezbędne do procesowania budowania.

W części pierwszej standardowo należy podać niezbędne informacje o projekcie. Czyli typowo nazwy dla targetu i pamięci EEPROM programu (zmienne TARGET i EEPROM), jakie otrzymają pliki wynikowe, typ mikrokontrolera oraz jego taktowanie (MCU, CLK). Oczywiście niezbedna jest lista plików źródłowych C, C++ i ASM, a także flagi, definicje makr, biblioteki i ścieżki dla kompilatorów, linkera, programatora i innych narzędzi…

W większości tych zmiennych, gdzie można podawać listę (np. makra, ścieżki), można zapisać wartości oddzielone spacją lub innym białym znakiem, bez żadnych przełączników. One zostaną dodane automatycznie w dalszej części skryptu przy procesowaniu wszystkich ustawień dla danego narzędzia.

Druga cześć pliku Makefile zawiera standardowe, domyślne i wspólne ustawienia, jakie używane są w we wszystkich moich projektach, a także ogólne przyjęte standardy i docelowe reguły dla programu make. Tutaj raczej rzadko wymagane są jakieś modyfikacje i na razie nie wydaje mi się, abym w jakimś projekcie wymagał edycji czy modyfikacji tej części.

Zwarte reguły są typowe, umożliwiają bardzo elastyczne tworzenie wymaganych plików lub czynności. Od prostych, standardowych reguł robiących wszystko, po pojedyncze specjalistyczne reguły. Można zrobić wiele, wygenerować jedynie pliki hex lub binarne dla firmware-u lub pamięci EEPROM, pliki z wynikiem kompilatora przedstawiające kod asemblera, co może przydać się przy podglądaniu pracy kompilatora lub jakiś optymalizacjach, czy wstawkach asemblerowych. A kończąc na programowaniu urządzenia.

Mógłbym tutaj podać jakieś przykłady lub wszystkie wymienić, ale to bez sensu, myślę, że każdy choć trochę zaznajomiony z make-iem i plikami sterujących kompilacją oraz budowaniem nie będzie miał problemu z odczytaniem wszystkie z dosyć prostego kodu.

Źródła plików i skryptów można znaleźć w repozytorium AVR-Project na moim githubie. Są one częścią szablonu projektu dla Visual Studio, które przy okazji stworzyłem, aby wygodnie tworzyć nowe projekty z mikrokontrolerami AVR.

Stworzenie takiego template-a łatwo wykonać korzystając z opcji Export template…, tak też zrobiłem, a wygenerowany szablon poddałem dodatkowej modyfikacji. Można go zainstalować wrzucając do katalogu z szablonami, który w większości standardowych instalacji VS, znajduje się w podkatalogach z dokumentami użytkownika – "%USERPROFILE%\Documents\Visual Studio 20XX\Templates\. Dokładne miejsce można znaleźć w ustawieniach środowiska.

Teoretycznie powinien to być plik archiwum ZIP z plikami szablonu, ale „gołe” pliki też działają bez problemu, zatem najprościej jest zrobić klona repozytorium bezpośrednio do docelowego miejsca:

git clone https://github.com/malcom/AVR-Project.git \
	"%USERPROFILE%\Documents\Visual Studio 20XX\Templates\ProjectTemplates\AVR-Project"

Wtedy każde aktualizacje będą ograniczać się tylko do git-pull-a.

Projekt, czy sam Makefile, bazuje na toolchanie AVR-GCC i BinUtils-ach z projektu GNU, ja polecam wersję wprost od Atmela – Atmel AVR Toolchain for Windows. Do tego mogą być wymagane inne narzędzia i utilsy z systemów uniksowych, które można zdobyć z wielu źródeł (GnuWin32, MinGW, Cygwin). Wszystkie muszą być widoczne w systemie, więc odpowiednie wpisy w zmiennej systemowej PATH są wymagane.

Dodatkowo, aby móc w pełni korzystać z możliwości Visual C++ i IntelliSense, projekt wymaga ustawienia zmiennej systemowej AVR_TOOLCHAIN_INCLUDE wskazującej na katalogi z nagłówkami dla AVR-ów z używanego toolchaina. Można też ręcznie to zmienić w ustawieniach projektu. Podobnie należy postąpić z innymi dodatkowymi ścieżkami (INC_PATH) i definicjami makr (DEFS) z pliku Makefile, one też powinny znaleźć się w ustawieniach projektu. Wtedy można cieszyć się wygodą pracy w IDE.

Sam plik Makefile jest niezależny i uniwersalny, więc można korzystać z niego również w innych projektach poza Visual Studio, a skoro używa narzędzi z projektu GNU, również bez problemu na innych platformach.

Ograniczyłem się do typowego szkieletu i narzędzi oraz funkcjonalności używanych głównie przeze mnie i tylko do bazowych elementów używanych w każdym projekcie. Ale będę w miarę możliwości i potrzeb rozszerzał pliki reguł dodatkowe opcje. Do tej pory nie korzystałem z debugowania sprzętowego czy symulatorów AVR-owych, więc nie znajdzie się w Makefile żadnych z tym powiązanych elementów. Co nie znaczy, że takie nigdy się nie pojawią.

Mam nadzieje, że szablon i plik Makefile przyda się także innym, a wszelkie uwagi są mile widziane.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *