Сегодня мы выйдем за пределы одного чистого программирования и возьмем в руки паяльник. Задача на вечер — помигать светодиодом на Orange Pi.
Orange Pi — это одноплатный мини-компьютер, который, видимо, появился как конкурент Raspberry Pi, при этом и меньше размером, и дешевле. За 15 евро вы получаете четырехядерный компьютер размером со спичечный коробок, куда можно поставить Линукс. Ну не чудо ли? Да еще и c Wi-Fi.
Почти все сказанное ниже применимо, разумеется, и к Raspberry Pi.
Для экспериментов я установил дистрибутив ARMBIAN Debian 9, Rakudo Perl 6 и WiringOP (ну еще пришлось припаять планку с контактами).
WiringOP — это библиотека и утилиты для работы с портами ввода-вывода. Устанавливается просто:
git clone https://github.com/zhaolei/WiringOP.git -b h3 cd WiringOP chmod +x ./build sudo ./build
С перлом же пришлось повозиться. Я хотел скомпилировать свежий Rakudo Star и начал делать все по инструкции. Началось все замечательно, но потом намертво встало, нагрев процессор до 60-70 градусов. При этом невозможно было достучаться до компьютера по SSH, хотя видно было, что оно просто дико тормозит, но работает.
В итоге я не дождался, пока все соберется, и пошел искать готовые порты. Нашлись два имени — perl6 и rakudo — и это дистрибутив версии 2016.12.
# apt-get install perl6
Конечно, декабрь 2016 это уже очень старое, но при этом версия языка 6.c, что в целом нормально: эта текущая версия спецификации Perl 6.
This is Rakudo version 2016.12 built on MoarVM version 2016.12 implementing Perl 6.c.
Теперь пишем программу на Perl 6:
my $pin = 7; shell("gpio mode $pin OUT"); for True, !* ... * { shell("gpio write $pin " ~ +$_); sleep 0.5; }
Здесь я обращаюсь к внешней утилите gpio (из WiringOP): сначала нужно установить один из портов в режим вывода, а затем поочередно устанавливать его в ноль или единицу.
Обратите внимание на интересные моменты в программе.
Во-первых, бесконечный цикл сделан с помощью ленивой последовательности, каждый элемент которой вычисляется как !*, то есть как отрицание предыдущего. В итоге последовательность состоит из бесконечного чередования True и False.
Во-вторых, булевы величины преобразуются в единицу или ноль с помощью префксного оператора: +$_ и затем подставляются в строку, которая выполняется командной оболочкой.
В-третьих, для запуска используется функция shell. Для этой задачи этого более чем достаточно. В идеале нужно было бы написать код, который напрямую устанавливает биты в соответствующих регистрах устройства.
В-четвертых, не забывайте, что sleep в Perl 6 может принимать и нецелые значения.