...

пятница, 17 января 2014 г.

Raspberry PI и JAVA: пристальный взгляд

Недавно на хабрахабре вышла статья о 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 — реальная и вполне легко решаемая задача (чем я и собираюсь заняться в дальнейшем).

Спасибо за внимание)


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий