В наше время, из-за санкций одноплатники стали стоить каких-то «конских» денег. Даже б/у RaspberryPi Zero стоит 2-3 тысячи рублей на барахолках, что, мягко скажем, не совсем лояльная цена для «самого дешевого одноплатного компьютера в мире». Конечно, Orange Pi Zero всё ещё можно купить в пределах 1.500-2.000 рублей, но как по мне и эта цена не слишком лояльна за те характеристики, который предлагает такой одноплатник. С другой стороны, Android-планшеты 10-летней давности продаются на барахолках по 100-300 рублей, что выглядит гораздо привлекательнее, причём на некоторые устройства практически без костылей можно установить полноценный дистрибутив Linux! Вероятно, многие читатели скажут мол «автор бомж» и будут правы: ведь в рамках этой статьи, я хочу рассказать о том, как использовать полурабочий древний планшет в качестве полноценного одноплатника путём подключения его к микроконтроллеру и выводу GPIO! Сегодня мы с вами: узнаем, как подключить микроконтроллер к шине UART в планшете и научимся работать с последовательной шиной в Android прямо из Java и нативных программ. Интересна моя концепция антикризисного одноплатника? Тогда добро пожаловать под кат!
Пожалуй, нельзя сказать, что подобная концепция пристраивания старых планшетов — вопрос исключительно цены. 2-3 тысячи рублей не такие уж и большие деньги и при желании можно купить хотя бы Б/У, но всё таки полноценный одноплатник с нормальной GPIO-гребенкой. Однако здесь стоит вопрос не столько дешевизны, сколько E-Waste: зачем выкидывать в помойку потенциально рабочие планшеты с живым процессором, если их можно пристроить куда-то ещё?
На самом деле, планшеты с ROOT-доступом уже из коробки могут выполнять весьма полезные задачи, как, например, хостинг http-сервера для домашней страницы, работать как панель с часиками и погодой, или, например, работать в качестве HMI-панели для оформления заказов в шаурмечной. Кроме того, многие планшеты на базе смартфонных чипсетов (MediaTek, Spreadtrum) имеют полноценный Bluetooth-модуль, что позволяет «подружить» планшет с микроконтроллером через радиоканал, что значительно расширяет возможный спектр применений.
Преимуществ у такого подхода много: у «пожилого» планшета уже есть большой, достаточно качественный (хороший TN, либо даже IPS) дисплей с тачскрином, который поддерживает мультитач, GPU для вывода 3D-графики, 3.5мм для вывода звука + встроенные динамики, а также весьма неплохое, по сравнению с дешевыми одноплатниками, железо. Звучит весьма вкусно для цены в 300 рублей: собрать хоть немного похожую конфигурацию на базе RPi выйдет в 10-15 тысяч рублей (учитывая дороговизну MIPI-матриц с тачскринами + цену самой «малинки» и обвязки для аудиотракта).
Но при всех перечисленных достоинствах, атрибутом любого полноценного одноплатника является наличие GPIO — и даже здесь мы сможем с вами выкрутится! Первый способ, о котором я чуть выше вскользь рассказал, позволяет реализовать общение с МК и «ногодрыг» через BT-радиоканал, но минусы такого подхода очевидны (МК с BT дороже, радиоканал потребляет дополнительную энергию, некоторые могут посчитать BT небезопасным). Однако есть и второй подход, который заключается в использовании диагностических пятачков UART на плате устройства для наших личных целей!
С таким подходом можно использовать как «голый» Linux, используя концепцию, которую я представил в этой статье, так и взаимодействовать из Java-приложений для Android (что даёт уже, как минимум, удобный GUI-фреймворк). Сегодняшняя статья будет «без воды», только чистая конкретика, поэтому давайте перейдем к реализации!
Как я уже говорил выше — в рамках данной статьи мы рассмотрим использование UART в планшете для наших собственных целей. UART — это двунаправленная полнодуплексная цифровая шина, которая позволяет обеспечить стабильную передачу данных при относительно невысокой скорости, измеряемой вбодах. То есть, быстро стримить картинку с её помощью вы не сможете, но сможете, например, получить состояние входов МК, прочитать что-то на шине I2C, используя мост UART -> I2C или, например, прочитать показания датчиков, которые МК предварительно опросил.
Сама по себе концепция очень простая: многие китайские производители планшетов и смартфонов не только разводят UART в виде отдельного пятачка на плате, но и подписывают его, задействуя UART-канал как вывод для логов ядра, а иногда и предоставляя доступ к рутовой консоли! В свою очередь, из юзерспейса мы можем получить доступ к UART с помощью устройства/dev/ttySна подавляющем числе чипсетов и/dev/ttyMTна MediaTek. Однако учтите, что в некоторых случаях придется патчить загрузчик, дабы редиректнуть логи ядра в /dev/null.
Однако наличие UART на плате — не всегда признак того, что он сконфигурирован в системе верно. Например, на смартфонах с чипсетами SC6820 нормально завести UART я так и не смог, а на некоторых устройствах на базе MT657x нужно патчить загрузчик, дабы он «увидел» нужный канал UART! В моём случае, героем статьи стал планшет Prestigio, у которого отказал тачскрин, но был доступен UART:
Конкретно в моём случае, после установки последней официальной прошивки планшет перестал слать логи на UART и устройство /dev/ttyMT3 оказалось доступным для наших операций, в вашем же случае может потребоваться настройка devicetree, или просто патчинг загрузчика, дабы редиректнуть консоль на другой вывод UART. Кроме того, необходимо обязательно получить root-доступ хотя бы к adb shell, поскольку доступ к /dev/tty устройствам возможен только от имени суперпользователя. Как же проверить UART на возможность чтения/записи? Сначала нам необходимо взять ESP32 или любой UART-USB преобразователь, припаять сигнальные линии RX/TX и использовать любую программу для работы с последовательным портом, например Putty. Заходим в adb shell, и пишем что-нибудь в консоль:
Работает? Замечательно, значит мы сможем использовать планшет вместе с микроконтроллером! Переходим к практической реализации нашего приложения!
Я специально решил выделить для Java-подхода отдельный раздел, поскольку просто взять и открыть/dev/ttyMT3с помощью FileInputStream не выйдет. Дело в том, что даже несмотря на наличие root-доступа, по факту ни одно Android-приложение его не имеет (за исключением подписанных системных в папке /system/app/) и для всех операций, требующих повышенных привилегий, либо распаковывают и запускают внешнюю нативную программу из под суперпользователя, либо с помощью специального костыля с запуском sh-программ читают/пишут нужные блочные устройства сами. Связано это с тем, что все Android-приложения работают в хост-процессе app_process, который форкается (отпочковывается) от «главного» процесса, который запущен из под «простого» пользователя, который не находится в группе system.
Здесь концепция также очень простая: suимеет аргумент -c, который позволяет запустить команду от имени root-пользователя и возвращает объект процесса, дабы мы потом могли перехватить stdout: