Условия задачи с одной стороны сложны, с другой стороны очень просто формулируются. Есть сервер очень-очень далеко, к нему через FTDI конвертер подключена Arduino. Доступ у серверу – SSH. А надо исправлять, компилировать и заливать прошивки в плату. Классический пример — оклейка обоями запертой комнаты через замочную скважину. Очевидно ни о какой Arduino IDE, Eclipse и прочих красивых средах программирования речи быть не может.
С другой стороны — что нам стоит дом построить, нарисуем, будем жить.
Итак цель в том, чтобы создать на удаленной системе окружение, достаточное для программирования Arduino. Речи о возможной серьезной отладке конечно не идет, да и сами скетчи я пишу и отлаживаю на настольной машине в среде Eclipse, пользуясь всем тем комфортом, который дает мне уютное кресло и большой красивый монитор. Соответственно одна плата смонтирована на монтажной плате для быстрого прототипирования, а другая на далеко на сервере, можно сказать продакшн во всей красе.
Установлены стабильные пакеты последних версий.
Плата Arduino Pro Mini 328p 16МГц 5V и USB конвертер к ней на чипе FTDI
Установка в ядро поддержку USB конвертера
Как добавить поддержку модуля для FTDI конвертера в ядро описано в моей предыдущей статье, за подробностями отсылаю именно к ней, а здесь просто укажу, что нужно добавить в конфиг ядра:
Device Drivers ---> [*] USB support ---> <M> USB Serial Converter support ---> <M> USB FTDI Single Port Serial Driver
После подключения конвертера к USB должно появиться следующее устройство:
# ls -l /dev/ttyUSB0 crw-rw---- 1 root uucp, 0 марта 9 13:04 /dev/ttyUSB0
Установка окружения toolchain для компиляции
В целом все аналогично тому, что я писал ранее, но, как говорится, есть нюанс. Целевая система, использует hardened ядро и соответствующие ключи portage, поэтому простая сборка toolchain потерпит крах с ошибкой:
configure: error: *** --enable-esp is not supported on this XXXX target.
Чтобы устранить эту проблему, необходимо отключить неактуальные для целевой сборки ключи, для этого команда меняется следующим образом:
# USE="nopie nossp -hardened -pic -openmp" crossdev -S -t avr
Попутное решение проблем с некорректными путями
Как я уже писал, пути могут быть некорректны, поэтому необходимо создать символические ссылки:
# find /usr/ -name avr5.x /usr/lib64/binutils/avr/2.23.1/ldscripts/avr5.x # ln -s /usr/lib64/binutils/avr/2.23.1/ldscripts /usr/avr/lib/ldscripts # find /usr/ -name crtm328p.o /usr/avr/lib/avr5/crtm328p.o # ln -s /usr/avr/lib/avr5/crtm328p.o /usr/avr/lib/
Устанавливаем заодно программатор и minicom
# emerge dev-embedded/avrdude net-dialup/minicom
Создаем пользователя
Нам больше нечего делать в root-окружении, поэтому создаем себе простого пользователя, если его до сих пор нет, и продолжаем все остальное в его окружении. Не забудьте добавить вашего пользователя в группу uucp.
# useradd -G uucp -m -U arduino # passwd arduino # su arduino
Исходники Arduino, ничего личного лишнего
Если ставить arduino из portage, то она подтянет за собой кучу пакетов и зависимостей, ту же Java VM, и прочее, и прочее. Не вижу никакого смысла все это устанавливать, особенно если вспомнить, что целевая система серверная, где по определению не должно быть ничего лишнего.
Итак скачиваем и распаковываем исходники, для этого идем сюда arduino.cc/en/Main/Software и смотрим, что есть свеженькое. На момент написания статьи вышел релиз 1.0.4. В вашем случае версия может быть другая, поэтому, чтобы дальнейшие шаги не зависели то версии, просто переименуем каталог.
$ wget http://arduino.googlecode.com/files/arduino-1.0.4-linux32.tgz $ tar -xzvf arduino-1.0.4-linux32.tgz $ mv arduino-1.0.4 arduino
Компиляция статической библиотеки
Существует три варианта получения статической библиотеки для последующей линковки с будущими проектами.
- Установить где-нибудь полную Arduino IDE, создать в ней любой скетч, скомпилировать, найти нужный файл и стянуть. Возможно это работает, я не пробовал. Мне представляется, что степень идентичности систем должна быть высока. В общем это не наш путь.
- Компилировать ее внутри каждого проекта. Тоже сомнительное мероприятие, поскольку, см. след. пункт...
- Библиотеку можно сделать один раз, а потом линковать ее с каждым новым проектом. Как раз это полностью укладывается в наш gentoo-way.
Создаем папку для библиотеки и подключаем исходники
$ cd ~ $ mkdir ArduinoCore $ cd ArduinoCore $ mkdir src $ ln -s ~/arduino/hardware/arduino/cores/arduino/* src/
Если у вас с этим возникли проблемы, то это папка где находится файл Arduino.h и остальные заголовки и исходники, найти можно командой:
$ find ~/arduino -name Arduino.h /home/arduino/arduino/hardware/arduino/cores/arduino/Arduino.h
Кроме того нам понадобится заголовочный файл pins_arduino.h специфичный для вашего варианта платы. В моем случае имеются следующие файлы:
$ find ~/arduino -name pins_arduino.h /home/arduino/arduino/hardware/arduino/variants/micro/pins_arduino.h /home/arduino/arduino/hardware/arduino/variants/standard/pins_arduino.h /home/arduino/arduino/hardware/arduino/variants/leonardo/pins_arduino.h /home/arduino/arduino/hardware/arduino/variants/mega/pins_arduino.h /home/arduino/arduino/hardware/arduino/variants/eightanaloginputs/pins_arduino.h
Мне подходит стандартный, а вы выбирайте свой:
$ ln -s ~/arduino/hardware/arduino/variants/standard/pins_arduino.h src/
Компилируем библиотеку
Makefile я честно взял из Eclipse и поправил всего две строки, в которых были абсолютные пути вместо относительных. Фактически вся идеология взята оттуда и реализована в консоли. Берем 328P_16MHz.tgz и распаковываем в папку ~/ArduinoCore, должно получиться следующее:
$ cd ~/ArduinoCore/ $ wget https://github.com/madixi/ArduinoCore/blob/master/ArduinoCore/328P_16MHz.tgz?raw=true -O 328P_16MHz.tgz $ tar -xzvf 328P_16MHz.tgz $ ls -R ~/ArduinoCore /home/arduino/ArduinoCore: 328P_16MHz 328P_16MHz.tgz src /home/arduino/ArduinoCore/328P_16MHz: makefile objects.mk sources.mk src /home/arduino/ArduinoCore/328P_16MHz/src: subdir.mk /home/arduino/ArduinoCore/src: Arduino.h IPAddress.h Stream.h WCharacter.h malloc.c wiring_private.h CDC.cpp Platform.h Tone.cpp WInterrupts.c new.cpp wiring_pulse.c Client.h Print.cpp USBAPI.h WMath.cpp new.h wiring_shift.c HID.cpp Print.h USBCore.cpp WString.cpp pins_arduino.h HardwareSerial.cpp Printable.h USBCore.h WString.h wiring.c HardwareSerial.h Server.h USBDesc.h binary.h wiring_analog.c IPAddress.cpp Stream.cpp Udp.h main.cpp wiring_digital.c
Если у вас другая плата (другой чип) и/или другая частота, то достаточно исправить ключи компилятора в файле:
~/ArduinoCore/328P_16MHz/src/subdir.mk -mmcu=atmega328p -DF_CPU=16000000UL
Последнее что нам осталось сделать, это скомпилировать статическую библиотеку:
$ cd 328P_16MHz $ make
в итоге получится что-то похожее на:
$ ls -l ~/ArduinoCore/328P_16MHz total 592 -rw-r--r-- 1 arduino arduino 187186 Mar 18 10:18 libArduinoCore.a -rw-r--r-- 1 arduino arduino 327022 Mar 18 10:18 libArduinoCore.lss -rw-r--r-- 1 arduino arduino 2021 Mar 17 14:46 makefile -rw-r--r-- 1 arduino arduino 231 Mar 17 14:46 objects.mk -rw-r--r-- 1 arduino arduino 599 Mar 17 14:46 sources.mk drwxr-xr-x 2 arduino arduino 4096 Mar 18 10:17 src
Ради чего мы все это делали – это статическая библиотека libArduinoCore.a, которую будем линковать с будущими проектами.
Первый проект
В каждом языке программирования есть свой Hello world, в Arduino – это Blink, моргающий светодиодом, который распаян непосредственно на плате и подключен к 13-му выводу чипа. Его веселое помаргивание в итоге расскажет о том, что все получилось.
$ cd ~ $ mkdir BlinkA $ cd BlinkA
Создаем файл main.cpp
/*
* main.cpp
*
* Example: Blink 'A'-letter Morse code '.-'
*
* Created on: 15.03.2013
* Author: madixi
*/
#include <Arduino.h>
int led = 13;
void setup() {
pinMode(led, OUTPUT);
Serial.begin(9600);
Serial.println("Example: Blink 'A'-letter Morse code '.-'");
}
void loop() {
digitalWrite(led, HIGH);
delay(200);
digitalWrite(led, LOW);
delay(200);
digitalWrite(led, HIGH);
delay(600);
digitalWrite(led, LOW);
delay(200);
Serial.println("._");
}
int main(void) {
init();
setup();
for (;;) {
loop();
}
}
Как видите, от скетча он отличается незначительно. В начале добавлено подключение заголовочного файла Arduino.h, а в конце тело функции main. Все это Arduino IDE добавляет незаметно от вас. Не модифицируйте функцию main(), если не знаете точно, зачем вам это нужно.
Компилируем первый проект
Как и в предыдущем случае, Makefile взят с Eclipse, и правки коснулись исключительно замены абсолютных путей на относительные. Берем файл ArduinoBuild.tgz и распаковываем в папке с проектом. Должно получиться следующее:
$ cd ~/BlinkA $ wget https://github.com/madixi/BlinkA/blob/master/BlinkA/ArduinoBuild.tgz?raw=true -O ArduinoBuild.tgz $ tar -xzvf ArduinoBuild.tgz $ ls -lR ~/BlinkA/ /home/arduino/BlinkA/: total 8 -rw-r--r-- 1 arduino arduino 1430 Mar 18 10:20 ArduinoBuild.tgz drwxr-xr-x 2 arduino arduino 71 Mar 17 21:06 Debug -rw-r--r-- 1 arduino arduino 563 Mar 17 19:45 main.cpp /home/arduino/BlinkA/Debug: total 16 -rw-r--r-- 1 arduino arduino 2314 Mar 17 21:06 makefile -rw-r--r-- 1 arduino arduino 249 Mar 17 21:06 objects.mk -rw-r--r-- 1 arduino arduino 609 Mar 17 21:06 sources.mk -rw-r--r-- 1 arduino arduino 761 Mar 17 21:06 subdir.mk
Далее собираем проект:
cd ~/BlinkA/Debug make
Если все прошло успешно, то у вас должно получиться что-то подобное:
$ ls -lR ~/BlinkA/ /home/arduino/BlinkA/: total 12 -rw-r--r-- 1 arduino arduino 1430 Mar 18 10:20 ArduinoBuild.tgz drwxr-xr-x 2 arduino arduino 4096 Mar 18 10:23 Debug -rw-r--r-- 1 arduino arduino 563 Mar 17 19:45 main.cpp /home/arduino/BlinkA/Debug: total 216 -rwxr-xr-x 1 arduino arduino 29271 Mar 18 10:23 BlinkA.elf -rw-r--r-- 1 arduino arduino 7078 Mar 18 10:23 BlinkA.hex -rw-r--r-- 1 arduino arduino 41490 Mar 18 10:23 BlinkA.lss -rw-r--r-- 1 arduino arduino 98309 Mar 18 10:23 BlinkA.map -rw-r--r-- 1 arduino arduino 2994 Mar 18 10:23 BlinkA.symbol -rw-r--r-- 1 arduino arduino 713 Mar 18 10:23 main.d -rw-r--r-- 1 arduino arduino 6588 Mar 18 10:23 main.o -rw-r--r-- 1 arduino arduino 2314 Mar 17 21:06 makefile -rw-r--r-- 1 arduino arduino 249 Mar 17 21:06 objects.mk -rw-r--r-- 1 arduino arduino 609 Mar 17 21:06 sources.mk -rw-r--r-- 1 arduino arduino 761 Mar 17 21:06 subdir.mk
Собственно файл BlinkA.hex – это готовая прошивка, которую мы и будем заливать в контроллер.
Прошивка
Команда прошивки простая:
/usr/bin/avrdude -pm328p -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:BlinkA.hex:a
В данном случае у вас может отличаться тип контроллера, параметр -p, полный список можно посмотреть в man.
Можно добавить процесс прошивки в makefile, в этом случае прошивка будет происходить по окончании каждого билда. Для этого вместо файла ArduinoBuild.tgz следует взять ArduinoBuildBuild.tgz.
Как проверить, что заработало
В скетче выше есть не только веселое помигивание светодиодом, но и вывод сообщений в последовательный порт. В данном случае использовать вывод как средство контроля вполне удобно, можно даже прикрутить демон, который будет все сообщения платы приземлять в syslog, но сейчас я на этом останавливаться не буду.
Чтобы заглянуть в последовательный порт понадобится minicom
$ minicom -b 9600 -D /dev/ttyUSB0
Если все работает, то вы увидите «пульс» в виде точка-тире '.–'
Вместо заключения
В следующей статье я планирую раскрыть вопрос использования внешних библиотек, которых на данный момент существует очень много.
Содержание
- Программирование Arduino из Linux, gentoo-way, быстрый старт
- Программирование Arduino из консоли, gentoo-way, ничего личного лишнего
Использованные Источники:
- playground.arduino.cc/linux/gentoo
- playground.arduino.cc/code/eclipse
- forums.gentoo.org/viewtopic-p-6971658.html
Автор: madixi