Электронная книжка в качестве дисплея

в 21:56, , рубрики: diy или сделай сам, дисплей, Си, метки: ,

Нетрадиционное применение распространённых вещей — это то, что всегда нам интересно! Ведь так хочется порой похачить очередное устройство. Понять как оно работает и внести какие-то свои коррективы в его работу, добавив новых функций.

Электронная книжка в качестве дисплея
Выводим свои картинки

Я расскажу, как можно старенькую читалку Sony PRS-505 превратить в удобный дисплейчик. И так же расскажу, как можно писать свои программы для этой книжечки

Постановка задачи

Для одного устройства мне понадобился дисплейчик для отображения графиков и экспериментальных данных. Данные должны отображаться нечасто, но желательно чтобы дисплей был с низким энергопотреблением, большого размера и с неплохим разрешением.
Моё исходное устройство бегает под линуксом и имеет USB-host. Сначала я поглядел в сторону дисплея Vogue, но отмёл его по небольшим размерам и разрешению. Начал искать дальше.
У меня давно без дела валяется электронная книжка PRS-505. Достал я его и положил перед собой, помня что там внутрях линукс и где-то слышал, что можно достучатся до него через консоль. Но так же понимая, что эта вещь в себе. Положил и забыл.

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

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

Зачем это нужно:

Зачем это нужно: Например на целевой машине идёт видеовывод в виртуальный экран, с разрешением, равным разрешению книжки (а именно 600х800). Далее периодически, берётся файл фреймбуффера виртуального экрана и перенаправляется в сом-порт, а на том конце из ком-порта, коммандой cat это перенаправляется во фреймбуффер книжки.

Иллюстрирую, все комманды выполняются на целевой машине, книжка подключена по UART, через VCP, который висит на /dev/ ttyUSB0. Комманды вызываются раз в несколько минут, например в кроне.

echo «cat /dev/ttyS0 >/dev/fb0» > /dev/ttyUSB0

Эта комманда по UART передаёт комманду перенаправлять содержимое файла СОМ-порта во фреймбуффер. Следом идёт вторая комманда:

cat /dev/fbn > /dev/ttyUSB0

Эта комманда передаёт содержимое виртуального экрана fbn (где n-номер экрана) в СОМ-порт. Всё должно отработать прекрасно, передача кончится по приходу символа конца файла.

Нормальные люди в походе наслаждаются природой...

Приступаем к делу

Когда мы вернулись из нашего эпичного похода, я разыскал его статью www.xakep.ru/magazine/xa/129/092/1.asp и дальше понеслась.

Первоначально я разобрал книжку, и попаялся к отладочной консоли, используя микросхему ft232rl для сопряжения интерфейсов (см. мой пост «UART и с чем его едят» — habrahabr.ru/post/109395/ )

Электронная книжка в качестве дисплея
Распатроненная читалка с подпаянным интерфейсом

Электронная книжка в качестве дисплея
Вид сзади

Подробнее о том, как и к каким контактам подпаиваться можно прочитать тут www.the-ebook.org/forum/viewtopic.php?p=120092#120092

Я не хочу заниматься цитированием статьи камрада Vshmuk о том как залогинится, какие процессы надо убить и т. п. Лучше всего прочитать у него в этой статье. Скажу лишь, что эмпирически установлено, что при подключённой книжке к компьютеру по штатному USB никаких процессов убивать не надо, всё работает и так. В качестве терминалки я использую любимый minicom.
После подпайки я начал проводить изучение операционки. Перво-наперво поглядел скрипт, о котором говорится в статье, что он всё монтирует и выводит загрузочную картинку. Поглядим же, что это за зверь такой:

root@(none):/# cat /etc/rc.d/rcS.d/S20libromount

из всего фаршмака, что там вывалилось, нам наиболее интересно вот что:

# display booting image 
/usr/local/sony/bin/nblconfig -dump | head -3 | awk '{print $9}' | grep 02 > /dev/null
if [ $? == 0 ]; then
        # init screen load
        grep BootImg /proc/mtd > /dev/null
        if [ $? == 0 ]; then
                NUM=`grep BootImg /proc/mtd | awk -F: '{print $1}' | awk -Fd '{print$2}'`
                dd if=/dev/mtd$NUM of=/dev/fb0 bs=256 count=1875
                /opt/sony/ebook/bin/writescreen init 0
        else
                /opt/sony/ebook/bin/writescreen init 1
                echo no boot image
        fi
else
        /opt/sony/ebook/bin/writescreen init 1
fi
...

Я решил попробовать забить случайным фаршем экран, и сделал вот такую команду:

root@(none):/# dd if=/dev/urandom of=/dev/fb0 bs=256 count=1875
1875+0 records in
1875+0 records out

Но ничего не произошло…

Попробуем выполнить следующую команду:

root@(none):/# /opt/sony/ebook/bin/writescreen init 0
latest nblconfig read from 0x00035000
latest nblconfig written to 0x00035800
И… чуда не произошло. Более того, комманда
root@(none):/# /opt/sony/ebook/bin/writescreen init 1

тупо гасит экран и всё, после чего он уже не подавал признаков жизни.

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

