24.09.2009

bitlash: интерпретатор для Arduino

Оказывается, далеко не всех устраивает традиционное ардуиновское "поправил-компильнул-загрузил". В качестве альтернативы всегда вспоминается интерпретатор языка Бейсик для контроллеров Basic Stamp от Parallax, но оказалось, что идея интерпретации плавно трансформировалась в направление т.н. shell-ов - консольных интерпретаторов, работающих внутри МК AVR/ATmega, в том числе и на Arduino.

По мере возможностей, расскажу про них под тегом shell.

bitlash

Автор: Bill Roy
Сайт проекта: bitlash.net
Лицензия: LGPL 2.1
Время первого упоминания: октябрь 2008 г.

Для начала, надо скачать с сайта проекта файлы bitlash, которые оформлены пользовательской библиотекой Arduino. Текущая версия - 1.0RC2, с предварительной поддержкой Arduino Mega - как видите, проект развивается ;)

Файлы надо распаковать в hardware/libraries/ (ArduinoIDE 0016), не забыв переименовать верхний каталог (что-то типа "bitlash-0.95a") в "bitlash". Далее, надо запустить ArduinoIDE и открыть пример из этой же библиотеки - bitlash-demo.pde:

#include "bitlash.h"


void setup(void) { initBitlash(57600); }


void loop(void) { runBitlash(); }

Компилируем (не пугайтесь only initalized variables can be placed into program memory - это нормально), загружаем.

Размер скетча  -  13,5 Кбайт, следовательно загружать требуется в ATmega168 или ATmega328P.

Подключаемся к виртуальному Serial-порту Arduino при помощи терминальной программы на скорости 57600-N-8 ( с помощью serial-монитора не очень-то удобно: но он не посылает перевод строки, вместо нее приходится набирать символ обратной кавычки ` - на русской клавиатуре он соседствует с ё ). Пример настройки putty:





После коннекта можно полюбоваться приглашением, а затем набрать help:



Итак, в вашем распоряжении есть 26 автоматических переменных, размерностью 32 бита каждая. Они называются соответствующей буквой латинского алфавита:

> a=2;b=3;c=(a+b)/2
> print c
2

(увы, арифметика здесь целочисленная). Выводы Arduino обозначены d0..d22 и a0..a7 соответственно. С ними можно манипулировать, как с переменными, что больше похоже на синтаксис AVR GCC, чем на ардуиновский:

> print a0,a1,d2
283 266 1
> d13=1

В первом случае мы прочитаем значения с аналоговых выводов, во втором - зажжем стандартный светодиод L на выводе 13.

Есть и строковые константы, но их длина ограничена 80 символами, если не жалко RAM очень надо - можно исправить в исходном коде и перекомпилять скетч.

В выражениях можно использовать и функции, они по смыслу совпадают с Arduino, только имена урезаны, для экономии. Например, analogRead(0) записывается как ar(0). Есть и возможность написать пользовательскую функцию в скетче, чтобы потом к ней обращаться через usr(arg).

Есть операторы ветвления: if, while и switch. Например:

> if d4: print "the light is on"
the light is on
>

Авторы твердо считают, что цикл for - неоправданная роскошь, которую можно сублимировать через while. Хорошо хоть он не оставил один только if - теоретически, его одного достаточно для любой операции ветвления в программе ;)

Подходим к самому интересному - программированию. Наверное, глупо  крайне неэффективно просто заходить зайти терминалкой на МК, чтобы почитать состояние на входах. Хотя для элементарных тестов какого-то нового оборудования - самое то. Постоянные мелкие правки и перекомпиляция отнимут гораздо больше времени, чем работа в командной строке bitlash - ну, это мое субъективное мнение по поводу аппаратного хакинга, конечно же.

bitlash поддерживает макросы. Макрос - это именованная последовательность команд, например:

> toggle13:="d13=!d13;delay(100)"
saved
>

Скромная надпись saved означает, что макрос сохранен в EEPROM. Те, кто знаком с основами unix shell, оценят:

> ls
toggle13:="d13=!d13;delay(100)"

В этом смысле EEPROM представляет собой некую файловую систему, а макросы - запускаемые команды-файлы. Как и в каждом уважающем себя unix-е, можно запустить задачу как в foreground:

>toggle13

..,так и в background:

>run toggle13

в последнем случае она будет выполняться циклически - светодиод отчаянно замигает. Список задач можно смотреть командой ps, а останавливать - командой stop:

>ps

0: toggle13
>stop 0


Команды top здесь все-таки нет ;), но запустить можно до восьми задач, которые будут функционировать в режиме разделения времени (величину кванта времени можно регулировать параметрами run). Если задача зациклена в foreground, например:

>while 1:toggle13

..., то прервать ее можно по Ctrl-C.

Специальные макро с именем startup выполняется при старте программы:

> startup:="print(1,2,3)" 
> boot 
bitlash v0.99z here!... 
1 2 3 
>

а специальное макро prompt изменяет системное приглашение:

> prompt:="print millis,;print\"$\","
saved
596139$ a =1
604209$ a =1
606905$

Ненужные макро можно удалять командой rm , при этом освобождается EEPROM, но, к сожалению, заодно и фрагментируется. Автор рекомендует распечатать все макро через ls, затем дать команду rm *, а потом снова их ввести через командную строку. Визуальное представление о состоянии EEPROM дает команда peep:

> peep 
E000: t13\ d13= !d13 ;del ay(1 00)\ star tup\ prin t("R unni ng b link -13 demo - p 
E040: ress ^C" ); w hile 1:t 13\. .... .... .... .... .... .... .... .... .... .... 
E080: .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... 
E0C0: .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... 
E100: .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... 
E140: .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... 
E180: .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... 
E1C0: .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... ....

Комбинируя содержимое sketch-а и макросы bitlash, можно добиваться очень интересных результатов, труднодостижимых при программировании в классической ArduinoIDE. Например, в бэкграунде можно исполнять определенные задачи и одновременно обслуживать общение с пользователем через консоль.

Bitlash можно запустить на ATmega644 (это "родной" процессор Sanguino), через Ethernet (если подключить и правильно заинитить XPort Direct) и с платой GATOR Plus+, которую я как-нибудь разберу под тегом ArduinoCompatible.

Краткий итог: проект определенно заслуживает внимания, потому что в некоторых применениях может оказаться проще и быстрее, чем Arduino/Wiring.

4 комментария:

  1. Вот это вещь! В закладки и обязательно попробовать.

    ОтветитьУдалить
  2. А подключив клавиатуру и экран к Arduino можно сделать автономный компьютер ;)

    ОтветитьУдалить
  3. Илья, я так понял вы довольно неплохо разобрались с сабжем. А не подскажете, почему у меня такая штука происходит?

    > toggle13:="d13=!d13;delay(100)"
    ^
    eeprom underflow

    Чип 168 родной, плата Diecimila. Сначала в EEPROM содержался какой-то мусор, но я обнулил всё. То есть, просто ничего не пишется. Сижу думаю, где баг.

    ОтветитьУдалить
  4. Я с таким не сталкивался, если честно. А как обнуляли EEPROM, кстати? Можно по исходнику глянуть, когда такая ошибка встречается...

    ОтветитьУдалить