Pull to refresh

Программирование Arduino из консоли, gentoo-way, ничего лишнего

Reading time 7 min
Views 29K
Условия задачи с одной стороны сложны, с другой стороны очень просто формулируются. Есть сервер очень-очень далеко, к нему через FTDI конвертер подключена Arduino. Доступ у серверу – SSH. А надо исправлять, компилировать и заливать прошивки в плату. Классический пример — оклейка обоями запертой комнаты через замочную скважину. Очевидно ни о какой Arduino IDE, Eclipse и прочих красивых средах программирования речи быть не может.

С другой стороны — что нам стоит дом построить, нарисуем, будем жить.

Итак цель в том, чтобы создать на удаленной системе окружение, достаточное для программирования Arduino. Речи о возможной серьезной отладке конечно не идет, да и сами скетчи я пишу и отлаживаю на настольной машине в среде Eclipse, пользуясь всем тем комфортом, который дает мне уютное кресло и большой красивый монитор. Соответственно одна плата смонтирована на монтажной плате для быстрого прототипирования, а другая на далеко на сервере, можно сказать продакшн во всей красе.

Для справки, целевая система:
Архитектура x86, ядро 3.7.5-hardened-r1
Установлены стабильные пакеты последних версий.
Плата 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


Если все работает, то вы увидите «пульс» в виде точка-тире '.–'

Вместо заключения


В следующей статье я планирую раскрыть вопрос использования внешних библиотек, которых на данный момент существует очень много.

Содержание


  1. Программирование Arduino из Linux, gentoo-way, быстрый старт
  2. Программирование Arduino из консоли, gentoo-way, ничего лишнего


Использованные Источники:


  1. playground.arduino.cc/linux/gentoo
  2. playground.arduino.cc/code/eclipse
  3. forums.gentoo.org/viewtopic-p-6971658.html
Tags:
Hubs:
+27
Comments 7
Comments Comments 7

Articles