Popularny post Matthew11 Napisano Kwiecień 9, 2021 Popularny post Udostępnij Napisano Kwiecień 9, 2021 Ten artykuł jest częścią serii "Kompilatory od podszewki" #1 - Wprowadzenie #2 - Linker i biblioteki #3 - Automatyzacja procesu kompilacji, kompilatory a mikrokontrolery (właśnie to czytasz) #4 - Programowanie mikrokontrolerów AVR z terminala W tej części Dowiesz się o różnych sposobach automatyzacji procesu budowania projektów oraz napiszesz swój własny plik Makefile. Poruszymy również temat kompilatorów dla innych architektur i zajrzymy pod maskę IDE przeznaczonego do programowania mikrokontrolerów STM32 - STM32CubeIDE. Dodatkowo przedstawimy inne przydatne narzędzia dostarczane wraz z kompilatorem. Automatyzacja procesu kompilacji Gdy kompilujemy program w celach testowych najszybciej będzie wykonać proces kompilacji bezpośrednio z konsoli. Gdy posiadamy projekt, który cały czas rośnie i składa się z wielu modułów, a każdy moduł z wielu plików wtedy kompilacja każdego pliku źródłowego w konsoli może okazać się nienajlepszym pomysłem. Dlatego w tym celu powstały dedykowane narzędzia, które automatyzują ten proces jak np. bardzo popularny CMake. Możesz też spotkać się z narzędziem o nazwie make i plikami Makefile - to narzędzie również pozwala na zautomatyzowanie procesu kompilacji. Twoje IDE, które wykorzystujesz w swoich projektach zapewne korzysta z jednego z takich narzędzi. Źródło grafiki: Designed by macrovector / Freepik Makefile i make Pliki Makefile to prosty sposób na zorganizowanie kompilacji kodu. Oczywiście możesz stworzyć specjalny skrypt, w którym będziesz utrzymywał listę komend kompilujących Twój projekt jednak na dłuższą metę nie jest to zbyt efektywne rozwiązanie. Plik Makefile zawiera między innymi reguły kompilacji projektu co pozwala za pomocą prostych wywołań narzędzia make np. wygenerować plik wynikowy czy stworzyć bibliotekę. Dlatego nie musisz pamiętać jakich opcji kompilatora musisz użyć - wywołujesz tylko jedną prostą komendę, która zbuduje za Ciebie cały projekt. Przykład Stwórzmy plik o nazwie Makefile (pliki Makefile nie mają żadnego rozszerzenia). A następnie dodajmy do niego poniższą zawartość: default: g++ -Wall -Wextra -o program main.cpp Jest to najprostsza postać pliku Makefile: znajdziemy tam regułę default, oraz polecenia w niej zawarte (wywołanie kompilatora na pliku main.cpp). Posiadając plik Makefile możemy od razu skorzystać z narzędzia make przez wywołanie w terminalu polecenia: $ make Uwaga: musimy znajdować się w katalogu z plikiem Makefile przed uruchomieniem make). W terminalu zobaczymy taki komunikat: g++ -Wall -Wextra -o program main.cpp g++: error: main.cpp: No such file or directory g++: fatal error: no input files compilation terminated. make: *** [Makefile:2: default] Error 1 W katalogu z plikiem Makefile nie ma pliku o nazwie main.cpp - dlatego otrzymaliśmy komunikat o błędach - stwórzmy taki plik i dodajmy do niego następującą zawartość: // main.cpp #include <iostream> int main(int, char*[]) { std::cout << "Hello Makefiles and make!" << std::endl; return 0; } Po ponownym uruchomieniu w terminalu narzędzia make, w tym samym katalogu co plik main.cpp pojawi się plik wykonywalny programu. Gdy wywołamy make’a bez żadnych dodatkowych argumentów wykona on pierwszą regułę z pliku Makefile - czyli w tym wypadku default. Plik Makefile może zawierać więcej reguł np.: default: g++ -Wall -Wextra -o program main.cpp clean: rm -f program main.s dump: g++ -S main.cpp W ten sposób zdefiniowaliśmy trzy reguły, gdzie każda z nich odpowiednio: kompiluje program usuwa pliki wynikowe generuje listing assemblera Chcąc np. wyczyścić projekt wywołujemy make z argumentem clean: $ make clean Warto również dodać, że make między jedną kompilacją a drugą, kompiluje tylko te pliki, które uległy zmianie (porównuje daty modyfikacji plików źródłowych i wynikowych) - co znacznie przyspiesza proces kompilacji. Przedstawiony przykład jest bardzo prosty a o tym narzędziu można napisać cały kurs, dlatego na tym zakończymy. Jednak jeśli chcesz dowiedzieć się więcej możesz przeczytać o tym całą serię artykułów na blogu cpp-polska.pl. Natomiast jeśli interesuje Cię seria dotycząca CMake to również na cpp-polska.pl znajdziesz o tym narzędziu kilka artykułów. Źródło grafiki: Tło zdjęcie utworzone przez xb100 - pl.freepik.com Kompilatory dla mikrokontrolerów Kompilując kod na Linuxie do dyspozycji mieliśmy między innymi GCC i Clang, na Windowsie mogliśmy korzystać z MSVC, Clang czy MinGW. Dlaczego nie istnieje jeden kompilator do wszystkiego? Z tego samego powodu dlaczego nie istnieje jeden procesor do wszystkiego. Każda platforma np. Windows, Linux, Android czy macOS posiada różnice, z powodu których musimy korzystać z dedykowanych kompilatorów. Z kolei procesory mogą różnić się zestawami instrukcji maszynowych, które są w stanie wykonać co może wymagać również posiadania dedykowanego kompilatora dla danej rodziny procesorów. I tak np. dla mikrokontrolerów AVR możemy używać AVR GCC Toolchain (avr-gcc) a np. dla mikrokontrolerów z rdzeniami ARM możemy skorzystać z GNU Arm Embedded Toolchain (gcc-arm-none-eabi). Takie kompilatory nazywamy kross-kompilatorami (ang. cross-compiler) - pracują na innej platformie niż ta dla której generują kod. Kompilatory dla popularnych systemów operacyjnych (jak np. wspomniany MSVC) nazywamy kompilatorami natywnymi - kompilują kod dla tej samej platformy na której pracują. Na niektóre układy jak np. RaspberryPi można kompilować programy zarówno za pomocą kompilatora natywnego (bezpośrednio na płytce) lub za pomocą kross-kompilatora na komputerze klasy PC - co z reguły jest znacznie wygodniejsze. Logo programu STM32CubeIDE. Proces programowania mikrokontrolerów ST w środowisku STM32CubeIDE STM32CubeIDE to najnowsze IDE dla STM32 od ST. Na stronie projektu przeczytamy: STM32CubeIDE is an advanced C/C++ development platform with peripheral configuration, code generation, code compilation, and debug features for STM32 microcontrollers and microprocessors. It is based on the Eclipse®/CDT framework and GCC toolchain for the development, and GDB for the debugging. Nas interesuje fragment: “It is based on (...) GCC toolchain for the development”. Co to oznacza? Oznacza to, że pisząc programy dla mikrokontrolerów ST w STM32CubeIDE będziemy tak naprawdę wykorzystywać kompilator GCC dla procesorów ARM, czyli wspomniany GNU Arm Embedded Toolchain. Jak to sprawdzić? Wystarczy w STM32CubeIDE stworzyć projekt np. dla płytki STM32 NUCLEO-F103 (model wybranej płytki nie ma tutaj żadnego znaczenia, jednak wspomniana płytka jest jedną z używanych w kursach Forbota). I następnie zbudować projekt. Interesujące nas informacje znajdziemy w wyjściu konsoli IDE: make -j8 all arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.o" arm-none-eabi-gcc "../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.d" -MT"Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.o" arm-none-eabi-gcc -mcpu=cortex-m3 -c -x assembler-with-cpp -MMD -MP -MF"Core/Startup/startup_stm32f103rbtx.d" -MT"Core/Startup/startup_stm32f103rbtx.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Startup/startup_stm32f103rbtx.o" "../Core/Startup/startup_stm32f103rbtx.s" arm-none-eabi-gcc "../Core/Src/main.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/main.d" -MT"Core/Src/main.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/main.o" arm-none-eabi-gcc "../Core/Src/stm32f1xx_hal_msp.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/stm32f1xx_hal_msp.d" -MT"Core/Src/stm32f1xx_hal_msp.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/stm32f1xx_hal_msp.o" arm-none-eabi-gcc "../Core/Src/stm32f1xx_it.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/stm32f1xx_it.d" -MT"Core/Src/stm32f1xx_it.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/stm32f1xx_it.o" arm-none-eabi-gcc "../Core/Src/syscalls.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/syscalls.d" -MT"Core/Src/syscalls.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/syscalls.o" arm-none-eabi-gcc "../Core/Src/sysmem.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/sysmem.d" -MT"Core/Src/sysmem.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/sysmem.o" arm-none-eabi-gcc "../Core/Src/system_stm32f1xx.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/system_stm32f1xx.d" -MT"Core/Src/system_stm32f1xx.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/system_stm32f1xx.o" arm-none-eabi-gcc -o "ExampleProject.elf" @"objects.list" -mcpu=cortex-m3 -T"C:\Users\Mateusz Patyk\STM32CubeIDE\workspace_1.5.0\ExampleProject\STM32F103RBTX_FLASH.ld" --specs=nosys.specs -Wl,-Map="ExampleProject.map" -Wl,--gc-sections -static --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -Wl,--end-group Finished building target: ExampleProject.elf arm-none-eabi-size ExampleProject.elf text data bss dec hex filename 3448 20 1636 5104 13f0 ExampleProject.elf Finished building: default.size.stdout arm-none-eabi-objdump -h -S ExampleProject.elf > "ExampleProject.list" Finished building: ExampleProject.list arm-none-eabi-objcopy -O binary ExampleProject.elf "ExampleProject.bin" Finished building: ExampleProject.bin Wygenerowanego wyjścia jest sporo, ale zacznijmy od pierwszej linii: make -j8 all Możemy zauważyć tutaj wywołanie make’a dla wszytskich reguł - all. Co to oznacza? Że STM32CubeIDE wykorzystuje pliki Makefile i narzędzie make do budowania programów. A konkretnie plik Makefile definiuje reguły dotyczące procesu kompilacji, generowania pliku wsadowego, listingu assemblera i drukowania rozmiaru wynikowego pliku wsadowego. Co więcej IDE wykorzystuje w pełni potencjał maszyny na której jest uruchomione - maszyna na której budowałem projekt korzystała z procesora, który posiadał 4 fizyczne rdzenie, a każdy rdzeń posiadał 2 wątki logiczne, co pozwoliło na uruchomienie 8 zadań, czyli kompilacji 8 plików źródłowych jednocześnie. Możemy ten fakt zauważyć w parametrze -j8. W wyjściu konsoli IDE możemy również zobaczyć zawartość wywołania kompilatora dla pliku main.c: arm-none-eabi-gcc "../Core/Src/main.c" -mcpu=cortex-m3 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/main.d" -MT"Core/Src/main.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/main.o" Widzimy tam, że STM32CubeIDE wywołuje kompilator z szeregiem argumentów. Daje nam to informacje o tym, że program budowany jest dla procesora z rdzeniem ARM Cortex M3 (-mcpu=cortex-m3), przy wykorzystaniu standardu C11 z rozszerzeniami GNU (-std=gnu11), dodatkowo dowiadujemy się np. że stosowana jest optymalizacja -Os oraz to, że procesor nie wspiera sprzętowo operacji zmiennoprzecinkowych - są one emulowane programowo co możemy zauważyć w argumencie -mfloat-abi=soft. Znajdziemy tam również szereg innych argumentów, których znaczenie możemy znaleźć w dokumentacji kompilatora. Co oprócz kompilacji wykonuje w tle IDE W wyjściu konsoli znajdziemy również wywołania dodatkowych narzędzi takich jak: size, objdump i objcopy: size arm-none-eabi-size ExampleProject.elf text data bss dec hex filename 3448 20 1636 5104 13f0 ExampleProject.elf Finished building: default.size.stdout objdump arm-none-eabi-objdump -h -S ExampleProject.elf > "ExampleProject.list" Finished building: ExampleProject.list objcopy arm-none-eabi-objcopy -O binary ExampleProject.elf "ExampleProject.bin" Finished building: ExampleProject.bin Podsumowując STM32CubeIDE to nic innego jak zintegrowane środowisko programistyczne, które między innymi jest nakładką na kompilator GCC. Narzędzia objcopy, objdump, size Zwykle wystarcza nam sam kompilator, ale możemy również skorzystać z dodatkowych narzędzi lub wspomóc się informacjami jakie one generują. Są one niezwykle przydatne, gdy piszemy programy dla układów wbudowanych. Ich wykorzystanie mogliśmy zobaczyć w powyższym przykładzie dotyczącym STM32CubeIDE. Warto jednak napisać o każdym z tych narzędzi nieco więcej: size to narzędzie, które pozwala na poznanie rozmiaru (w bajtach) różnych sekcji naszego programu na podstawie wygenerowanego przez kompilator pliku wynikowego, działanie narzędzia mogliśmy zobaczyć wyżej objcopy narzędzie, które pozwala na wygenerowanie pliku wsadowego dla mikrokontrolera, np. kompilując program na mikrokontroler AVR kompilator stworzy nam plik o rozszerzeniu .elf z kolei program programatora np. AVRDUDE przyjmuje plik w postaci .hex, to właśnie objcopy pozwala na wygenerowanie pliku w postaci, którą rozumie programator - podobną czynność wykonuje STM32CubeIDE objdump to z kolei narzędzie, które pozwala na wygenerowanie listingu assemblera naszego programu lub podejrzenie listy symboli jakie udostępnia konkretna biblioteka - w powyższym przykładzie STM32CubeIDE automatycznie generuje listing assemblera, podobnym narzędziem jest np. readelf Zwykle, te narzędzia dystrybuowane są wraz z kompilatorem. W tej części to już wszystko W kolejnej części napiszemy program, który będzie sterował diodą LED, następnie go zbudujemy i zaprogramujemy nim mikrokontroler ATmega328p korzystając jedynie z terminala bez użycia jakiegokolwiek zintegrowanego środowiska programistycznego. 8 Link do komentarza Share on other sites More sharing options...
Treker (Damian Szymański) Kwiecień 12, 2021 Udostępnij Kwiecień 12, 2021 @Matthew11 artykuł został właśnie zaakceptowany i jest już widoczny publicznie 🚀 Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »