Электронные чернила для Wirenboard 5 или рисуем штрихкоды на Go
Привет, Хабр! В процессе разработки иногда приходится изобретать велосипеды инструменты для тестирования приложений и бывает что некоторые из них могут быть полезными например в домашней автоматизации. Вот случай из моего личного опыта. При разработке приложения для мобильных терминалов сбора данных, появилась необходимость тестирования лазерных сканеров, без печати штрихкодов на бумаге. К сожалению эти сканеры не умеют считывать с обычных экранов. Бумагу им подавай, но и электронная бумага им тоже очень понравилась.
Вспомнилась статья на Хабре Электронная книжка в качестве дисплея, решено было достать с полки старенький полуживой ридер Sony PRS-505 и дать ему вторую жизнь в роли экрана для контроллера автоматизации. Но слать картинки через флеш память плохая идея. Нужно было научиться работать напрямую с оперативной памятью электронной книги. Это увеличивает скорость отображения и надежность. Позвольте поделиться опытом рисования в Go на примере генератора штрихкодов и отображении на электронной книге через контроллер Wirenboar 5.
Задачи- Ничего не сломать. Мы только добавляем новую функцию.
- Электронная книжка должна уметь слушать порт и в течении 1 секунды выводить изображение
- Работа только через буфер в оперативной памяти, никакой flash памяти
- Протестировать вывод великой командой dd
- Рисование штрихкода нужного размера в Go и размещение его в центре холста
- Передача изображения в буфер электронной книжки
- Наслаждаться полученным результатом
В читалке Sony PRS-505 нет wi-fi и к тому же из модулей ядра USB Gadget имеется только g_file_storage, поэтому это единственный способ быстро передать изображение. К счастью прошивка от PRSPlus умеет запускать любой скрипт при включении электронной книги. Все что нам нужно, это просто положить нужные файлы в папку directory/database/system/PRSPlus и при загрузке будет запущен скрипт prsp.sh.
В качестве буфера использовать Flash память нельзя, поэтому нам нужен небольшой tmpfs диск в оперативной памяти который будет доступен по USB, следует выгрузить модуль ядра g_file_storage и загрузить его с нужными параметрами, для публикации нашего созданного RAM диска по USB. Далее мы должны отслеживать изменения в заданной области и выводить изображение на e-ink дисплей.
#!/bin/sh echo $'\n===============\nSTART SCRYPT\n' >> /dev/console
#TODO «here need Kernel Event instead while and sleep bottom placed» function waitnewdata > /dev/console
#Show only modify time the image file MODIFYTIMEOLD=`ls -l --full-time /tmp/raw.img | awk ' '` MODIFYTIMENEW=$MODIFYTIMEOLD
while [ "$MODIFYTIMEOLD" == "$MODIFYTIMENEW" ] do MODIFYTIMENEW=`ls -l --full-time /tmp/raw.img | awk ' '`
if [ "$MODIFYTIMEOLD" != "$MODIFYTIMENEW" ] then showpic fi >
function showpic > /dev/console
#Generating Back Screen for best clear e-ink (optional) dd if=/dev/zero of=/tmp/img.raw bs=1k count=480 /tmp/showpic /tmp/img.raw
dd if=/tmp/raw.img of=/tmp/img.raw bs=1k count=480 /tmp/showpic /tmp/img.raw
#ldconfig PATH="/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/local/sony/bin:/usr/sbin:/sbin" LD_LIBRARY_PATH="/Data/opt/sony/ebook/application:/lib:/usr/lib:/usr/local/sony/lib:/opt/sony/ebook/lib" export PATH LD_LIBRARY_PATH
# set initial date /bin/date 0101000007
#Unload kernel module rmmod g_file_storage
#Create raw file 1Mb dd if=/dev/zero of=/tmp/raw.img bs=1k count=1k
grep Data /proc/mtd > /dev/null if [ $? == 0 ]; then
NUM=`grep Data /proc/mtd | awk -F: '' | awk -Fd ''` insmod /lib/modules/2.4.17_n12/kernel/drivers/usb/g_file_storage.o file=/dev/mtdblock$NUM,/dev/sdmscard/r5c807b,/dev/sdmscard/r5c807a,/tmp/raw.img ProductID=$MODEL VendorSpecific=$VENDOR sn_select=0 iSerialNumber=$ID else insmod /lib/modules/2.4.17_n12/kernel/drivers/usb/g_file_storage.o file=/dev/sdmscard/r5c807b,/dev/sdmscard/r5c807a,/tmp/raw.img ProductID=$MODEL VendorSpecific=$VENDOR sn_select=0 iSerialNumber=$ID fi
#start kbook application nohup /opt/sony/ebook/application/tinyhttp > /dev/null &
cp /Data/database/system/PRSPlus/showpic /tmp/
Основные моменты, что делает скрипт psrp.sh
-
Сначала мы выгружаем модуль:
Да, согласен, знатный велосипедик, но к сожалению в прошивке нет inotify, а с Kernel Event мне было лениво разбираться. Тем более что fps в 1 секунду меня устроит.
ПроверимНажимаем reset на электронной книжке, ждем окончания загрузки, подключаем USB кабель. Для проверки мы можем отправить тестовое изображение. Например из Ubuntu это можно сделать так:
Если при загрузке ридера скрипт успешно запустился, то при подключению по USB мы увидим устройство с размером 1Мб.
Находим вот такую строку:
Теперь мы знаем, вот он наш кусочек оперативной памяти электронной книги /dev/sdx .
Для конвертации из jpeg, нам понадобится djpeg, установим нужные пакеты:
Далее создаем JPEG файл в Вашем любимом редакторе, размером 600x800 и отправляем его на электронную книжку.
В этом конвейере мы преобразуем jpeg в монохромный pgm, пропускаем заголовок и передаем 480Кб единым блоком на устройство /dev/sdx. И тут же видим результат.
Генератор штрих кода и отправка его в устройствоДля рисования штрихкода в Golang нам понадобятся дополнительные библиотеки:
Основные моменты в коде:
-
На примере EAN, сначала мы рисуем штрих код толщиной в 1 пиксель:
Разработчики Wirenboard, предоставляют нам очень удобный инструмент кросс компиляции на базе Docker контейнера. Но в рамках данной статьи его мы рассматривать не будем. Под ARMv5 наше простое приложение можно собрать одной командой.
Переносим все на Wirenboard 5:
Переходим на Wirenboard, смотрим имя устройства размером в 1 Мб, в моем примере /dev/sdd.
ВыводыИспользование электронной книги в качестве экрана вполне реально. Своим потенциалом технология электронных чернил побуждает к использованию в дизайне интерьера. E-ink экран будет хорошо смотреться особенно на светлой стене. Можно выводить полезную информацию с домашнего контроллера.
Спасибо за внимание!
P. S. Исходники, можно посмотреть тут и тут. Прошивка PRSPlus для электронных книг тут.