Программируем микроконтроллеры на java

uJVM: платформа для запуска Java-приложений на микроконтроллерах (MCU)

uJVM: платформа для запуска Java-приложений на микроконтроллерах (MCU)

2019-07-04 в 7:18, admin , рубрики: arduino, avr, crypto, gpio, hello world, java, jvm, mcu, msp432, open source, saml, stm32, systick, tm4c1294, uart, программирование микроконтроллеров

Иллюстрация

Добрый день, уважаемыее. В этом цикле статей я попытаюсь рассказать Вам о Java Virtual Machine и запуске Java программ на микроконтроллерах. Тема достаточно спорная: Зачем Java на микроконтроллерах, где и так мало ресурсов? Лучше нативного кода написаного на чистом С, ничего нет, даже на плюсах мало кто пишет! И т.д. Сразу скажу, сам задавал себе эти вопросы и не один раз. Мой ответ такой: Кто хочет попробовать, на что способно железо; понять, как работает JVM ; увидеть интересный подход к построению мультиплатформенного проекта; внести свой вклад в Open Source; или просто побаловаться — все на борт, корабль по имени uJVM отправляется в плавание! Те кто уже настроился критиковать, смотрите как «Титаник» отправился в путь, надеюсь на Вашу лояльность!

Введение

Для затравки предлагаю Вам посмотреть видео ниже.

Если я правильно понял, то описанный в видео продукт состоит из OS, JVM и библиотек. Запускается он на многих контроллерах (можно посмотреть другие видео данной компании). Но решение оказалось закрытым, а мне захотелось попробовать поэкспериментировать. Я начал искать альтернативу. И выбрал uJVM — исходники открыты, легко скомпилировать и запустить, можно принять участие в разработке.

Читайте также:  border-style

В первой статье я кратко расскажу об архитектуре, процессе загрузки исходного кода, настройке окружения и получении первого результата: скомпилированные JVM и традиционное первое приложение HelloWorld.java, которые мы запустим на платформе x86_64. В последующих статьях перейдем к самому главному — запуску uJVM на микроконтроллерах разных архитектур, портированию на новые платформы, добавлению новых Java и native классов. Итак, начнем.

uJVM

uJVM была разработана в соответствии с общей архитектурой, описанной в The Java Virtual Machine Specification Java SE 7 Edition и ее можно разделить на 3 части:

  • Class loader Загрузчик классов uJVM — может загружать содержимое классов, хранящихся в .class или .jar файлах в память, выполнять связывание и инициализацию.
  • Managed memory areasuJVM поддерживает потоки, хранение специальных регистров, выделение памяти для стеков, кучи и потоков.
  • Execution engine. Из-за жестких ограничений на объем памяти, в uJVM в качестве механизма выполнения используется только интерпретатор байт-кода — JIT-компилятор не реализован. Движок uJVM предоставляет доступ к коду Java, H/W драйверам (например, UART, GPIO и SysTick для большинства платформ) и нативным методам.

На данный момент uJVM доступна для следующих H/W платформ:

image

— но об этом я раскажу в другой серии статей.

uJVM — реализация JVM с открытым исходным кодом для встраиваемых систем с ограниченными ресурсами. Самая простая конфигурация требует ~6 KB RAM для исполнения и ~45 KB Flash ROM для хранения. Система сборки позволяет разработчику настраивать uJVM, отключая ненужные функции для экономии ресурсов или включения поддержки определенных H/W-драйверов (например, использование FPU для ускорения вычислений с плавающей запятой и т.д.). Давайте посмотрим, как ее собрать и запустить…

Настройка окружения и загрузка исходного кода

1. Установка необходимых Linux пакетов

Для сборки uJVM я использую дистрибутив на основе 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 

2. Указание расположения компилятора Java (значение переменной JAVA_HOME )

Учтите, что папка, в которой находится компилятор Java (javac), должна быть известна системе сборки, для этого Вам следует (согласно инструкциям из документации Oracle Java) установить переменную окружения, указывающую на компилятор. В качестве альтернативы Вы можете использовать команду 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 

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

3. Сборка kconfig-frontends под Linux (optional)

Подготовка kconfig-frontends для Linux — это быстрый и простой процесс, похожий на подготовку любого программного обеспечения с использованием autotools .

Обычно весь процесс сводится к скачиванию архива с исходным кодом, распаковке и запуску:

$ ./configure && make && sudo make install 
3.1 Загрузка и распаковка исходного архива
$ 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 
3.2 Патч

Если в вашей системе установлен 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 
3.3 Настройка

Рекомендуемый набор опций для настройки kconfig-frontends :

$ ./configure --enable-conf --enable-mconf --disable-shared --enable-static 
3.4 Компиляция и установка
$ make $ sudo make install $ sudo strip /usr/local/bin/kconfig-* 

