Виртуальная машина и байт код

Часто требуется делать большие последовательности сложных операций — например полетное задание для робота. Да, можно запихать все это дело в основную программу, но вдруг что то пойдет не так как надо и алгоритм надо будет переделать — придется переделывать всю программу.

Тут на помощь придет виртуальная машина. Суть в чем — в памяти контроллера, в основную программу, занесены основные процедуры управления устройством. Если это робот, то это могут быть такие простые команды как «вперед», «назад», «повернуть» и так далее.

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

Потом нам нужен обработчик скриптов, который бы брал откуда нибудь, нашу последовательность действий — скрипт и преобразовывал это в вызовы реальных кусков кода -микрооперации.
Обработчик скриптов может быть той же самой задачей диспетчера, запущенной фоном. А откуда он будет брать данные неважно. Их вполне можно засасывать по usart или тащить из EEPROM памяти. А можно загнать на IIC память и получится сменный картридж :)

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

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

Например, есть у нас такая система команд:

  • 0х00 выключить периферию
  • 0х01 включить периферию
  • 0х02,0хZZ поднять манипулятор на ZZ попугаев.
  • 0x03,0xYY повернуть манипулятор на YY слонят.
  • 0x04 открыть зажим
  • 0х05 закрыть зажим

Тогда алгоритм хватания и переноса в нулевую позицию ящика стоящего на высоте в 10, под углом 15. Будет в источнике кода (ЕЕПРОМ или вообще что угодно) будет выглядеть примерно таким образом:

1
01, 02,10, 03,15, 04, 02,-10, 05, 02,10, 03,-15, 02,-10, 04, 00

Всего 17 байт на довольно сложное действие. Обрабатывать его можно будет примерно таким способом.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
script_loader(void)
{
Byte_op=current_chain[i]	// Берем код команды
 
switch(Byte_op)
	{
	case 0x02:	// Если у ней есть аргументы
	case 0x03:	// То в зависимости от типа команды делаем переход
		{
		SetTask(Byte_op);		// Сразу грузим команду на конвейер
		i++;				// Берем аргумент
		Param_REG = current_chain[i];	// Грузим его в регистр аргументов
		}				// Откуда задаче будет его удобно взять
		break;
	default:				// Если команда не имеет аргументов
		{
		SetTask(Byte_op)		// Просто бросаем ее на конвейер. 
		Param_REG = 0;			// А регистровый параметр зануляем
		}				// Хотя это и не обязательно
	}
i++;		// Переводим указатель на следующую команду
}

Сейчас операнды байт-кода выполняются последовательно. НО! Никто не мешает сделать доп аргумент разрешающий выполнять их и одновременно (кооперативно, разумеется, но никто не мешает побить ту же микрооперацию на подзадачи которые можно перемешать в конвейере).
И тогда, например, команды подъема и поворота могут быть указаны следующим образом:

  • 0х00 выключить периферию
  • 0х01 включить периферию
  • 0х02,0хZZ,0хMM поднять манипулятор на ZZ попугаев. Поставить MM код многозадачности
  • 0x03,0xYY,0хMM повернуть манипулятор на YY слонят. Поставить MM код многозадачности
  • 0x04 открыть зажим
  • 0х05 закрыть зажим

Что такое код многозадачности? Ну это я только что, экспромтом, придумал :) Некий флаговый байт в памяти содержащий код, который показывает, что текущая задача может допускать параллельное выполнение других задач, а также свой собственный код.
При этом, управление обработчику скриптов отдается сразу же (если MM не нулевой) и следующая задача, забрасываемая в конвейер, проверит код многозадачности и если он не конфликтует с ней (понятно, что повернуть одновременно на разные углы нельзя или есть ограничения механического плана) — пихается на конвейер в нагрузку к первой.

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

Вот таким нехитрым образом, увязав диспетчер* с обработчиком скриптов мы получаем действующую виртуальную машину, со своим языком, своим байт кодом. Получаем полностью отвязанные от железа алгоритмы устройств.
А поскольку байт код может быть где угодно, хоть в ОЗУ, то это открывает нам широчайший простор для создания полиморфических и самообучающихся алгоритмов =).

Предлагаю коллективным разумом на форуме сгенерировать ROBO-API на подобном байткоде. По крайней мере сформулировать список команд, синтаксис инструкций. А тут, в комментах, обсуждения самого подхода.

