Недавно на хабрахабре вышла статья о java на raspberry pi, увидев название которой было много ожиданий, а под катом оказался банальный Hello World!
Дело в том, что ко мне как раз ехала моя малинка и хотелось получить ответы на следующие вопросы:
1. Сравнима ли скорость работы java на малинке и настольном компьютере?
2. Насколько удобно работать с java на raspberry?
3. Есть ли адекватные библиотеки для работы с GPIO?
Вот на эти вопросы я и попробую дать ответы в этой статье.
Кому интересно: добро пожаловать под кат (графики и фотографий обнаженной малинки там не будет)
Настройка доступа к Raspberry PI по ssh без пароля
Я очень люблю свой родной ноутбук и предпочитаю работать на других линукс-машинах через ssh.
Поэтому, в первую очередь, ради удобства настраиваем доступ к малинке по ключу.
Для этого на компьютере, с которого будет осуществляться подключение генерируем пару ключей при помощи команды ssh-keygen.
Затем копируем открытый ключ на малинку
$ scp /home/user1/. ssh /id_rsa.pub pi@raspberry_server:~/
$ ssh pi@raspberry_server
$ mkdir .ssh
$ cat ~/id_rsa.pub >> ~/. ssh /authorized_keys
Нажимаем Ctrl-D для выхода из сеанса. Пытаемся снова подключиться — профит. Подключение происходит без запроса пароля.
Заглядываем под капот
Прежде всего меня интересует, что же за оборудование мне досталось. Можно, конечно, посмотреть в документацию, но всей правды она не всегда скажет.
Поэтому, подключаемся и вводим команду
$ cat /proc/cpuinfo
Заинтересовала следующая строка:
Features: swp half thumb fastmult vfp edsp java tls
Что-ж уже интересно. Можно надеяться, что малинка меня порадует.
Установка JAVA SE Embedded
В предыдущей статье был описан способ установки openJDK. Кому интересно — посмотрит.
Но мне было интересно установить java от оракла (все равно java-код я люблю компилировать на любимом ноутбуке в любимой IDE), что и я сделал:
Итак, идем на сайт оракла, скачиваем пакет java se embedded (ARMv6/7 Linux — Headless — Client Compiler EABI, VFP, HardFP ABI, Little Endian) и заливаем его в папку /home/pi.
Заходим в консоль малинки и
1. Распаковываем архив в папку /opt
$ sudo tar -xvf ejre-7u45-fcs-b15-linux-arm-vfp-hflt-client_headless-26_sep_2013.tar.gz -C /opt
2. Далее добавляем путь к файлу java в переменную PATH и устанавливаем переменную JAVA_HOME
$ sudo chmod a+w /etc/profile
$ echo 'export PATH=/opt/ejre1.7.0_45/bin:$PATH' >> /etc/profile
$ echo 'export JAVA_HOME=/opt/ejre1.7.0_45' >> /etc/profile
$ sudo chmod a-w /etc/profile
Перезаходим по ssh и командой
$ java -version
убеждаемся, что виртуальная машина установлена.
Тестируем скорость работы
Теперь настало время выяснить насколько медленна/быстра java на малинке. Тест не претендует на какую-либо всеобъемлющую объективность, а лишь призван показать приблизительный порядок разницы скорости работы виртуальной машины на малинке и настольном компьютере.
Для теста был выбран мой нетбук с процессором AMD E-300 APU с тактовой частотой 1,3 Гц (т. е. Почти в два раза большей, чем у малинки).
Для теста используем программу поиска простых чисел при помощи решета Эратосфена.
public class RaspTest {
public static void main(String[] args) {
int maxPrimesCount = 40000;
int currentPrimesCount = 1;
long prevTime, execTime;
prevTime = System.currentTimeMillis();
long[] primes = new long[maxPrimesCount];
long currentNumber = 3;
boolean isPrime = false;
primes[0]=2;
while (currentPrimesCount < maxPrimesCount) {
isPrime = true;
for (int i = 0; i < currentPrimesCount; i++) {
if (currentNumber % primes[i] == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primes[currentPrimesCount] = currentNumber;
currentPrimesCount++;
}
currentNumber++;
}
execTime = System.currentTimeMillis() - prevTime;
System.out.println(execTime);
System.out.print(currentNumber-1);
}
}
Итого:
Нетбук показал результат 89 секунд, а raspberry — 444 секунды.
Итого: на малинке почти в пять раз медленнее. Что-ж вполне ожидаемо учитывая разницу в тактовой частоте и архитектуре.
Неожиданность нас постигнет, если мы изменим тип числе с long на int.
При этом нетбук показал результат 38 секунд, а raspberry — 65 секунд.
Я был, приятно удивлен.
Вывод: скорость работы виртуальной машины на raspberry pi сравнима с таковой на настольных компьютерах.
Работа с GPIO
В одном из докладов на конференции Joker докладчики программировали GPIO на Java Embedded ME (micro edition).
Standart Edition, к сожалению, не имеет соответствующих классов, поэтому я обратился к гуглу и нашел проект Pi4J (www.pi4j.com). Стабильная версия сейчас 0.0.5, но проект развивается и версия 1 разрабатывается в данный момент.
Тем не менее я рекомендую пользоваться стабильной версией, ибо на версии 1 у меня не все заработало.
Следует также отметить, что номера портов несколько отличаются от стандартных, поэтому рекомендую ознакомиться с документацией на сайте Pi4J.
Цепляю на первый порт светодиод, на второй кнопку, пишу следующий код:
public class Test1 {
public static void main(String[] args) throws InterruptedException {
GpioController gpioController = GpioFactory.getInstance();
GpioPinDigitalOutput gpioPinDigitalOutput = gpioController.provisionDigitalOutputPin(RaspiPin.GPIO_01, "MyLED", PinState.HIGH);
GpioPinDigitalInput gpioPinDigitalInput = gpioController.provisionDigitalInputPin(RaspiPin.GPIO_02,PinPullResistance.PULL_DOWN);
gpioPinDigitalInput.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent gpioPinDigitalStateChangeEvent) {
System.out.println("GPIO Pin changed" + gpioPinDigitalStateChangeEvent.getPin() + gpioPinDigitalStateChangeEvent.getState());
System.out.println("Sleeping 5s");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Unsleep");
}
});
while (true) {
gpioPinDigitalOutput.toggle();
Thread.sleep(500);
}
}
}
Собираю пакет, копирую jar файл и библиотеки на raspberry pi, запускаю и… Не работает.
Оказывается, для управления портами ввода/вывода необходимы права администратора.
Но для того, чтобы сработала команда
$ sudo java
в каталоге /bin должна быть символическая ссылка на исполняемый файл java-машины. Создаем ее:
ln -s /opt/ejre1.7.0_45/bin/java /bin/java
Снова запускаем — работает. Лампочка мигает, при нажатии на кнопку и засыпании потока обработки лампочка мигать продолжает, т.е. обработка события от кнопки запускается асинхронно.
Выводы:
1. Raspberry pi — это не игрушка, а компьютер с производительностью и возможностями, подходящими для решения многих задач.
2. Производительности виртуальной машины java сравнима с производительностью в настольных системах, хотя и несколько ниже.
3. Управление внешним оборудованием при помощи java и raspberry pi — реальная и вполне легко решаемая задача (чем я и собираюсь заняться в дальнейшем).
Спасибо за внимание)
Автор: shapovalex