Jak przenieść projekt ze środowiska IAR Embedded Workbench do Atollic TrueSTUDIO – poradnik migracyjny

Szczegóły sterowania procesem budowania projektu

Mając już określone zmiany na poziomie kodu źródłowego konieczne do zbudowania projektu za pomocą nowych narzędzi, można napotkać koleją trudność. Może się mianowicie okazać, że domyślne ustawienia kompilatora nie pozwalają zbudować działającego programu lub dają w efekcie program, który działa, ale nie spełnia wymagań wydajnościowych lub dotyczących rozmiaru.

W takim przypadku ważna jest znajomość używanych narzędzi, która pozwala jak najlepiej wykorzystać ich funkcje.

Często krytyczne znaczenie ma umiejscowienie danych i kodu w układzie docelowym. Lokalizację wszystkich części aplikacji można kontrolować za pomocą skryptów konsolidatora (linkera), ale ich konstrukcja jest specyficzna dla danego zestawu narzędzi projektowych. Bardziej skomplikowane migracje mogą też wymagać przenoszenia plików binarnych i/lub bibliotek. To z kolei wymaga zrozumienia jak zbudowane są biblioteki.

Niniejszy rozdział omawia w szczegółach wszystkie poruszone tematy, umożliwiając precyzyjną kontrolę nad migrowanym projektem i dostosowanie go do własnych potrzeb.

Migracja plików sterujących budowaniem
WSKAZÓWKA

Program GCC jest tak naprawdę tylko interfejsem grupującym kilka narzędzi (preprocesor, kompilatory C i C++ oraz konsolidator). Oznacza to, że – o ile nie zostanie wymuszone wprost inne zachowanie – będzie on próbował stworzyć z wskazanych mu plików wejściowych wykonywalny plik binarny, wybierając odpowiedni „silnik” kompilacyjny i wykonując konsolidację według domyślnego skryptu konsolidatora.

W większości aplikacji wbudowanych użytkownik chce mieć szeroką kontrolę nad umiejscowieniem danych i kodu, więc konieczny jest dwustopniowy proces – osobnej kompilacji i konsolidacji. Do wygenerowania relokowalnych plików obiektowych wykorzystywany jest kompilator i asembler, a do połączenia wskazanych relokowalnych plików obiektowych w jeden plik wykonywalny – konsolidator.

 

Rys. 23. GCC - struktura

Rys. 23. GCC – struktura

 

 

Ustawienia kompilatora i sterowanie nim

Kompilatory C i C++ narzędzi GNU mają dużą liczbę opcji pozwalających użytkownikowi na dopasowanie ich pod kątem architektury układu docelowego, wymaganego stopnia optymalizacji, wykorzystania rozszerzeń języka oraz komunikatów o błędach i ostrzeżeń.

Niniejszy tekst nie omawia każdej z opcji w szczegółach – użytkownicy powinni w razie wątpliwości posługiwać się dokumentacją GCC. Omówione tu zostały opcje wymagane do przeprowadzenia podstawowej kompilacji oraz te, które związane są bezpośrednio z układem docelowym.

Prostą kompilację pliku z kodem w języku C uruchamia się wywołując komendę:

Wynikiem jest relokowalny plik obiektowy plik.o utworzony (za pomocą opcji „-c”) poprzez kompilację pliku plik.c.

Informacje dla debugera (w formacie DWARF2) można wygenerować przy pomocy parametru „-g”:

Rozdział 3.9 instrukcji GCC podaje szczegóły dotyczące dodatkowej kontroli nad generacją informacji dla debugera.

Optymalizacja

Stopień optymalizacji można dobrać za pomocą jednego z parametrów –O1, -O2, -O3 lub –Os. Odpowiadają one coraz wyższym poziomom optymalizacji wydajności numerycznej lub – w przypadku opcji –Os – optymalizacji rozmiaru kodu. Domyślne ustawienia odpowiadają wywołaniu z parametrem –O0, który zapewnia, że wygenerowany kod da się debugować, a czas kompilacji jest minimalny.

WSKAZÓWKA

Należy pamiętać, że wymienione parametry oznaczają wybór zestawu opcji, sterujących pojedynczymi krokami optymalizacyjnymi kompilatora.

Użytkownik może ustawić dodatkowe opcje ręcznie w linii poleceń, aby doprecyzować ustawiania optymalizacyjne. Parametry odpowiadające za te możliwości są wymienione w dokumentacji GCC i zwykle zaczynają się od „-f”.

Przykładem może być parametr „-fomit-frame-pointer” (wyłączający przechowywanie wskaźnika ramki przez funkcje, które go nie potrzebują), używany powszechnie przy generacji finalnej, produkcyjnej wersji kodu. Wskaźniki ramek są bowiem przydatne do debugowania, ale mogą nie być potrzebne w innych przypadkach, a ich przechowywanie wymaga poświęcenia rejestru.

Wyższe poziomy optymalizacji są zorientowane na poprawę wydajności, a nie rozmiaru kodu, co może skutkować „odwijaniem” pętli (loop unrolling) oraz nadmiernym stosowaniem inline’u (wstawiania kodu funkcji w miejscu odwołania do niej). W  przypadkach, gdy rozmiar kodu jest istotny można stosować dodatkowe parametry wywołania kompilatora, pozwalające na kontrolowanie odwijania pętli i wstawiania kodu. Przykładowe wywołanie kompilatora z użyciem tych parametrów wygląda następująco:

Szczegóły dostępnych ustawień optymalizacji są opisane w rozdziale 3.10 dokumentacji GCC.

O autorze