*) Диспетчер рассмотренный в прошлых статьях Архитектуры Программ курса AVR для этих целей не очень годится, т.к. конвейер там основан на указателях, а не на таблице переходов (хотя никто не мешате сварганить там и таблицу переходов, прям в задаче скрипт лоадера). А вот диспетчер из цикла статей по ассемблерной RTOS вполне на эту роль пойдет. Ну и кто то его на Си портировал уже.

85 thoughts on “Виртуальная машина и байт код”

      1. Wait по флагу.
        т.е. в данном случае, каждый манипулятор может двигаться одновременно с остальными. Но не может одновременно поворачиваться на разные углы. (собсно код многозадачности, как я понял и решает эту проблему) Этот код можно вшить в саму команду. Т.е. при например выполение функции ПОВОРОТ(манипуляторА, Pi/2), поставит в очередь запрос на поворот и зажгет флаг занятости манипулятора, а выполненная задача этот флаг потушит.
        Команда Ждать — тогда может получиться довольно интересная. Можно например,
        Ждать(10) — секунд,
        Ждать(МанипуляторА|МанипуляторБ) — до выполнения нужных заданий
        Ждать() — пока все флаги занятости сбросятся.
        В эту же систему флагов можно включить и датчики (есть срабатывание — зажигаем флаг, нет — сбрасывам), получаем еще один вариант:
        Ждать(СВЕТ) =)
        Для датчиков возвращающих не булево значение можно сделать что-то вроде ПОРОГ(СВЕТ, 50%) тогда функция Ждать(СВЕТ) будет отдавать управление при определенном уровне освещения.

        1. Самая проблема начнется с ветвлениями, переменными и освобождением памяти.
          Хотя реализация условных переходов как в процессорах 8×86 никаких больших сложностей не вызовет — команда сравнения (cmp) с записью результата и несколько переходов по условию(je, jne,jb ,ja итд)
          с переменными сложнее, в условиях ограниченной памяти сбор мусора будет самым главным. Ограниченность ресурсов опять же не даст реализовать удобный и хороший GC (на графах например, как в .net), хотя счетчик ссылок ( а-ля python), думаю, можно организовать.
          Вообще тема для меня очень интересная, с удовольствием бы занялся

          1. Не надо пытаться сделать монстра.

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

            Переменных фиксированное число. Скажем 100шт достаточно будет под большинство задач (тем более что мы же управляем обьектом со своими командами)

            1. А никто и не предлагает делать монстра, просто компиляторов/трансляторов/интерпретаторов за последние полвека столько придумано, что все грабли на которые мы можем наступить уже помечены крестиками и пути между этими граблями (т.е. архитектура) уже давно придуманы.
              Статическое количество переменных это не айс. А вот как захочется массив? На память переменных ограничение конечно же будет (оно и так есть), но распоряжаться ей должен пользователь

                1. А что сложного в представлении массива как именованный кусок памяти? Как в С, например.
                  имхо, вводить такие условности как заранее определенные переменные — это как раз лишние сложности.
                  Опять же с типами будет проблемы. Захочется вот uint64, а все 100 зарезервированные переменные int16

                  1. А кто сказал что будут типы? Будут 100 ячеек общего назначения.

                    По сути дела, мы делаем над_ассемблер. Типы данных это уже надо оставить компилятору нашего псевдокода.

                    1. Тогда будет очень сложно работать переменными различной длинны. Если все ячейки будет 8-и разрядными, то например сложить 2 16-и разрядных числа будет уже сильно сложнее чем А+Б. Оно надо?
                      Компилятору надо отдать типизацию. Вот оно, имхо, надо.

                    2. Тьфу, мы по-сути говорим об одном и том же, но разными языками %)
                      Переменных будет сколько душе угодно, а вот памяти под них на ВМ будет ограниченное количество Nбайт.

      1. Тоже верно. Но конвеер-то не резиновый? Залезет 2-3 команды, и всё. Плюс к тому, команды на один узел просто физически не смогут отработать параллельно. Пробовать надо, что выйдет. Но в качестве концепта — почему бы и нет?

        1. Срыв конвейера это фейл. Я думаю делать проще. Байт код же может лежать в памяти? Так вот. Завести оператор «Новый тред» в котором будет хранится номер треда. И любая задача может вызвать любую таким образом Вызвать_новый тред:номер. Эта микрооперация прочесывает весь массив байтокода и находит этот тред. Заводит для него отдельный индекс и начинает уже брать оттуда параллельно. Все! Дальше они выполняются независимо. Каждая по своему индексу. Единственно программер должен следить за тем чтобы ресурсы не пересекались.

  1. Да вроде как всё уже есть… Не особо развито, но есть. Есть форт для микроконтроллеров. И даже есть форт ассемблер! Довольно интересно тем, что можно не только байт код в реалтайме задавать (по уарт например), но и определять подпрограммы для обработки нового байт кода и тут-же его(их) использовать.

    1. форт — это Сила)
      управление с консоли, расширяемость, компактный шитый код, простота)
      к тому же никто не мешает доработать напильником и в качестве
      имени слов юзать 1-2 байтовое целое) тогда будет очень компактный код

  2. Так как команд в данном примере немного, имеет смысл ввести не команду, а бит многозадачности — т. е. иметь по два кода для обычного и параллельного исполнения.

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

    И код, и обработчик должны получиться более компактными.

          1. Бит можно запомнить и скинуть перед тем как натравливать на команду свитч. А можно воспользоваться тем, что свич выполняет все инструкции от метки, удовлетворяющей условию до ближайшего break, например так:


            //одно и тоже действие для обычной команды и многопоточной
            case CMD_1 | BIT_MT:
            case CMD_1:
            some_action_1();
            break;
            //многопоточная команда выполняет дополнительные действия, например проверку условия
            case CMD_2 | BIT_MT:
            if(condition)
            mt_action();
            else
            break;
            case CMD_2:
            some_action_2();
            break;

  3. Предлагаю усложнить формат комманд:

    0xFFAA00, 0xAAAA, 0xBB, [0xCC…], 0xFF00AA

    0xFFAA00 — байт который показывает что сейчас будет код команды
    0xAAAA — слово код операции
    0xBB — кол-во параметров
    0xCC — параметры
    0xFF00AA — конец команды

    Профит:
    1) Простенькая защита от шума в канале данных
    2) Переменное кол-во параметров, на этом можно строить функциональный быдлополиморфизм.

    Внутреннюю архитектуру обработки команд лучше организовать так

    массив команд (код операции, адрес обработчика)

    выборка нужного обработчика из массива, путём его обхода
    вызов происходит путём запихивания параметов в стёк
    и вызова(перехода по адресу call/jmp) обработчика по адресу из массива

    Сейчас нету доков по архитектуре AVR так что с параметрами в стёк я может быть налажал :) Не помню как параметры при call передаются, мб через регистры.

    1. Ну изобретать велосипед занятие не сильно полезное. Лучше взять опыт поколений, например систему команд какого-нибудь процессора.
      для интелов например, есть команда MOV, у которой могут быть в параметрах, регистр-регистр, регистр-память, память-регистр. На ассемблере это выглядит совершенно прозрачно, а в байткод переводится разный.
      Шум в канале данных проще устранять передачей блоков подписанных CRC, чем вводить избыточность.

      1. У них компилятор решает проблему адресации. У нас же этим будет заниматься наша ВМ, т.е. по сути дела интерпритатор выходит.

        Ниже я предложил свою систему байткода.

    2. Вы предлагаете не формат команд, а структуру пакета для их передачи. Когда же команда принята, заголовок и хвост (контрольные суммы) диспетчеру совершенно не нужны. Не надо все валить в одну кучу.
      Например, я при передаче по радиоканалу включаю несущую передатчика, жду 100мс для стабилизации АРУ приемника, затем передаю 3-4 (в зависимости от скорости) комбинации «FF», и затем признак команды «$». Затем байт кода команды, и 3 байта параметра, и концевую паузу 100мс. Приемник же постоянно следит за поступающими байтами, отбрасывая все, пока не получит «FF», после которой будет «$». Получив эту пару, он принимает следующие байты в буфер, после приема 4 байт выставляет флаг «Принята команда», и переходит снова в режим ожидания «FF», после которой будет «$». (я$ в символьном виде). Аналогично при отправке данных в буфер передатчика заносятся 4 байта, остальное там уже есть. При приеме также контролируется интервал между байтами, и если очередного байта не было дольше, например, 20мс, приемник снова сбрасывается в исходное состояние. Такой простой протокол позволил мне резко повысить качество радиоканала на 1200 бод через обычные китайские брелеки на 315МГц без их переделки. Лба конца, и компа, и робота, работают аналогично. Да, еще у меня используется взаимная блокировка — передатчик не будет задействован, пока не закончен прием, и наоборот.

      1. Я бы на вашем месте попробывал копать в сторону пакетной передачи и протокола с подтверждениями. Задержки это конечно круто и для управления роботом сгодится, но это не спортивно :)

        1. Пока хватает. Не будет устраивать — сделаю иначе, на данном этапе у меня много еще других задач, над которыми думаю. Идеальным решением было бы вообще использовать просто удлинители RS232 на WI-FI, метров до 100, но у нас в продаже их нет, заказывать в лом, да и дорогие они… Но, как часто бывает, в процессе решения других проблем эта, возможно, отрадет сама.

      2. Но есть в этом и рациональное зерно. Например, с переменной длиной команд у нас плывет шаг смещения при переходах. И если для перехода вперед по коду достаточно отсчитать по командам, то для перехода назад по коду уже придется запарить мозг.

        А вот когда у нас команда формата вида
        [длина команды в байтах][код команды][аргументы][аргументы]…[аргументы][аргументы][длина команды в байтах]

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

        1. Так переменная «string» в Паскале построена. Нулевой байт — длина строки в байтах, для пустой строки (») в нем 0. Очень удобно, в отличие от нуль-терминированного ANSI формата в C, где, чтобы узнать длину строки, надо пробежать ее всю для поиска 0. И сам 0 в строке использовать в этом случае нельзя… Если случайно байт с нулем попадет при сбое в Паскалевскую строку, он испортит лишь один символ, а в С — обрубит кусок строки.

  4. Предположим определились со всеми форматами и стали кодить… Потом подумали, что кодить прямо в цифрах как-то не кошерно, а значит нужен некий компилятор который понятное «поднять вверх на X попугаев» переведёт в байт код. И программа после этого станет понятнее чем набор цифровых байт команд. Раз появится компилятор, то следует отдать ему на откуп расчёт смещений при переходах при любом формате байт-команд. За счёт этого интепретатор в АВР станет быстрее и меньше. Потом ещё что-то будет отдано компилятору и в конце концов всё придёт к компилятору из созданного и заточенного под конкретную задачу языка в машинный код или какой-либо промежуточный байт код. И это будет хорошо! Компилятор на PC выполнит генерацию и оптимизацию кода, разберётся с одновременным выполнением некоторых команд и позволит сильно упростить программу в АВР. Посмотрите на форт — там всё это уже есть. Хотя ради академического интереса можно весь путь пройти самостоятельно…

    http://www.forth.org.ru/
    http://fforum.winglion.ru/viewtopic.php?t=9 (Форт для МК)
    Ну и вот почитать по ассемблеру: http://www.cqham.ru/rz6at/files/FS/DopKom/Dopkom.doc

    P.S. Сам с фортом никогда не работал и даже не сталивался, но то, что Вам надо он умеет.

    1. Понимаешь в чем проблема. Форт это универсальный язык. А нам надо просто общую концепцию, с завязками на железо.

      Или под каждый модуль писать свой компилятор форта?

      1. дык, форт — это не столько язык, сколько архитектура
        к тому же есть уже готовые реализации форта по авр
        с шитым кодом(разновидность vm) и встроенным компилером,
        например http://amforth.sourceforge.net/
        фактически, это набор асмовых примитивов для железа + десяток примитивов
        для самой вм вместе с компилером
        в крайнем случае,, если места зверски не хватает, можно компилер вынести
        из мк

    2. А зря… Надо было поработать.
      Я в конце 80х пробовал несколько вариантов Форта. И для Микроши, и для Корвета под CP/M и МикроДос. Язык конечно интересный, да больно уж непривычный, даже для меня, свободно использовавшего уже лет десять до того обратную польскую нотацию программируемых калькуляторов Б3-21 и Б3-24, где используется похожая методика. Так и не смог преодолеть некоторый психологический барьер. Все вроде понятно, программы на нем писал, но как-то без легкости, с напрягом, без участия подсознания, на одном голом разуме. Уж больно непривычно… Вся работа через стек. Пихаешь туда данные, снимаешь с верхушки, меняешь верхнюю пару местами… Если нужны данные из середины — замаешься все перелопачивать. Мне все же привычнее нормальные языки, где я могу делать что угодно и когда угодно с любыми данными, где бы они не находились.
      Код программ при размерах больше 2к байт получался даже короче ассемблерного, но какой ценой…

  5. По поводу Байт-кода на AVRe, обратим свои взоры на Японца Osamu Tamura!
    Сан-Сей Осаму Тамура сфорганил ForCy — Простой Язык для Встроенной Компиляции!
    Интерпретатор виртуальной байт-код машины (1,4К) + встроенный компилятор языка (1,7К)
    http://www.recursion.jp/forcy/index.html

    Реализация Форта на AVR: проект amForth
    http://amforth.sourceforge.net/

      1. Я уже давно это понял. Каждый мыслит по-своему, и когда пытаешься понять чужую логику, только отвлекаешься и начинаешь путаться в своей. Судя по опыту других, более старых сайтов по робототехнике, как только начинаются теоретические обсуждения с целью сделать чуть ли не Винды для робота, чтобы охватить все и вся, начинается застой и стагнация, реальная работа прекращается, а болтовня ни к чему не приводит. Весь пар в свисток уходит.
        Лучше потихоньку делать что-то свое, но делать. Тщательно продумывая, перебирая варианты, отбрасывая десятки неудачных, но делать. Что-нибудь да получится, да и сам процесс доставит много приятных минут, и кусок жизни будет потрачен не зря. А надеяться на чудо, что в результате болтовни вдруг родится что-то конкретное, что сразу решит все проблемы — что в бога верить. Верь-не верь, а толку — то с того…

        1. «чуть ли не Винды для робота, чтобы охватить все и вся, начинается застой и стагнация»

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

          1. Давно пора что-то с ним сделать. За почти два года с его создания было перепробовано вами много готовых вкусных железяк, — и акселерометры, и радиомодули, и много чего еще готового — бери да ставь, но потом пошли теоретические статьи, ленивый переход на критиковавшиийся до этого C, возня с голой теорией программирования, а корыто, с которого сайт начинался, забыто и покрывается пылью… И пропадает интерес у этому делу. Лучше двигаться, хоть мелкими шажками, но вперед, не стоять на месте. Тем более, когда вопросы материального жизнеобеспечения вроде решены и можно немного позаниматься и для души.

            1. Возня «с голой теорией» тоже очень полезна.
              DI HALT, большое спасибо за твои статьи! Прочитать, как мигать светодиодом, можно в куче мест. Тебе же моя благодарность именно за фундаментальность подхода. Написать одно и тоже можно двумя способами. Первый способ — сесть и начать писать. Второй способ — разработать концепцию, теорию, продумать, «обсосать» на форуме, а потом уже сесть писать. Первый способ быстрее второго на маленьких задачах, второй — на больших. При этом многие задачи первым способом нерешаемы вообще. Первое, что надо сделать — четко представить (ограничить) объемы решаемой задачи. Второе — не выходить за рамки поставленной задачи до ее реализации, другими словами не отвлекаться и не распыляться.

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

        1. Так давно уже есть. Назвается сопроводительная документация. Она может включать в себя не только комменты в коде, но и всякие архитектурные диаграммы и прочие мыслезаписи.

        2. Да полно такой шняги.

          Взять хотя б юмл. Но иной раз проще код прочитать или поговорить за чашкой кофе, чем изучать грёбаняй юмл и пытаться понять что же таки хотел сказать автор схемы и что таки у него получилось сказать этой схемой.

          Любые абстрактные схемы — есть некое гогно, т.к. надо извратом и пинками впихнуть предметную область в систему описаний сферического вакуума, а потом тот, кто будет читать — должен развернуть сферический ваккум в предметную область. Естественно, в итоге нихрена не понятно, зато всегда есть кипа веселых картинок и диаграмм.

          Вот ещё по теме:
          http://ru.wikipedia.org/wiki/Mind_map

  6. Я протестую !

    То, что здесь приведено — это не виртуальная машина, это DSL (domain specific language). Строго говоря, это термины немного из разных областей определения, и DSL в общем-то все равно на чем исполнять, хоть в шитый код транслировать, хоть интерпретировать, хоть виртуальную машину строить. Однако, ввиду простоты самих DSL’ей и ограниченности решаемого ими круга проблем полноценная ВМ часто не требуется, а то чем реализуют сам DSL называют каким-нибудь другим словом.

    Типичным DSL’ем является, например, код спецификации формата для printf.

    Построение же большой ВМ для полноценного, универсального языка требует учитывать кучу различных аспектов, для чего по-хорошему нужен целый цикл статей. Вот тут (http://fprog.ru/2009/issue2/) есть статья мужика, который прошёл этот путь до конца.

  7. Я на Баскоме делал такую виртуальную машину, отлично работает. Но я не программер и до всего своим умом доходил. У меня программа хранится в епиромке, цикл по очереди считывает байты по смещению нужного мне алгоритма и отправляет их на конвеер — обычный оператор Case. Типа так:

    Sel:
    Select Case Buf
    Case &H01 : Gosub Printdbeg
    Case &H02 : Gosub Printdend
    Case &H03 : Gosub Pasn
    Case &H04 : Gosub Pas2
    Case &H05 : Gosub Dellong
    Case &H06 : Gosub Delshort3
    Case &H07 : Gosub Delshort10
    Case &H11 : Gosub Smenabegin
    Case &H12 : Gosub Smenaend
    Case &H021 : Gosub Print2000beg
    Case &H022 : Gosub Print2000end
    End Select
    Return

    Примитивно, но работает надежно.

            1. Понял.
              Значит, если я в дешифраторе команд своего робота заменю серию IF на CASE, у меня тоже будет виртуальная машина… Правда, у меня все же с IF код получается короче, чем с CASE (проверял!) и новые команды вставлять удобнее, и сразу флажки нужные ставятся при меньшем числе переходов и обращений к регистрам. Да и текст в целом получается прозрачнее, сразу все видать, не надо по листингу метаться туда — сюда за каждой процедурой.

  8. Конечно, чисто академически это интересно. Но в общем и целом — напоминает изобретение велосипеда. Дихальт, насколько я могу видеть, ты углубляешься в программирование и вступаешь в классическую стадию «а я могу сделать лучше». На самом деле, не можешь. Точнее, можешь, но ценой потери гигантского количества времени. Всё это давным-давно решено и имеет стандартные решения. Например:
    -если так уж хочется оставаться в рамках AVR — есть форт, есть Си, есть плюсы. Есть лисп. Никто не мешает описать нужные тебе функции/взять готовую OS и писать нужную тебе логику. В качестве альтернативного подхода — разнообразные системы разработки конечных автоматов, тысячи их (и с прямой компиляцией, и с предкомпиляцией в С, и как угодно).
    -да и зачем вообще всё это городить на AVR? Берём что-нибудь немного более мощное (да вплоть до полноценного SoC с линуксом, они уже вполне дешёвые) и пишем на чём-нибудь более высокоуровневом (есть embedded .NET, есть python). Нужны низкоуровневые игрища — просто описываешь свою логику на С и подключаешь в виде модуля. Для оконечных устройств проще собрать usb uart и получить возможность отлаживать железяку на своём большом компьютере.
    И кстати, полноценный SoC имеет огромный плюс под названием «достаточно ресурсов для использования большинства библиотек». Например, можно прикрутить распознавание образов на нейронных сетях (см. FANN и биндинг PyFANN). На зашитой логике далеко не уедешь, а писать AI на чистом С с нуля — то ещё извращение.

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

    2. Все имеющиеся решения универсальные. У меня же стоит задача сделать очень узкую специализированную систему. В идеале, чтобы ее программировать мог ребенок лет так с 8ми (соответствующая графическая среда уже тоже в процессе создания). Плюс быстрая загрузка через ЕЕПРОМ без модификации флеша (чтобы устройство в в принцие нельзя было распрограммировать или что то запороть — т.к. для готового устройства это эпик фейл если юзер своими кривыми руками его запорет)

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

      Вот скажи, Какая из систем перечисленных тобой подходит под эту задачу?

      1. В 80х годах выпускался радиоконструктор «Старт 7245». С клавиатуры вводилась программа в виде команд «Вперед», «Назад», «Влево», «Вправо», «Пуск», «Стоп», «1», «2», «3», «4», «СД», «A», «Б»,»В»,»Г»,»», с 12 кнопок(4х3), и 2х переключателей: «Программирование-работа», и «Циклическое исполнение программы». Кроме команд, можно было задать количество квантов времени между ними.
        Состоял из платы с контроллером КР145ИК19Н01, преобразователем напряжения и клавиатурой (часть с КЛВ можно было отломить и подсоединить шлейфом), и 2х плат периферии — на одной 2 полных моста с КТ814/КТ815 на выходе, на другой — 4 ключа с КТ815 на выходе и защитным диодом. В общем, готовая начинка для простого робота. И чистейшая «Виртуальная машина» очень высокого уровня.
        Описание было в журнале «Радио» или можно тут глянуть: http://ironfelix.ru/modules.php?name=Pages&pa=showpage&pid=3
        У меня еще остался один неиспользованный, в упаковке, берегу как реликвию…

        1. Обалденная штука… Эх мне бы ее в детстве… А у нас же нифига не было. Кое как доставали микросхемы для радиокружка (моя мама в тот момент работала организатором в одном из таких кружков)

          1. «Обалденная штука… Эх мне бы ее в детстве… »
            ———————————————
            Приезжай летом в гости — подарю! Можешь Маячок захватить, чтобы не потеряться. Заодним и отдохнете, все равно не работаешь.
            У нас эти радиоконструкторы свободно в продаже лежали. По 24рубля. У меня в то время (инженер-электронщик 1 категории) оклад был 240, на руки выходило 286р… А когда каждый год бывал в Москве на курсах повышения квалификации, по выходным мотался в другу в Воронеж (билет 10р в мягком вагоне СВ, ночь езды без остановок). Там у них были магазины Электроника и Юный техник, где было полно всяких приборов для радиолюбителей, запчастей и некондиции. А на барахолке — любые микросхемы для компьютеров… Там я затаривался под завязку, и жутко завидовал Воронежцам. У нас в Электронике победнее было. В Бердске под Новосибирском тоже некондицию почти даром закупал на детали.

      2. Многоуважаемый Ди Халт!
        Вот ты спрашиваешь -«Вот скажи, Какая из систем перечисленных тобой подходит под эту задачу?»
        А на японца с его ForCy так и не взглянул!? A он так и просится в робота…
        И байт код, и простой язык с загрузкой с терминала и компиляцией внутри кристалла, и интерактивный режим с прямым управлением командами, и расширяй и модифицируй по своему вкусу, и сохраняй код хоть во внешнем еепроме, и размер крохотный, и философия и восточная мудрость. Ну чего тебе еще надо ?
        Хоть взгляни, и попробуй разобраться, потом не оторвешь….
        http://www.recursion.jp/forcy/index.html
        http://www.recursion.jp/forcy/abstract.pdf

        1. Ну почему не смотрел, смотрел. Но увидев:»простой язык с загрузкой с терминала и компиляцией внутри кристалла»

          Понял что японец страдает херней, впустую тратя и без того жидкие ресурсы контроллера.

          1. Да еще изучать еще одну китайскую грамоту, состоящую в основном из знаков препинания, скобок и закорючек. (Я за это даже С не переношу за его дурацкий синтаксис). Посмотрел я его команды и синтаксис… Еще один мертвый язык. Только мозги ломать. На мой век Паскаля с асмом хватит.

          2. Я не думаю, что так уж много ресурсов будет тратится.. Даже если туда код в прямом виде загружается, то компиляция произойдет только один раз. Проблема именно написать на нем программу — язык для робота уж слишком неудобный.

    1. аа соскучились. Да работы дофига. Не боись скоро будет. Я тут роботу уз+ик локатор делаю, статистику снимаю, квартиру сканирую. Скоро будет подробный обзор.

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

    P.S: спасибо за сайт! Сегодня очень помогла статья о PWM на прерываниях.

  10. Ага, классный подход!
    Я использовал это в другой задаче — в DPI (Deep Packet Inspection)
    Сделал как-то по работе «свой ассемблер с блэкджеком и шлюхами», заточеный чётко на обработку TCP/IP трафика ;)

  11. Может чего-то не догоняю, имхо проще в качестве так сказать интерпретатора использовать «готовый» язык программирования + свои функции, конечно потребует ввести в схему Computer-On-Module минимум, это все связать с функциональными узлами на avr.

    1. будет лишняя абстракция. Ведь готовый язык не будет отражать наше железо. Разве что вводить диалект какого из языка набитый командами относящимися непосредственно к железу, но это будет избыточно.

      1. Согласен, что абстракция, но так уж она плоха? Тем более для дальнейшего повторения конструкции будет полезна, да и вопрос переносимости кода тоже имеет значение. Хочется выслушать мнения, просто есть мысли о создании «робо-платформы».

Добавить комментарий