Электронная книжка в качестве дисплея
Выведенный отладочный порт на аудиоразъём

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

Для эксперимента я попробовал передать файл картинки. Помните я выше уже говорил о скрипте вывода загрузочной картинки? Он её читает с раздела NAND-флешки читалки и записывает его во фреймбуффер:

NUM=`grep BootImg /proc/mtd | awk -F: '{print $1}' | awk -Fd '{print$2}'`
dd if=/dev/mtd$NUM of=/dev/fb0 bs=256 count=1875
/opt/sony/ebook/bin/writescreen init 0

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

Ну дальше вторую комманду немного поправим, чтобы передача велась в СОМ-порт. Опытным путём установил, что консоль для приёмо-передачи — это файл /dev/tty. Перебрасываем картинку, для этого на компе закрываем терминал и выполняем:

cat /dev/ttyUSB2 > bootimg.raw, где ttyUSB2 — это мой интерфейс VCP на базе ft232rl.

После чего в другой консоли компьютера даём комманду:

echo «dd if=/dev/mtd9 of=/dev/tty bs=256 count=1875» > /dev/ttyUSB2, что посылает через консоль комманду передачи образа по консоли.

Преобразуем эту картинку из бинарного слепка в png:

echo -e «P5n800 600n255n» >result.pgm
cat bootimg.raw>>result.pgm
convert result.pgm result.png

В результате получаем вот такую картинку. Я не знаю почему её так перекособочило, но явно были какие-то ошибки передачи.

image
Полученная картинка

Кстати, что из себя представляет картинка, которую можно записать во фреймбуффер. Это битовая маска, где каждый байт равен цвету пикселя и весит она ровно 800х600 = 480000 байт. Следовательно картинку, которую мы хотим передать во фрейм буффер должна быть размером 800х600 и весить ровно 480000 байт. По сути это и есть *.pgm-файл, только с отрезанным заголовком.
Обратно мне не удалось передать файл. Видимо потому, что консоль является стандартным устройством ввода, и ей не нравится непечатные символы. Подробнее об этих экспериментах можно почитать тут: dlinyj.livejournal.com/608961.html.

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

Исследуя систему, различные скрипты и т. п. стало понятно, что средствами консоли вывести на экран изображение не представляется возможным. Мне подсказали, что уже один товарищ решал эту задачу и даже описывал ещё в своём блоге systemsand.me/sony-prs-300prs-505-hack/. Говоря кратко, программу писать придётся, хотя она будет и очень простой.

Я скачал тулчейн (говоря проще компилятор для сборки, хотя это и не совсем точно) отсюда www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/ немного попарившись с регистрацией, я таки накатил его на свою любимую убунту. И попробовал собрать hello word

Для справки, собирался он командой arm-none-linux-gnueabi-gcc -mcpu=arm920t hello.c -o hello

Самое главное было то, как передать полученный файл на книжку. Я заметил, что при подключённом USB на компе видится некий диск, объёмом примерно 200 метров. Но в системе на книжке его нет.

У меня есть вся прошивка кникжи, и я понял что жёский диск используется в приложении книги (имеется в виду то для чего предназначено устройство). Это файлик cramfs.Fsk.img
Я примонтировал этот образ на своём компьютере и поглядел скрипт sony/ebook/bin/tinyhttp.sh. Как это сделать опять же описанно в статье в Хакере. Это тот самый скрипт, который мы придушиваем в самом начале, чтобы получить консоль, согласно статье Vshmuk. И там была такая строка:

NUM=`grep Data /proc/mtd | awk -F: '{print $1}' | awk -Fd '{print$2}'`
/usr/local/sony/bin/mkdosfs /dev/mtdblock$NUM

Опять же первая строчка получает номер устройства. Выполнив первый скрипт (то что в кавычка), я получил число семнадцать, и дальше подмонтировал /dev/mtdblock17 в /tmp/t1. Объяснить как я понял, что именно это будет флешкой я не могу, но просто логика подсказала, что именно в этом файле должна идти инициализация пользовательских данных.

И в результате я увидел содержимое диска, которое я вижу на своём компе.

И я решил попробовать его запустить:

root@(none):/tmp/t1# ls
Digital Editions autorun.inf database hello tmp
root@(none):/tmp/t1# cp hello /tmp/
root@(none):/tmp/t1# cd…
root@(none):/tmp# ls
hello t1
root@(none):/tmp# ./hello
bash: ./hello: No such file or directory
root@(none):/tmp# chmod +x hello
root@(none):/tmp# ./hello
bash: ./hello: No such file or directory

Умные люди подсказали, что там может не хватать нужных библиотек, и посоветовали собрать с опцией -static. После этого всё стало ещё хуже

root@(none):/tmp# ./hello
Segmentation fault

Стало понятно, что надо искать компилятор. Благодаря помощи многих людей, я узнал что под эту книжку пилят альтернативную прошивку openinkpot.org/wiki! А следовательно тулчейн должен быть.

