- PVSM.RU - https://www.pvsm.ru -
Добрый день, уважаемыее. В этом цикле статей я попытаюсь рассказать Вам о Java Virtual Machine [1] и запуске Java программ на микроконтроллерах. Тема достаточно спорная: Зачем Java на микроконтроллерах, где и так мало ресурсов? Лучше нативного кода написаного на чистом С, ничего нет, даже на плюсах мало кто пишет! И т.д. Сразу скажу, сам задавал себе эти вопросы и не один раз. Мой ответ такой: Кто хочет попробовать, на что способно железо; понять, как работает uJVM [2] отправляется в плавание! Те кто уже настроился критиковать, смотрите как «Титаник» отправился в путь, надеюсь на Вашу лояльность!
Для затравки предлагаю Вам посмотреть видео ниже.
Если я правильно понял, то описанный в видео продукт состоит из OS, альтернативу [3]. И выбрал uJVM [2] — исходники открыты, легко скомпилировать и запустить, можно принять участие в разработке.
В первой статье я кратко расскажу об архитектуре, процессе загрузки исходного кода, настройке окружения и получении первого результата: скомпилированные uJVM [2] на микроконтроллерах разных архитектур, портированию на новые платформы, добавлению новых Java и native классов. Итак, начнем.
uJVM [2] была разработана в соответствии с общей архитектурой, описанной в The Java Virtual Machine Specification Java SE 7 Edition [4] и ее можно разделить на 3 части:
На данный момент uJVM [2] доступна для следующих H/W платформ:

Тажке uJVM [2] может быть легко портирована в качестве приложения под различные RTOS, например:
— но об этом я раскажу в другой серии статей.
uJVM [2] — реализация uJVM [2], отключая ненужные функции для экономии ресурсов или включения поддержки определенных H/W-драйверов (например, использование FPU для ускорения вычислений с плавающей запятой и т.д.). Давайте посмотрим, как ее собрать и запустить…
Для сборки uJVM [2] я использую дистрибутив на основе Ubuntu 16.04, но Вы можете использовать любой другой дистрибутив Linux. Необходимо установить следующие пакеты:
$ sudo apt-get install git gcc make openjdk-8-jdk-headless gperf flex bison libncurses5-dev texinfo g++ curl pkg-config autoconf libtool libtool-bin libc6:i386 libc6-dev:i386 gcc-multilib doxygen doxygen-gui
JAVA_HOME)Учтите, что папка, в которой находится компилятор Java (javac), должна быть известна системе сборки, для этого Вам следует (согласно инструкциям из документации Oracle Java [8]) установить переменную окружения, указывающую на компилятор. В качестве альтернативы Вы можете использовать команду shell:
$ export JAVA_HOME = _java_compiler_directory_
В приведенной выше команде _java_compiler_directory_ не должен включать конечную папку bin; например, если компилятор находится в папке /usr/bin, в качестве значения JAVA_HOME должно быть указано /usr. Если Вы хотите навсегда присвоить это значение переменной JAVA_HOME для всех пользователей системы, Вы можете использовать следующую команду для добавления этой переменной в файл /etc/environment:
$ echo "JAVA_HOME="/usr"" | sudo tee -a /etc/environment
Того же эффекта можно добиться, добавив переменную JAVA_HOME в файл /etc/profile с помощью следующей команды:
$ echo "export JAVA_HOME="/usr"" | sudo tee -a /etc/profile
После использования любой из этих команд Вам необходимо выйти из оболочки и войти снова, чтобы новое значение переменной среды вступило в силу.
kconfig-frontends под Linux (optional)
Подготовка kconfig-frontends для Linux — это быстрый и простой процесс, похожий на подготовку любого программного обеспечения с использованием autotools.
Обычно весь процесс сводится к скачиванию архива с исходным кодом, распаковке и запуску:
$ ./configure && make && sudo make install
$ curl -O http://ymorin.is-a-geek.org/download/kconfig-frontends/kconfig-frontends-3.12.0.0.tar.xz
$ tar -xf kconfig-frontends-3.12.0.0.tar.xz
$ cd kconfig-frontends-3.12.0.0
Если в вашей системе установлен gperf 3.0.4 или более ранней версии, Вы можете смело пропустить этот пункт.
gperf 3.1 (выпущен 5 января 2017 года) изменил тип, используемый в качестве аргумента длины в сгенерированных функциях, с unsigned int на size_t. Это приведет к сбою сборки со следующим сообщением об ошибке:
CC libkconfig_parser_la-yconf.lo
In file included from yconf.c:234:0:
hconf.gperf:141:1: error: conflicting types for 'kconf_id_lookup'
hconf.gperf:12:31: note: previous declaration of 'kconf_id_lookup' was here
static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
^~~~~~~~~~~~~~~
make[3]: *** [Makefile:456: libkconfig_parser_la-yconf.lo] Error 1
make[2]: *** [Makefile:350: all] Error 2
make[1]: *** [Makefile:334: all-recursive] Error 1
make: *** [Makefile:385: all-recursive] Error 1
Процедура исправления ниже:
$ curl -O https://gist.githubusercontent.com/KamilSzczygiel/d16a5d88075939578f7bd8fadd0907aa/raw/1928495cfb6a6141365d545a23d66203222d28c0/kconfig-frontends.patch
$ patch -p1 -i kconfig-frontends.patch
$ autoreconf -fi
Рекомендуемый набор опций для настройки kconfig-frontends:
$ ./configure --enable-conf --enable-mconf --disable-shared --enable-static
$ make
$ sudo make install
$ sudo strip /usr/local/bin/kconfig-*
$ git clone https://github.com/Samsung/uJVM.git
Выберите PLATFORM x86_64_linux. После этого создайте контекст с параметрами конфигурации по умолчанию командой:
$ cd uJVM/
$ make PLATFORM=x86_64_linux create_context
Включаем приложение HelloWorld.java в сборку. Для этого запускаем конфигуратор:
$ make menuconfig
Переходим в меню приложений