4. Клонирование репозитория uJVM

$ git clone https://github.com/Samsung/uJVM.git 

Компиляция uJVM

Выберите PLATFORM x86_64_linux . После этого создайте контекст с параметрами конфигурации по умолчанию командой:

$ cd uJVM/ $ make PLATFORM=x86_64_linux create_context 

Включаем приложение HelloWorld.java в сборку. Для этого запускаем конфигуратор:

Переходим в меню приложений

uJVM: платформа для запуска Java-приложений на микроконтроллерах (MCU) - 3

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

uJVM: платформа для запуска Java-приложений на микроконтроллерах (MCU) - 4

После этого 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 пока еще не реализованы, но надеюсь это изменится — возможно, именно благодаря Вам!

uJVM: платформа для запуска Java-приложений на микроконтроллерах (MCU) - 5

Можете дальше эксперементировать, подключая другие приложения!

В следующей статье начнем расмотрение запуска uJVM непосредственно под микроконтроллеры. Если руки зачесались, то Вы можете и сами начинать эксперементы, пользуясь инструкциями, которые можна найти в репозитории.

Источник

В теории о байт-коде, JVM и микроконтроллерах | Java-код для МК

Java-университет

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

Тема : Где и как работает Ява
Об устройстве Явы
О железе
Как этот софт работает на железе

Статья была об проблемах, с которыми я столкнулся. Изучив инфу, дополнил её ответами.
Представляет из себя кашу-малашу из тем сверху.

Предисловие.(Оффтоп)
Было и есть у меня нарастающее желание сконструировать кое-какой, вполне физический агрегат.
Агрегат,в основе которого лежит одна простая, но поглотившая меня целиком идея.
Идея, задавшая мне направления развития на ближайшие десять лет.
В теории уже полу-готова конструкция устройства, реализующего кроху возможностей той запланированной махины.

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

Здесь и подходит череда вопросов, обьеденить которые можно в «Можно ли, и как, заставить МК выполнять java-код ?».

Тело. Детально о вопросах.
Мы помним, что java-код, который мы пишем, преобразуется в byte-код, который, уже в свою очередь, интерпретируется JVM в машинный код, код, состоящий из команд, понимаемых железом. Всем понятна причина именно такого расклада событий — портируемость/переносимость в купе с бОльшей скоростью (по сравнению с просто интерпретируемыми языками).

После того, как я узнал это, у меня возникли вопросы, оставшиеся неотвеченными, всплывшие и дополненные новыми вот сейчас.
1. Можно ли стандартными средствами JVM полностью прогнать весь byte-код в машинный, единовременно / Скомпилировать его ?
if false.Есть сторонние средства ? Хоть как-то ?

2. Поддерживает ли JVM работу с микроконтроллерами/контроллерами ? (мало знаю о железных «мозгах», если есть знающие — расскажите).
if true.Есть отличия\особенности от работы на привычных нам ПК ?

Обновлено! 09.04
Об 1. Стандартным средством ( подразумевалась JVM ) прогнать код до машинного возможности нет, по крайней мере так нам говорит вики, но, оттуда же, стало ясно, что есть сторонне средство — GCJ. Является альтернативой JVM и имеет в своём арсенале вот такую приятную плюшку. Точной информации об платформах(аппаратных), под которые поддерживается компиляция, не нашел — «многих».
Разница byte-code и native-code:
1)native быстрее запускается
2)Нет никаких гарантий, что native будет работать быстрее
3)Как я полагаю, native не будет тащить на себе ОС и JVM, что существенно отражается на кол-ве необходимой для работы программы ROM.

Возможно, это решение может выступить альтернативой ME-версии.
(Под здоровенным вопросом, ибо :
1) Не известно, поддерживает ли GCJ такие низкопроизводительные аппаратные платформы.
2) Нет информации о производительности этого кода.

Обновлено. 11.04
Об 2. Любая версия языка Java, будь то ME,SE или Embedded, работает в паре с JRE, интерпретируясь. Кроме случая выше и двух, будущих описанными ниже.
Во-первых, были попытки выщемить из цепи ОС, заменив её своим, исключительно Ява-ориентированным средством. О том, что это такое, тут.
Во-вторых, оказалось, что существуют Ява-ориентированные процессоры, их особенностью является встроенный сопроцессор, который аппаратно интерпретирует byte-code(!не программно) и уже его отдаёт на исполнение.
Подробнее о Jazelle.
Богато тут.

Оффтоп
Идея, о которой шла речь — «обратная связь», конкретно реализуемый тип в будущем прототипе — давление/сопротивление давлению.
Пользуясь случаем. Читающий народ уровней 15-25, давайте бахнем маленькое комьюнити для общения/тэт-а-тэт. Ибо одному — вообще не гут, и даже больше — жуть полнейшая.

Источник

Оцените статью