Вроде бы ничего экстраордиинарного после тыкания в кнопку не происходит… Все знают, что будет идти компиляция текста скетча и полученный исполняемый код загрузится в подключенную к компьютеру плату Arduino. Но, все-таки, интересно, а какие внутренние процессы совершаются в Arduino IDE…
В раследовании воспользуемся статьей самих разработчиков…
Для определенности возьмем классический Blink и посмотрим на его превращения.
int led = 13; void setup() { pinMode(led, OUTPUT); } void loop() { digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(led, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second }
Во-первых, в среде Arduino IDE над текстом выполняются «некоторые небольшие преобразования», чтобы убедиться, что код корректен для компилятора C или C++. Это логично — мало ли что автор в скетче понаписал…
Затем текст передается компилятору, который превращает его в машиночитаемые инструкции (или объектные файлы).
После этого код линкуется вместе со стандартными Arduino библиотеками, которые предоставляют основные функции, например, digitalWrite() или Serial.print().
В результате получается готовый Intel hex файл, который содержит конкретные байты, которые должны быть записаны в память программ микросхемы на плате Arduino. Этот файл затем выгружается в плату через интерфейс USB или последовательное соединение через загрузчик микроконтроллера платы или с помощью внешнего программатора.
Какие манипуляции Arduino IDE производит над нашим скетчем:
- сначала #include «Arduino.h» добавляется перед текстом скетча. Файл находится в папке <ARDUINO>/hardware/cores/<CORE>/. Тем самым добавляются все стандартные определения ядра Arduino.
- затем добавляются все определения используемых в скетче функций. Они добавляются в текст после #include, но до определения переменных.
- в завершение, содержимое the current target’s main.cxx (описание параметров конкретной платы) добавляется в конец нашего скетча.
Компиляцию скетча производит avr-gcc. В процессе принимают участие файлы, расположенные: собственно в папке скетча, в папке определения ядра (<ARDUINO>/hardware/core/<CORE>/), в папке <ARDUINO>/hardware/tools/avr/avr/ include/, в папках библиотек (<ARDUINO>/hardware/libraries/) заголовки которых определены в скетче. Когда идет процесс проверки, в «системной директории для временных файлов» создается папка с файлами проекта (например, для нашего скетча у меня появилась папка «C:\WINDOWS\Temp\build4053678212198882370.tmp»
из всех представленных файлов нам интересен (и понятен) Blink.cpp. Он, практически, повторяет наш скетч, лишь в начале добавлен текст:
#line 1 "Blink.ino" #include "Arduino.h" void setup(); void loop(); #line 1
результат компилируется в файл с расширением .o (у нас см. файл Blink.cpp.o). Интересен также файл Blink.cpp.d, где перечислены все «работающие» файлы:
C:\WINDOWS\Temp\build4053678212198882370.tmp\Blink.cpp.o: \
C:\WINDOWS\Temp\build4053678212198882370.tmp\Blink.cpp \
C:\ProgramFiles\Arduino\hardware\arduino\cores\arduino/Arduino.h \
C:\ProgramFiles\Arduino\hardware\arduino\cores\arduino/binary.h \
...
После объединения *.o вместе с «статическими» библиотеками Arduino (выбираются только необходимые) рождается HEX файл (у нас это Blink.cpp.hex). Он то и загружается в плату Arduino. (Написано, что в процесе загрузки, файл записывается и в папку со скетчем (меню «Скетч» — «Показать папку скетчей»), но… там я его не обнаружил 🙁 ). Теоретически, HEX файл — готовый файл для прошивки программатором в любую AVR микросхему для автономного устройства…