и выбираем «Hello world example»

После этого HelloWorld.java будет включен в сборку
/**
* @file japps/hello_world/HelloWorld.java
* @brief Example how to use String and SysLog classes
*
* @copyright Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved.
* @author Taras Drozdovskyi t.drozdovsky@samsung.com
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
import ujvm.lang.*;
public class HelloWorld {
public static void main() {
SysLog.log("Hello world!n");
String hello = "Hello world!n";
SysLog.log(hello);
byte[] bytes = { 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', 'n' };
String str = new String(bytes);
SysLog.log(str);
}
}
Пускай Вас не смущает SysLog.log(str) — это низкоуровневая функция вывода, аналог System.out.println(str). Стандартные билиотеки Java в uJVM [2] пока еще не реализованы, но надеюсь это изменится — возможно, именно благодаря Вам!
Сохраняем и компилируем:
$ make
И наконец, запускаем!
$ make run

Можете дальше эксперементировать, подключая другие приложения!
В следующей статье начнем расмотрение запуска uJVM [2] непосредственно под микроконтроллеры. Если руки зачесались, то Вы можете и сами начинать эксперементы, пользуясь инструкциями, которые можна найти в репозитории.
Автор: TarasDrozdovsky
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/322887
Ссылки в тексте:
[1] Java Virtual Machine: https://en.wikipedia.org/wiki/Java_virtual_machine
[2] uJVM: http://github.com/samsung/uJVM
[3] альтернативу: https://en.wikipedia.org/wiki/List_of_Java_virtual_machines
[4] The Java Virtual Machine Specification Java SE 7 Edition: https://docs.oracle.com/javase/specs/jvms/se7/jvms7.pdf
[5] ZephyrOS: https://www.zephyrproject.org/
[6] FreeRTOS: https://www.freertos.org/
[7] Nuttx: https://nuttx.org/
[8] инструкциям из документации Oracle Java: https://docs.oracle.com/cd/E19182-01/820-7851/inst_cli_jdk_javahome_t/)
[9] Источник: https://habr.com/ru/post/458772/?utm_source=habrahabr&utm_medium=rss&utm_campaign=458772
Нажмите здесь для печати.