Начал гуглить Поиском «prs-505 toolchain» он был найден тут code.google.com/p/prs-plus/downloads/detail?name=arm-toolchain-sony-300.tar.gz&can=4&q=. После чего хелло ворд завёлся без проблем (даже без статика!). Ну дальше дело техники, согласно systemsand.me/sony-prs-300prs-505-hack/ набросал небольшую программку

/* showpic.c */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>


#define FBIO_EINK_GET_TEMPERATURE        0x46A1    //Returns temperature in degree Celsius
#define FBIO_EINK_DISP_PIC                0x46A2    //Displays picture

int main (int argc, char* argv[])
{
    printf ("Show imagen");

    int *fb, *image;
    int pio_fd = open ( "/dev/fb0", O_RDWR);
    int f_image = open ( argv[1], O_RDWR);                                 //open file into arg
    int t= ioctl (pio_fd, FBIO_EINK_GET_TEMPERATURE, NULL);    //configure framebuffer

    fb= mmap(0, 800*600, PROT_WRITE, MAP_SHARED, pio_fd, 0);    //map device into memory
    image= mmap(0, 800*600, PROT_READ, MAP_SHARED, f_image, 0); //load image into memory
    
    memcpy(fb,image,800*600);
    ioctl (pio_fd, FBIO_EINK_DISP_PIC, 0);
    
    close(pio_fd);
    close(f_image);
    return 0;
}

Дефайны взял из кода драёвера с сайта Sony www.sony.net/Products/Linux/Audio/PRS-505.html файл 8track20070714.tgz

Компилировал примитивнной коммандой с минимум опций: path to toolchain/arm-unknown-linux-gnu-gcc -static showpic.c -o showpic

Без статика не захотел работать.

Теперь в gimp создаём картинку с разрешением 800х600, рисуем что хотим и сохраняем как habrahabr.pgm.

Электронная книжка в качестве дисплея
Мои художества

Вы простите мои художества. Мне было лениво особо стараться.

После чего открываем его в любом хекс-редакторе и удаляем весь заголовок до FF

Электронная книжка в качестве дисплея
Удаляем заголовок

Заливаем на жёсткий диск книжки. Лезем в консоль и выполняем:

root@(none):/# cd tmp/
root@(none):/tmp# mkdir t1
root@(none):/tmp# mount /dev/mtdblock17 t1
root@(none):/tmp# cd t1/
root@(none):/tmp/t1# ls
Digital Editions autorun.inf habrahabr.raw showpic
a.out database send.raw tmp
root@(none):/tmp/t1# ./showpic habrahabr.raw
Show image
root@(none):/tmp/t1#

И видим:

Электронная книжка в качестве дисплея
Фаршмак

ой! Это мы картинку не повернули. Поворачиваем исходную картинку в gimp на 90 градусов и повторяем процедуры. В результате нашему взору предстанет

Электронная книжка в качестве дисплея
Что и требовалось доказать!

Итоги

Мне удалось написать свою программу для книжки и даже выводить картинки. Надо сказать, что цель выводить графики gnuplot. Сей пакет прекрасно умеет генерировать сам файлы pgm, и остаётся только коммандой dd отрезать заголовок.

Электронная книжка в качестве дисплея
Пример графика

Главная проблема, которая сейчас не решена — это как передавать файлы графиков на книжку. Я хотел это делать прямо по отладочной консоли, но для этого надо уметь её отучать быть консолью и превращать в обычный UART. Как это сделать я не знаю. Ещё более того, я думаю это делать на лету.
Мне подсказывают, что можно собрать драйвер, чтобы устройство виделось как COM-порт по USB, но мне кажется что это может вылиться в тот ещё гемморой. Я думаю можно попробовать создать папку на флешке, а в неё монтировать виртуальную временную файловую систему в оперативной памяти. Я не пробовал ещё этот метод. Но передача файла через флешку является абсурдным и неразумным решением.
В общем вопрос остаётся открытым и я готов услышать все разумные предложения по этому поводу.

Благодарности

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

Ссылки:

1.Исходная статья в Хакере www.xakep.ru/magazine/xa/129/092/1.asp откуда я начал свой эксперимент.
2.Инструкция по подпайке книжки www.the-ebook.org/forum/viewtopic.php?p=120092#120092
3.Аналогичную задачу решал наш соотечественник так systemsand.me/sony-prs-300prs-505-hack/ к сожалению, он не смог мне помочь исходниками и тулчейном.
4.Исходные тексты прошивки книжки и драйверов www.sony.net/Products/Linux/Audio/PRS-505.html
5.Открытый проект альтернативной прошивки openinkpot.org/wiki
6.Рабочий тулчейн code.google.com/p/prs-plus/downloads/detail?name=arm-toolchain-sony-300.tar.gz&can=4&q=
7. О моих муках с книжкой можно прочитать у меня в ЖЖ dlinyj.livejournal.com/tag/prs-505

P.S. Я не очень грамотный человек, буду очень признателен за личные сообщения с помарками, чтобы статья выглядела более достойно.
P.P.S.Так же замечания по сути приму с удовольствием. Я не крутой разработчик ПО под Linux, хотя очень хотелось бы им стать :).

Помните лучшая благодарность автору поста — это оставленный комментарий!

Автор: dlinyj

Поделиться

* - обязательные к заполнению поля