Jump to content

    

Виртуальная машина

Добрый день, коллеги! Впервые не уверен, что правильно разместил тему( В общем ситуация такая: нужно исполнять программу на МК (Cortex-M3). Но это программа должна быть загружаемой: грузится с microSD, возможно по сети или из встроенной флешки. Другими словами она должна компилироваться отдельно от основной программы-фреймворка, в котором содержатся все драйвера устройств целовй железки, стеки протоколов и т.п. Скажу сразу: никаких линуксов. В принципе, сама тема не нова. Но хочется определится с путём, каким идти. Примерные требования к загружаемой программе:

1. Пишется на Си, возможно Си++.

2. Никакой графики. Нужны только условные операторы, циклы, математика (несложная, буквально на уровне 5 класса). Ну и нужно дёргать предоставленное API (управление портами ввода-вывода, системные сервисы).

3. Желательно запретить работу с указателями, дабы не попортить содержимое основной системы.

Какие есть соображения:

1. Пишем свой интерпретатор и язык программирования. Примеров здесь, и на гитхабе - достаточно. Минусы решения: это не Си/Си++, язык не будет распространённым, будут ошибки как в компиляторе, так и в самой виртуалке.

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

3. Ничего не выдумываем. Берём какой-нить компилятор для несложной архитектуры (avr, pic, 8086). Заставляем компилятор генерить "чистый" код (без обращений к ос, биос, без линковки с библиотеками и тп). На своей железки эмулируем архитектуру. Приложение думает, что оно исполняется на "родном" 8086, например. Мы же полностью изолируем код от нашего железа, можем ему запретить делать нехорошие вещи, в любой момент остановить и выдать предупреждение. Минусы: хочется лёгкий компилятор, желательно из одного exe-файла, способный генерить "чистый" код. Компилятор должен быть по свободной лицензии. Вроде gcc и подходит, но это не один экзешник.

4. Взять какой-нить интерпретатор для lua или чего-то подобного. Минус: я не знаю этот язык, да и интерпретаторы ещё нужно от всего вычистить, чтобы встроить в своё окружение.

5. Посматриваю в сторону llvm  и clang. Пока только прокуриваю тему. Но из плюсов - генерит байт код, на который есть документация, а сам код не привязан ни к какому железу.

6. Ваши предложения...

Возможно я немного сумбурно изложил всё... Если что, уточню) Ну в общем задача "простая": сделать "персоналку", способную запускать приложения с полным контролем так, чтобы целевая железка не зависла и не перезагрузилась. При этом ресурсы этой железки весьма скромные: LPC1768, 64 кб ОЗУ, 512 кБ ПЗУ.

Share this post


Link to post
Share on other sites

ага, самое забавное, что оно само себя собрать может.

ну и всё что выше этой строки https://github.com/rswier/c4/blob/master/c4.c#L466 можно пожалуй в ПК вынести, оставив в МК только исполнение бинарного кода ВМ.

а вместо OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP, добавить своё предоставленное API.

 

Но на Lua я бы посоветовал ещё раз взглянуть по лучше, хороший повод познакомиться c этим языком. https://habr.com/ru/post/459602/

Share this post


Link to post
Share on other sites
2 часа назад, haker_fox сказал:

Взять какой-нить интерпретатор для lua или чего-то подобного. Минус: я не знаю этот язык

Шикарный документ: Learn Lua in 15 Minutes. Пока не захотите всяких изврщений типа объектно-ориентированности, его вполне хватает. Хотя... классы и наследование в этом документе тоже есть.

Share this post


Link to post
Share on other sites
2 часа назад, haker_fox сказал:

3. Желательно запретить работу с указателями, дабы не попортить содержимое основной системы.

Попортить можно и без указателей. Если хочется без указателей - может тогда попробовать Яву (язык)? Почти как си, только без указателей. :wink:

Ну а вообще - MPU Вам в помощь.

2 часа назад, haker_fox сказал:

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

Почему? Кроме MPU можно ещё сделать выполнение этого прикладного кода в user-mode. И системные вызовы - через SVC.

MPU будет защищать память, а всякие зацикливания внутри прикладного кода можно разруливать в прерываниях системного таймера.

2 часа назад, haker_fox сказал:

3. Ничего не выдумываем. Берём какой-нить компилятор для несложной архитектуры (avr, pic, 8086). Заставляем компилятор генерить "чистый" код (без обращений к ос, биос, без линковки с библиотеками и тп). На своей железки эмулируем архитектуру.

Будет ну ооооооооооооочень медленно.

Лучше уж тогда прогнать результат компиляции си-кода (листинг-файл) через какой-то простой парсер, который заменит все команды на вызовы соответствующих им процедур. А внутри этих процедур можно делать операцию, за которую отвечает эта команда (например: LDR R1, [R0] - чтение из памяти в R1) с дополнительной проверкой диапазона адресов и т.п.

Так будет работать хоть немного побыстрее чем простой эмулятор, выполняющий команды в режиме интерпретатора. Тем более что безопасные команды (без доступа к памяти, без переходов и т.п.) можно оставить как есть. Это даст заметный выигрыш по сравнению с режимом интерпретации.

Да и парсер такой написать несложно, и без багов.

2 часа назад, haker_fox сказал:

Возможно я немного сумбурно изложил всё... Если что, уточню) Ну в общем задача "простая": сделать "персоналку", способную запускать приложения с полным контролем так, чтобы целевая железка не зависла и не перезагрузилась. При этом ресурсы этой железки весьма скромные: LPC1768, 64 кб ОЗУ, 512 кБ ПЗУ.

Ещё вариант: припаять рядом дополнительный МК.  :biggrin:

Share this post


Link to post
Share on other sites
4 часа назад, haker_fox сказал:
4 часа назад, _pv сказал:

Я правильно понимаю, что это и компилятор и виртуалка в одном флаконе?

Делал на подобной стековой машине, результатом доволен, хоть и пришлось перелопатить половину, но мне много чего хотелось:biggrin:

4 часа назад, haker_fox сказал:

Взять какой-нить интерпретатор для lua или чего-то подобного. Минус: я не знаю этот язык,

Мне тогда тоже это не нравилось, хотелось Си подобного...

4 часа назад, haker_fox сказал:

Ничего не выдумываем. Берём какой-нить компилятор для несложной архитектуры (avr, pic, 8086). Заставляем компилятор генерить "чистый" код (без обращений к ос, биос, без линковки с библиотеками и тп). На своей железки эмулируем архитектуру. Приложение думает, что оно исполняется на "родном" 8086, например.

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

Это я про запуск без эмуляции, а если эмуляция, то да будет заметно медленнее, чем С4...

1 час назад, jcxz сказал:

Будет ну ооооооооооооочень медленно.

На основе С4 с оптимизацией "ручной" и машинной, правильным распределением памяти получил скорость на 400МГц АРМе около 5миллионов байткод-команд в сек, мне было "выше крыши":sun_bespectacled:

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

Edited by mantech

Share this post


Link to post
Share on other sites
4 часа назад, haker_fox сказал:

Очевидный минус, что даже MPU не сможет полностью защитить устройтсво от зависаний и прочих проблем из-за ошибок в приложении.

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

4 часа назад, haker_fox сказал:

При этом ресурсы этой железки весьма скромные: LPC1768, 64 кб ОЗУ, 512 кБ ПЗУ.

Ну эт еще нормально. Моя первая виртуалка работала на АТмега1284  128К флеша и 16Кбайт ОЗУ. При этом можно было запустить до 3х задач, в задачах была система прерываний, таймера и порты ввода-вывода, скорость байткода конечно не велика, несколько тыс. команд в сек, при условии 1 задачи, но вкупе с виртуалкой на МК крутилась ФС, с доступом из задач, и проигрывание WAV файлов на внешний ШИМ 8 бит 16КГц, а ДМА в Меге не было :cray:Печаль навевал единственный тип данных 16 бит число, памяти мало в меге... На АРМе уже стал 32х битными "ворочать".:biggrin:

Edited by mantech

Share this post


Link to post
Share on other sites
9 hours ago, _pv said:

ага, самое забавное, что оно само себя собрать может.

Угу, я поигрался с ней.

9 hours ago, _pv said:

Но на Lua я бы посоветовал ещё раз взглянуть по лучше, хороший повод познакомиться c этим языком. https://habr.com/ru/post/459602/

Меня тут тревожит, наверно, не столько даже новый язык, сколько перспектива вычистки интерпретатора и портирования его под IAR.

7 hours ago, Сергей Борщ said:

Спасибо, действительно быстро. Вопрос, на сколько качественно?)

7 hours ago, jcxz said:

Попортить можно и без указателей.

Каким образом, что-то вариант не приходит подходящий в голову).

7 hours ago, jcxz said:

Если хочется без указателей - может тогда попробовать Яву (язык)?

Да, этот вариант я тоже рассматривал. И даже маленько поигрался в компилятором javac. Вот только не понял, как можно заставить компилятор обращаться к своему API? В си/си++ я бы сделал таблицу указателей на функции. Ну вот, похоже, что без указателей никуда. А в случае с явой. Напишу, например код

set_gpio(LED0);

И компилятор javac скажет, а я не знаю такую функцию.

7 hours ago, jcxz said:

а всякие зацикливания внутри прикладного кода можно разруливать в прерываниях системного таймера.

Т.е. если программа зависнит (зациклится) её можно будет "прибить"? Можете пояснить чуть подробнее, каким образом можно понять, что программа слишком долго находится в цикле, и как прекратить её исполнение? Как я понимаю, мы в прерывании системного таймера смотрим, что, например, приложение выполнялось три-четыре предыдущих тика таймера, выполняется сейчас (PC в адресном пространстве приложения). И на основании этого делаем вывод, что оно зависло. Но как безопасно его завершить?

7 hours ago, jcxz said:

Ещё вариант: припаять рядом дополнительный МК. 

Такое решение мне не приходило в голову, но это тоже вариант!

6 hours ago, mantech said:

а в создании нормальных компиляторов я не силен - но за-то он очень простой...

Ну вот я и набрёл на llvm + clang. Clang умеет компилировать из Си в байт=код, поддерживает уровни оптимизации.

5 hours ago, mantech said:

Моя первая виртуалка работала на АТмега1284  128К флеша и 16Кбайт ОЗУ.

А какой язык использовали для написания программы?

Share this post


Link to post
Share on other sites

 

12 часов назад, haker_fox сказал:

6. Ваши предложения... 

 

1) Использовать готовую ВМ - Pawn. Синтаксис Си-подобный; может работать в режиме как интерпретатора так и исполнять скомпилированные скрипты (во втором варианте виртуальную машину для МК можно собрать без интерпретатора, для экономия места); из виртульной машины нет прямого доступа к остальной памяти МК; много примеров и документации; для написания и компиляции скриптов нет необходимости ставить весь тулчейн для МК. Вот пример его использования.

 

2) Можно использовать RTOS для МК, которая поддерживает исполнение отдельно скомпилированных программ. Например nuttx с её ELF/NXFLAT.  Не линукс :)

Share this post


Link to post
Share on other sites
12 minutes ago, arhiv6 said:

Ага, спасибо! Погляжу этот проект!

12 minutes ago, arhiv6 said:

Не линукс :)

У нас уже проект под FreeRTOS))) Не хотелось бы переползать на что-то другое)

Share this post


Link to post
Share on other sites
26 minutes ago, demiurg_spb said:

Вы случаем не ПЛК изобретаете?

Как вы догадались?:angel: Единственное, это не ПЛК (слишком круто), это более похоже на логическое реле. Хотя... хрен редьки...)))

Share this post


Link to post
Share on other sites

Логическое реле это тот же ПЛК, просто мало входов-выходов.

А пользователю конечному гораздо удобнее работать с такими изделиями стандартными средствами (языки МЭК 61131-3), а не Си и т.п....

Мы подобное даже на AVR делали. Так что по поводу ресурсов не переживайте - там генерируется Си-код, который компилируется нативным компилятором и готовая прога по bootloader загружается в контроллер. 

Share this post


Link to post
Share on other sites
6 minutes ago, demiurg_spb said:

Логическое реле это тот же ПЛК, просто мало входов-выходов.

Ну это как бы понятно.

6 minutes ago, demiurg_spb said:

А пользователю конечному гораздо удобнее работать с такими изделиями стандартными средствами

Ну это смотря какому пользователю. Нашему - лучше Си/Си++. Мы делаем эксклюзив. А ПЛК/реле и так на рынке пруд пруди)))

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now