Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Я хочу получать рассылки с лучшими постами за неделю
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
Создавая аккаунт, я соглашаюсь с правилами Пикабу и даю согласие на обработку персональных данных.
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр
Уникальная игра, объединяющая популярные механики Match3 и пошаговые бои!

Магический мир

Мидкорные, Ролевые, Три в ряд

Играть

Топ прошлой недели

  • AlexKud AlexKud 38 постов
  • SergeyKorsun SergeyKorsun 12 постов
  • SupportHuaport SupportHuaport 5 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая кнопку «Подписаться на рассылку», я соглашаюсь с Правилами Пикабу и даю согласие на обработку персональных данных.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня

Embedded + Гаджеты

С этим тегом используют

Микроконтроллеры Программирование Электроника AliExpress Китайские товары Товары Вертикальное видео Telegram (ссылка) Смартфон Все
10 постов сначала свежее
141
monobogdan
monobogdan
Посты о ремонте и моддинге ретрогаджетов.
TECHNO BROTHER
5 месяцев назад

Благодаря подписчику Роману, выкупил из утиля очень крутую штучку - NTT DoCoMo Sigmarion II (NEC MobilePro)⁠⁠

Благодаря подписчику Роману, выкупил из утиля очень крутую штучку - NTT DoCoMo Sigmarion II (NEC MobilePro) Опрос, Покупка, Гаджеты, Кпк, Компьютер, Ноутбук, Windows, Ретро, Компьютерное железо, Смартфон, Wince, Embedded, Nec, Длиннопост

Ещё бы переводчик SHARP серии Brain найти и китайские ноутбук c MIPS-процессором - уж очень я люблю Windows CE :) Вот что я с девайсами на его базе делаю:
Как я купил электронный переводчик за 1.000 рублей и превратил в мини-нетбук на ARM
Как я Wolfenstein и эмулятор Денди на промышленный терминал портировал
Гиковский КПК за копейки: как китайцы сделали ARM-ноутбук за 40$ с железом от… навигатора?

Благодаря подписчику Роману, выкупил из утиля очень крутую штучку - NTT DoCoMo Sigmarion II (NEC MobilePro) Опрос, Покупка, Гаджеты, Кпк, Компьютер, Ноутбук, Windows, Ретро, Компьютерное железо, Смартфон, Wince, Embedded, Nec, Длиннопост
Аппарат радует довольно бодрым 200МГц MIPS R3000 процессором NEC VR4131, 32Мб SDRAM ОЗУ и большим дисплеем 640x240
Всего голосов:
Показать полностью 2 1
[моё] Опрос Покупка Гаджеты Кпк Компьютер Ноутбук Windows Ретро Компьютерное железо Смартфон Wince Embedded Nec Длиннопост
13
278
monobogdan
monobogdan
Посты о ремонте и моддинге ретрогаджетов.
TECHNO BROTHER
1 год назад

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One⁠⁠

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

В своей жизни я обожаю как минимум три вещи: это C# (как и .NET в целом), интересное железо и одноплатные компьютеры. В Embedded-системах на Linux обычно принято писать код на C/C++ для решения чувствительных к производительности задач и интерпретируемых Lua/Python для быстрого прототипирования, которые стали популярны в встраиваемых устройствах сравнительно недавно. Однако о нативной разработке под одноплатники на C# практически ничего не слышно и я решил исправить это недоразумение! В сегодняшнем материале: рассмотрим, какие платформы .NET нам доступны на одноплатниках, научимся работать с GPIO и SPI в юзерспейсе, а также напишем практическое приложение, которое реализовывает драйвер дисплея и выводит на экран определенное изображение.

❯ Предисловие


Одноплатники уже давно вошли в повседневную жизнь многих DIY-щиков, сисадминов и людей, которые интересуются мини-компьютерами. Казалось бы, одну и ту же задачу можно решить несколькими методами на самых разных языках: кто-то предпочитает писать нативный код на тех же плюсах, а особо прожженные — на Plain-C и ассемблере, стараясь получить максимальную производительность, а кто-то хочет сразу перейти к реализации своего устройства не заморачиваясь с подробным изучением того, как чип работает «под капотом» и какие шины существуют, ограничиваясь использованием готовых библиотек.

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Но я лично очень люблю C# за его максимальную гибкость, позволяющую оптимизировать некоторые обращения к памяти путем получения прямых указателей на данные, умеет в удобные темплейты, а также имеет механизм для маршаллинга (прямой импорт функций из библиотек, возможность создать нативный трамплин на управляемый делегат, возможность быстрого копирования из unmanaged в managed окружение и т. п.). Потому всегда думал: почему бы его не использовать в своих embedded-проектах на базе одноплатников?

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Сейчас .NET можно накатить на большинство современных одноплатников, за исключением самых слабых с 64Мб ОЗУ «бутербродом» на чипе (AllWinner F1C100s, AllWinner V3s, некоторые MStar и т. п.). Доступно два рантайма, которые предлагают разные профили и соответственно, разный функционал.

  • dotnet — официальный рантайм, который реализует профиль .NET Core (ой, простите, так уже не модно, теперь это просто .NET). Предоставляет весь современный базовый функционал дотнета вкупе с современными версиями самого C#, но в нём нет, например, Windows Forms для UI (если вы используете полноценные «иксы» и GTK), и System.Drawing для обработки графики и отрисовки текста. Это эталонная реализация дотнета и его можно без проблем накатить на любой одноплатник, для которого есть достаточно свежий Linux.

  • Mono — альтернативная реализация .NET Framework для Linux, ранее активно использовалась в Unity. В отличии от .NET Core, может работать и на более старых одноплатниках на прошлых версиях дистрибутивов Linux, в том числе и самой первой Raspberry Pi. Считается более медленной, чем dotnet, зато имеет значительно большую функциональность, почти идентичную фреймворку на Windows.


В сегодняшней статье мы будем писать программу на C# для OrangePi One, которая должна инициализировать дисплей из юзерспейса и выводить на него определенные данные. В качестве профиля используем .NET Framework 4 (да, я порой старомоден), а одноплатником выступит OrangePi One в стоковой конфигурации ядра, без правок devicetree, где по умолчанию у нас доступен spidev без аппаратных чипселектов, доступ к GPIO из /sys/ и i2cdev.

❯ Настраиваем окружение


Для начала нам нужен образ системы для нашего одноплатника. Какой — выбирать вам. Для большинства устройств на чипсетах AllWinner доступны образы с ядром 3.x, которые более стабильны, но не используют devicetree и не входят в мейнлайн и 5.x, так называемый мейнлайн, но там всё ещё есть некоторые нюансы. Я выбрал Ubuntu Xenial с ядром 5.3.5.

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Теперь самое время накатить рантайм, что мы и делаем командой:

apt-get install mono-all

Обратите внимание, Mono громоздкий и с учетом всех зависимостей может устанавливаться минут 30, если у вас достаточно медленная флэшка. Всё, теперь устройство готово к запуску программ на дотнете, нашу программу можно запустить следующей командой:

mono assembly.exe

Давайте же перейдём к фактической реализации нашей программы и узнаем как работать с периферией устройства!

❯ GPIO


Начинаем с GPIO или «ногодрыга». В Linux есть удобный интерфейс, позволяющий экспортировать пины общего назначения в юзерспейс и рулить ими прямо из sysfs, в том числе и из терминала! Для реализации софтварного SPI или быстрого опроса цифровых пинов такой способ не подойдет — слишком большой оверхед, но для моргания светодиодами, обработки кнопок или… программного ногодрыга чипселектом — вполне подойдет :)

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Как я и говорил выше, GPIO сначала нужно сделать видимым в sysfs — т. е. экспортировать, путём записи номера нужного пина в «файл» /sys/class/gpio/export. Посчитать ID нужного пина можно с помощью простой формулы: (позиция буквы в алфавите — 1) * 32 + номер пина. То есть, для PA10 ID будет 10. При ошибке, системный вызов close выбросит ошибку, а поток в C# — IOException.

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

После этого, по пути /sys/class/gpio/gpio10/ появится директория с файлами direction, куда нужно записать направление нашего пина («in» — ввод, «out» — вывод) и value, куда мы будем записывать или читать значение пина. Реализовать управление пином можно так:

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Да, всё так просто! Мигалка светодиодом в нашем случае будет выглядеть так:

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Переходим к чему посложнее, а именно к SPI из всё того-же юзерспейса!

❯ SPI


Для управления SPI нам потребуется вызов ioctl, который позволяет отправлять устройству различные пакеты с описанием команд. Для этого нам пригодится PInvoke:

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Для каждой аппаратной шины SPI создаётся одно устройство spidev. В случае OrangePi One, по умолчанию экспортирована только одна шина (поскольку и SPI-контроллер на гребенке лишь один) — spidev0.0. Для начала открываем наше устройство для записи:

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Драйвер spidev работает по принципу транзакций — вы посылаете IOCTL с запросом SPI_IOC_MESSAGE (в оригинале это макрос с возможностью послать сразу несколько транзакций в драйвер) и указателем на структуру spi_ioc_transfer с описанием отправляемых или получаемых данных, а драйвер уже сам решает что и когда отправить, при этом вызов ioctl — блокирующий, то есть управление в поток вернется только когда драйвер завершит работу. Но есть нюанс — драйвер SPI у чипсетов AllWinner не может отправлять более 128-байт (на AllWinner A10/A13 — 64-байт) данных за транзакцию, поэтому большой массив данных придётся разбивать на несколько мелких:

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Уже в шоке от обилия указателей в коде на шарпе? :) Надеюсь, комментарии помогут вам разобраться.

Тоже самое и для чтения данных с шины, только вместо txBufPointer — rxBufPointer.

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Пример работы прост до безобразия:

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Имея GPIO и SPI уже можно переходить к реализации чего-то более конкретного!

❯ Дисплей


В качестве дисплея я буду использовать стандартную дешёвую 2.4" матрицу с разрешением 240x320 и контроллером ST7789 с интерфейсом SPI. Для использования дисплея с питанием 3.3В нужно поставить перемычку на позиции J1, как показано на фото ниже.

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Для подключения такого дисплея, достаточно всего лишь 4 (5, если нужен чипселект) сигнальные линии на 40-пиновой гребенке RPi One, плюс один для ШИМ (если нужно регулировать подсветку) и два на питание. Обратите внимание, что лучше сдуть гребенку и паяться к одноплатнику напрямую — у меня из-за китайских дюпонтов постоянно помехи на дисплее и мусор на шине.

Схема подключения:

VCC -> 3.3V

GND -> Масса

CS -> PA9

RESET - PA10

D/C - PA20

MOSI - PC0

SCK - PC2

LED -> 3.3V

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Начинаем с подготовки необходимых GPIO. Для управления дисплеем всегда нужен аппаратный RESET и D/C (бит команда/данные). Чипселект необязателен (его можно кинуть на массу), если это будет единственное устройство на шине, однако в случае ST7789 почему-то в таком случае нужно использовать SPI MODE 3.

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Переходим к реализации коммуникации с дисплеем. Здесь всё просто — ставим CS в низкий уровень, начиная транзакцию, устанавливаем D/C в низкий уровень в случае команды, либо высокий в случае данных и отправляем байт контроллеру, после чего устанавливаем чипселект обратно в высокий уровень.

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Теперь дисплей нужно инициализировать. Здесь нужно сконфигурировать регистры контроллера дисплея для установки режима адресации, цветности и порядка байт в пикселях (BGR или RGB).

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Если всё сделано правильно — то после этого вы должны увидеть «мусор» на дисплее, поскольку состояние ОЗУ не определено после подачи питания на контроллер (но при сбросе содержимое DRAM останется на месте).

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

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

После этого, достаточно лишь непрерывно слать изображение на контроллер дисплея и всё будет работать!

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Поскольку ни один формат изображений не соответствовал моим требованиям (RGB565, без выравнивания), я быстренько накостылил конвертер в самопальный:

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

Загрузчик такого формата выглядит так:

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

А фактическое использование — так:

Пишем программы на C# для одноплатников: что, как и где на примере Orange Pi One Своими руками, Гаджеты, Orange Pi, Raspberry Pi, Программирование, Net, Код, Embedded, Ништяки, Туториал, Умный дом, Дисплей, Длиннопост

❯ Заключение

Как мы видим, писать программы для одноплатников на C# отнюдь не сложно и можно пользоваться всеми приятными фишками языка. Часть кода из этой статьи выдрана из моего сайд-проекта, о котором хочу рассказать вам в ближайшее время — поэтому местами код совсем не причесан, но надеюсь — всё было понятно :)

Также у меня есть канал в Telegram, куда я выкладываю посты с тематикой DIY, ремонта и моддинга, а также программирования под гаджеты прошлых лет и вовремя ссылки на новые статьи.

Показать полностью 22
[моё] Своими руками Гаджеты Orange Pi Raspberry Pi Программирование Net Код Embedded Ништяки Туториал Умный дом Дисплей Длиннопост
29
66
monobogdan
monobogdan
Посты о ремонте и моддинге ретрогаджетов.
TECHNO BROTHER
1 год назад

Ищу девкит (плата для разработки, одноплатный компьютер)!⁠⁠

Друзья! Знаю, что среди читателей есть люди, которые работали над embedded-устройствами. Может у вас есть девкит Samsung S3C6410, когда либо списанный, на продажу?

Ищу девкит (плата для разработки, одноплатный компьютер)! Покупка, Android, Выбор, Гаджеты, Одноплатный компьютер, Embedded, Своими руками, Разработка, Электроника, Схемотехника, Sbc, Компьютерное железо

В целом, интересно было бы любой девкит покопать. Друзья, именно девкит, а не просто Raspberry Pi или Orange Pi. Впрочем, одноплатник на чем-то необычном типа Samsung Hummingbird или Tegra был бы интересен!

[моё] Покупка Android Выбор Гаджеты Одноплатный компьютер Embedded Своими руками Разработка Электроника Схемотехника Sbc Компьютерное железо
12

Продвиньте ваш пост

Перейти
Партнёрский материал Реклама
specials
specials

Нужно больше внимания к постам? Есть способ!⁠⁠

Иногда даже самый интересный материал теряется в потоке новых записей. Если ваш пост остался незамеченным, измените ситуацию. Для этого на Пикабу есть продвижение.

Все просто: оставьте заявку в форме, добавьте ссылку на пост и выберите подходящий бюджет. Все. Ваш пост покажут во всех лентах на специальных позициях. Ну а вы получите дополнительную аудиторию и отклик пользователей.

Продвинуть пост

Продвижение Посты на Пикабу Текст
230
monobogdan
monobogdan
Посты о ремонте и моддинге ретрогаджетов.
TECHNO BROTHER
1 год назад

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях!⁠⁠

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Пожалуй, немалая часть моих читателей так или иначе интересуется DIY-тематикой. И в различных самодельных девайсах порой есть необходимость вывести какую-либо информацию на дисплей, будь это текст, графики или даже какая-то анимация! Для разных задач существуют самые разные дисплеи и в сегодняшнем материале я хотел бы систематизировать и собрать подробнейший гайд об использовании дисплеев с нерабочих мобильных телефонов: какие бывают протоколы и шины данных, как читать схемы устройств и определять контроллеры дисплеев, какие дисплеи стандартизированы, а какие придётся реверсить самому и как быть с подсветкой. В практической части статьи мы подключим дисплей используя протокол MIPI DBI к RP2040 с использованием DMA. Интересно? Тогда добро пожаловать в статью!

❯ Виды дисплеев и их протоколы


Пожалуй, ЖК-дисплеи с самого момента их появления стали основным инструментом для вывода информации и взаимодействия с пользователями. Первые ЖК-панели были монохромными и требовали отдельный драйвер, который занимался выводом изображения на экран и формированием необходимых для его работы напряжений.

Сейчас же всё гораздо проще и каждый любитель DIY-электроники может и сам подключить дисплейчик к своему проекту и использовать в необходимых ему целях. Ведь не зря написаны десятки библиотек по типу AdaFruit LCD, которые упрощают задачу программисту и дают ему возможность оперировать готовыми и простыми операциями по типу «вывести линию» или «отрисовать изображение». Однако, готовые библиотеки — это, конечно, здорово, но они не всегда дают понимание о том, как работают такие дисплеи на программном и аппаратном уровне. И первая часть статьи как раз и будет посвящена этому.

Всего в мире дисплейных матриц существует несколько общепринятых аппаратных протоколов. Некоторые из них можно легко использовать в собственных проектов с микроконтроллерами, с другими придется повозиться:

  • Параллельная шина 8080 — одна из самых простых и понятных шин данных, как в теории, так и на практике. Суть её очень простая: на каждый бит отводится по одной сигнальной линии, плюс две дополнительные линии для сообщения статуса передачи: RD означает запрос чтения, а WR — запрос на запись. Большинство дисплеев использует девятый, неявный бит D/C, который сообщает контроллеру, задаём ли мы номер команды, или уже пишем аргументы для этой команды. Что самое приятное — шина по сути стандартизирована и во многих дисплеях команды на старт записи в видеопамять, а также получение ID-контроллера идентичны. Шина бывает 8-битной и 16-битной (её состояние задаётся битами IM0..IM2 и используется не только для подключения дисплеев, но и микросхем параллельной флэш-памяти, ОЗУ и т. д. Такие шины используются в дисплеях с разрешением до 480x320.

  • SPI — шина, которая наверняка знакома большинству моих читателей. Достаточно простая — у нас есть две сигнальные линии с входным (MISO) и выходным (MOSI) битом, плюс сигнал тактирования, который согласовывает передачу данных. Таким образом, шина получается полнодуплексной. Фактически, каждый байт передаётся по одному биту через одну сигнальную линию, что, по сравнению с 8080, заставляет повышать тактовую частоту контроллера SPI, но при этом занимает гораздо меньше пинов самого МК или процессора. В программном плане, большинство дисплеев представленных в различных интернет-магазинах полностью совместимы с дисплеями 8080, ведь SPI — просто один из режимов работы. Единственный нюанс — из SPI дисплея не всегда можно вычитать ID-контроллера и вообще что-либо читать из регистров дисплея.

  • I2C — относительно редко используемая шина для дисплеев из-за её невысокой производительности, однако, тем не менее, очень подходящая для МК (благодаря использованию только двух сигнальных линий — SDA для данных и SCL для тактирования. Даже чипселект здесь программный благодаря тому, что каждое устройство имеет собственный адрес!), однако её можно найти в дисплеях некоторых телефонов из самого начала 2000-х годов.

  • TTL/параллельный RGB — тут, в общем-то, меня упрекали пару раз из-за того, что я продолжаю называть её TTL, но так сложилось исторически — даже в даташитах эту шину называют именно так. С логической точки зрения она очень простая: у нас есть 16/24 сигнальные линии, где 5 (или 8) бит используются для красного и синего канала и 6 (или опять же 8) бит используются для зеленого цвета (т. е. в 16-битном цвете у нас RGB565, а в 24-битном — RGB888). К ним идут сигналы HSYNC для горизонтальной синхронизации и VSYNC для вертикальной. Вообще, необязательно использовать все сигнальные линии предоставляемые дисплеем — можно использовать, например, RGB332 и использовать всего 8 сигнальных линий. Однако для отображения картинки, необходимо строго соблюдать тайминги синхронизации, иначе дисплей будет просто показывать белый цвет. Помимо цифрового варианта, бывает также аналоговый, очень похожий на телевизионный RGB или VGA. Такие дисплеи обычно используются для матриц до 1024x768 включительно.

  • MIPI DSI — протокол, используемый для дисплеев высокого разрешения — от 480x800 и выше, его можно встретить в большинстве современных смартфонов и планшетов. Кроме того, такие дисплеи используют относительно мало пинов — по два на каждый канал LVDS (обычно в смартфоне около двух-четырех каналов) + две сигнальные линии на тактирование. Звучит всё хорошо? Как-бы не так: протокол дифференциальный и на каждый канал (т. е. логический бит) приходится по две сигнальные линии — одна с положительная, а вторая отрицательная. Затем одна вычитается из другой и получается окончательный сигнал, а сделано это для уменьшения помех от передачи данных по нескольким линиям с очень высокой тактовой частотой без увеличения битности шины.

  • LVDS/eDP — Протоколы, используемые в матрицах ноутбуков, телевизоров и иногда планшетов. На физическом уровне близки к DSI, на программном — если честно, не знаю, но наслышан о некой стандартизации и высоком уровне совместимости. Даже «неродные» ноутбучные матрицы вполне «заводятся», максимум после перепрошивки родной EEPROM, даже если дисплей другого разрешения!


В списке выше, мы рассмотрели несколько популярных аппаратных шин для дисплеев. В данной статье, мы разберемся в программных особенностях таких дисплеев и узнаем, где взять по дисплею одного из следующих типов: SPI, I2C, а также 8080.

❯ Виды дисплеев и их протоколы


Пожалуй, писать статью, где были бы только готовые примеры без объяснения принципов работы «под капотом» было бы плохим тоном. Поэтому предлагаю немного разобраться в системе команд для самых распространенных контроллеров дисплеев в наше время.

У рассматриваемых нами дисплеев есть собственная видеопамять, благодаря чему нет необходимости соблюдать тайминги, а также общий набор команд (или аппаратных регистров), которые мы можем записывать и тем самым менять поведение дисплея. Если мы просто подадим питание на дисплей и попытаемся что-то вывести — у нас ничего не выйдет, поскольку при каждом аппаратном RESET'е, состояние большинства регистров, кроме SleepOn и PowerOn не определено и может содержать в себе любой «мусор». Для корректной работы дисплея, нам необходимо послать определенный набор команд, называемый инициализацией, который установит настройки драйвера дисплея, такие как контраст, параметры цветности, направление развертки изображения из VRAM и т. д. Пожалуй, стоит сразу отметить, что некоторые люди называют регистры дисплея командами — это означает одно и тоже!

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Пример инициализации. На самом деле, не все люди делают такую простыню из вывозов функций чтения/записи регистров дисплея, поскольку это кушает драгоценный ROM. На AVR, например, команды инициализации можно хранить в ROM и читать из PROGMEM.

Если дисплей инициализирован неправильно, то мы можем наблюдать некорректную развертку, артефакты на дисплее и полосы: если вы когда-нибудь прошивали смартфоны прошивками других ревизий, то могли замечать подобный эффект сами.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Набор команд для контроллеров дисплеев частично стандартизирован спецификацией MIPI DBI, которая описывает и закрепляет некоторые конкретные адреса регистров, общие для всех контроллеров дисплея. К ним относится, например, установка «окна» для записи (0x2B и 0x2A), sleepout (0x11) и некоторые другие. Проприетарными командами остаются настройки питания, развертки, контраста и самого драйвера дисплея. Ну и всяческие LUT, а также палитровые режимы (если они есть) тоже проприетарные.

Пример одной из таких стандартизированных команд:

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Почти во всех дисплеях есть разделение отправляемых байтов на команду (или выборка номера регистра для чтения/записи) и на данные. Как обработать текущий байт определяет отдельный пин (или бит, в зависимости от конфигурации дисплея), называемый D/C (Data/Command), иногда также можно встретить названиеRS. Обычно, при записи команды, D/C должен быть на низком уровне, при записи данных, соответственно, на высоком. Суть простая: записываем номер команды (или регистра) при низком D/C, а затем дописываем необходимые аргументы (или конфигурацию регистра) при высоком уровне D/C.
Примерно так:

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Касательно сброса, то в дисплеях обычно существуют два вида этого процесса: аппаратный сброс через соответствующий пин и программный с помощью специальной команды. Пин RESET никогда нельзя оставлять в «воздухе» (т. е. не подключенным) в надежде что «да состояние пинов МК после ресета известно, мусора на шине явно не будет». Мусора может и не будет, а вот дисплей упадет в вечный ресет, поскольку ожидает перехода сигнала RESET в высокий уровень. Тоже самое касается и пина CS, отвечающий за выбор устройства на шине. Если вам не нужен CS и у вас висит только одно устройство на шине — просто притяните его к массе. Некоторые контроллеры (например, ILI9325) адекватно реагируют на CS «в воздухе», некоторые — нет. Только после того, как RESET оказался на высоком уровне, дисплей начнёт принимать команды:

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Переходим конкретно в выводу данных. Для начала вывода изображения на дисплей, нам необходимо выполнить команду 0x2C, которая переведет контроллер дисплея в режим записи данных в видеопамять. После этого, нам остаётся лишь установить высокий уровень на пине D/C и просто слать непрерывный поток пикселей. Контроллер дисплея сам инкрементирует координаты на дисплее и после того, как координаты выйдут за границы нужной области, дисплей сам их переведет в изначальные. Таким образом, достаточно лишь один раз проинициализировать дисплей и просто гонять в него данные, например, с помощью DMA.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Всё просто и понятно :)

❯ Дисплеи с шиной 8080


Пожалуй, подобные дисплеи найти проще всего, поскольку они использовались в большинстве кнопочных телефонов из нулевых. Такие экранчики можно встретить во многих моделях Nokia, Samsung, LG, Fly, Sony Ericsson и большинстве китайских телефонов. С поиском распиновки и разводкой таких дисплеев всё относительно просто и одновременно сложно: на некоторые модели телефонов (например, почти на все Nokia) можно свободно найти схему в гугле и узнать распиновку коннектора дисплея… однако этот коннектор сначала надо сдуть и развести на breakout-плате, или под микроскопом вывести перемычки. В некоторых случаях (например, Siemens S-серии), дисплей просто прижимался к контактам на плате, а сами контакты имели более чем паябельный шаг.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Из схемы на Nokia N70. Этот дисплей применялся во многих Symbian-смартфонах Nokia тех лет: N-Gage/N-Gage QD, N70, N72, 6600 и некоторых других.

Но особо удобными можно считать дисплеи с паябельными шлейфами с большим шагом пинов — такие можно встретить в некоторых телефонах Samsung и большинстве китайских телефонов. Пытливый читатель спросит «так это ж китаец, где ты на него схему будешь искать?». И вот тут, китайские производители нас приятно порадуют, поскольку за редким исключением, такие дисплеи имеют стандартизированную распиновку: лично мне известны матрицы 37 Pin, 39 Pin и 44 Pin. Как найти для них распиновку? Пишем на «алике» или «таобао» 37 pin lcd tft и смотрим: в описании продавец частенько прилагает распиновку (правда учтите, что 37 pin не имеет пинов IM для настройки ширины шины, а 16-битный интерфейс может быть слишком прожорилвый по числу пинов):

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост
Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

В случае с китайцами, иногда можно найти и схему (нажимайте на зеленую стрелку) на устройство: например, почти на все модели Fly схемы лежат в свободном доступе, где почти всегда можно найти распиновку дисплея. Иногда производитель даже выводит тестпоинты на все сигнальные линии и дисплей с тачскрином можно использовать, не выпаивая его с платы!

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Распиновка на Fly IQ239. На нижней части изображения, вы можете увидеть, что такие, безусловно, здоровенные дисплеи можно купить за копейки и сейчас :)

Но задумывались ли вы когда-нибудь, откуда на тачскринах в дисплеях с «али» взялись кнопки «домой», «сообщения», «телефон»? Это ведь те самые дисплеи, которые использовались в «ноклах», просто припаянные к удобной плате! :) Кроме того, на китайские дисплеи без проблем можно найти даташит: обычно они используют контроллеры от ST или ILI, в зависимости от разрешения дисплея.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост
Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Кстати, про девайс на фото выше есть отдельная статья, где я рассказываю что такие девайсы необязательно дербанить но запчасти, ведь под них можно писать полноценные нативные программы!

Концептуально, аппаратная реализация протокола одновременно простая и понятна любому: программа устанавливает состояние каждого бита передаваемого байта на сигнальных линиях D0..D7 (либо D00..D15, если шина у нас 16-битная), а затем просто «дёргает» линию RD (Read или чтение), либо WR (Write или запись) по переходу из низкого уровня в высокий, благодаря чему контроллер дисплея понимает, что байт (или слово в случае 16-битного интерфейса) можно «забирать» с шины. По переходу из высокого уровня в низкий, контроллер снова переходит в режим ожидания следующего байта с шины.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Где взять такие дисплейчики? Да почти везде! Но лучше всего брать дисплеи с китайчиков, которые можно развести на вот таких breakout-платах, которые можно заказать на алике за пару сотен рублей.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Обратите внимание на то, как по свински припаивают подсветку на некоторых дисплеях. И это завод! Лучше сразу прозвоните прежде чем подавать питание. Я, вот, забыл, понадеялся на производителя и по итогу сжёг подсветку :(

Другой вопрос, где искать на них информацию? Помимо схем, можно просто поискать на алике «37 pin lcd tft», «39 pin tft lcd», «24 pin tft lcd» и т. п. Обычно продавцы сами выкладывают распиновку и даже прикладывают ID контроллера дисплея. Поскольку иногда различия в распиновках всё же попадаются, обращайте внимание на то, куда у вас идут дорожки от подсветки и от резистивного тачскрина (если есть), а также вызванивайте все пины с массой — это поможет подобрать правильную распиновку без логического анализатора. Вот, например, дисплейчик из китайской нерабочей реплики Nokia 130 с здоровым 2.4" дисплеем… казалось бы, вообще не понятно что за дисплей, однако воспользовавшись смекалкой, мы находим его распиновку!

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост
Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

❯ SPI-дисплеи


SPI-дисплеи в телефонах встречались относительно редко. В основном, подобные дисплейчики можно было найти в моделях начала 2000х годов: сименсах, моторолах, ранних сонериках T-серии и Nokia на S40. Иногда SPI-дисплеи можно встретить в современных кнопочных телефонах — обычно они имеют шлейф с менее чем 15 пинами, как некоторые модели Fly. Обычно контроллер дисплея поддерживал сразу несколько аппаратных шин, а производитель телефона ещё на этапе установки шлейфа к контроллеру дисплея замыкал необходимые IM-пины выбирая необходимую шину, поэтому программный протокол фактически идентичен дисплеям с шиной 8080.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Несомненным плюсом SPI-дисплеев можно назвать малое число пинов для работы с матрицей: достаточно всего два (плюс сигнал D/C, если дисплей не 9-битный), если повесить RESET на VIO, либо три (четыре), если хотите управлять аппаратным RESET вручную. Но есть и, в некоторой степени, минусы: например, не все микроконтроллеры умеют работать в 9-битном режиме и возможно последний бит придётся досылать «ногодрыгом» (что ломает любую возможность реализации DMA).

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Многие дисплеи с этим интерфейсом задокументированы ещё в начале 2000х годов на известных форумах и сайтах, таких как VRTP, Радиокот и easyelectronics, поэтому проблем с их подключением не возникнет даже у новичка. Даже такой крутой и уважаемый дядька, как @DIHALT, когда-то писал полезный материал об использовании FSMC в STM32.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Достать их новыми можно и сейчас: различные магазины запчастей для телефонов бывают продают их по 20-30-40 рублей… Я недавно себе целую коробочку накупил, в том числе и просто для ремонта смартфонов для будущих статей :)

❯ I2C-дисплеи


Дисплеи с такой шиной — настоящая редкость и обычно попадались в телефонах самого начала нулевых годов с низким разрешением дисплея. Из известных мне — Ericsson'ы и ранние Sony Ericsson T-серии, ODM Motorola (головастики например) и… пожалуй всё.
Казалось бы, разве I2C может быть полезен для работы с дисплеями, где требуется активный вывод графики? Ведь он совсем медленный! Однако, даже он может пригодится для некоторых проектов, а в большинстве МК частенько попадается аппаратный TWI.

Кроме того, I2C дисплейчики удобно отлаживать: благодаря тому, что периферийное устройство должно отрапортовать ACK (состояние успешности получения байта) мастер-устройству, можно сразу определить обрыв линий до дисплея. Но какой-то конкретной информации по ним я не смогу написать — они все совсем разные :( Правда, полезным линком поделюсь, ребята с форума VRTP собрали хорошую таблицу с различными контроллерами дисплеев, где бывают и i2c!

❯ Подсветка


Отдельного радела стоит тема подсветки дисплеев. По первой может показаться, что тут всё просто: современным дисплеями достаточно 5В, а на старых можно замерить напряжение бустера на живом девайсе и смастерить свой DC-DC повышающий преобразователь, или взять, например, уже готовый драйвер, как известный в определенных кругах LTYN. На самом деле и тут есть свои нюансы.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Итак, каким образом реализована подсветка в том или ином устройстве? Обычно её реализация заключается в последовательном соединении двух и более светодиодов, которые формируют небольшую ленту под рассеивающей плёнкой. На современных китайских дисплейчиках, для работы в полную яркость достаточно всего лишь 5В источника питания + токоограничивающего резистора. Но что самое приятное, подсветка в таких дисплеях способна работать и при 3.3В, пусть менее ярко, но всё равно вполне читабельно.

Если вы делаете портативное маломощное устройство, работающее от одного Li-Ion аккумулятора, то достаточно лишь пустить 3.3В с линейного стабилизатора, который формирует напряжение VSYS для микроконтроллера. Таким образом, у вас будет стабильная подсветка среднего уровня яркости. В качестве альтернативного «бомж» варианта, когда нет возможности собрать нормальный драйвер подсветки, можно попробовать подключить светодиоды напрямую к АКБ, но при разряде дисплей будет потихоньку «тухнуть». Ещё один «бомж» вариант — разобрать дисплейный модуль, порезать дорожки на ленте и соединить пару светодиодов параллельно, выведя их через отверстие, откуда выходит шлейф дисплея, однако в таком случае, потребление подсветки заметно увеличится.

Правильным выходом будет взять с того-же телефона бустер подсветки с индуктивностью и иной необходимой обвязкой, и собрать бустер самому. Особой популярностью когда-то пользовались вышеупомянутые LTYN из телефонов Samsung (это маркировка известного драйвера LT1937). Уровнем подсветки на подобных бустерах телефоны управляют с помощью встроенного ШИМ-контроллера, чем можете воспользоваться и вы :)

❯ Запускаем дисплейчик на практике


В первой части статьи, я постарался ввести вас в курс дела и кратко рассказать о том, как работают такие дисплейчики «под капотом». Как видите — с теоретической точки зрения, ничего сложного нет: пересылаем данные на дисплей, да вовремя дёргаем пин D/C. Но какого же это на практике?


К сожалению, у меня на руках не нашлось подходящего дисплейчика от мобильного телефона (я ведь брал новые по уценке, не все заработали нормально), поэтому в качестве примера работы мы возьмём фактически такой же «китайский» дисплей с алика. Но будьте уверены — с большинством дисплеев, принцип работы будет идентичен (если мы говорим о дисплеях 2005г.в и моложе).

В качестве МК, мы возьмём мой любимый RP2040, который, по моему мнению, незаслуженно обделен вниманием. Время от времени я делаю всякие прикольные девайсы на базе этого МК, поэтому крайне рекомендую его всем моим читателям :)

Давайте же перейдем к практической части статьи!
Обычно при создании проекта, я просто клонирую с гита RPi сэмплы с уже готовыми файлами CMake, беру hello world, конфигурирую CMakeLists.txt и пишу свою программу. На малинке пока что нет такого удобного способа создания проекта, как idf.py create-project :)
Само собой, для удобства отладки я всегда включаю встроенную в чипсет эмуляцию UART через USB.

if (TARGET tinyusb_device)
add_executable(hello_usb
main.cpp
)

# pull in common dependencies
target_link_libraries(hello_usb pico_stdlib hardware_spi)

# enable usb output, disable uart output
pico_enable_stdio_usb(hello_usb 1)
pico_enable_stdio_uart(hello_usb 0)

# create map/bin/hex/uf2 file etc.
pico_add_extra_outputs(hello_usb)

# add url via pico_set_program_url
example_auto_set_url(hello_usb)
elseif(PICO_ON_DEVICE)
message(WARNING "not building hello_usb because TinyUSB submodule is not initialized in the SDK")
endif()

И инициализирую USB-стек и биндинги stdout к нему:

stdio_init_all();
sleep_ms(1000);

Задержка здесь важна, иначе девайс отказывается определятся в системе. Переходим, собственно, к разводке дисплея. Для работы нам достаточно лишь питания, подсветки, общей массы и четырёх сигнальных линий: MOSI, CLK, DC, RESET. На CS я обычно ставлю перемычку с массой, т. к обычно не вешаю что-то ещё на одну шину с дисплеем.

Переходим к инициализации дисплея. Наш экранчик работает на базе контроллера ST7735R и имеет разрешение 128x160. Сначала, назначаем функции для пинов и дёргаем RESET:

gpio_set_function(LCM_SPI_CLK, GPIO_FUNC_SPI);
gpio_set_function(LCM_SPI_MOSI, GPIO_FUNC_SPI);

// HW reset
gpio_init(LCM_RESET);
gpio_set_dir(LCM_RESET, true);
gpio_put(LCM_RESET, false);
sleep_ms(400);
gpio_put(LCM_RESET, true);

gpio_init(LCM_DC);
gpio_set_dir(LCM_DC, true);

spi_init(spi0, 105535000);

Весьма негусто скажете вы? Ну, с минорными изменениями, здесь заработает дисплейчик любого разрешения, даже 480x320! Переходим к фактической инициализации:

void lcmCommand(unsigned char byte)
{
gpio_put(LCM_DC, 0);
spi_write_blocking(spi0, &byte, sizeof(byte));
}

void lcmData(unsigned char byte)
{
gpio_put(LCM_DC, 1);
spi_write_blocking(spi0, &byte, sizeof(byte));
}

...

lcmCommand(0x11);
sleep_ms(120);
lcmCommand(0xB1);
lcmData(0x01);
lcmData(0x2C);
lcmData(0x2D);
lcmCommand(0xB2);
lcmData(0x01);
lcmData(0x2C);
lcmData(0x2D);
lcmCommand(0xB3);
lcmData(0x01);
lcmData(0x2C);
lcmData(0x2D);
lcmData(0x01);
lcmData(0x2C);
lcmData(0x2D);

lcmCommand(0xB4);
lcmData(0x07);

lcmCommand(0xC0);
lcmData(0xA2);
lcmData(0x02);
lcmData(0x84);
lcmCommand(0xC1);
lcmData(0xC5);
lcmCommand(0xC2);
lcmData(0x0A);
lcmData(0x00);
lcmCommand(0xC3);
lcmData(0x8A);
lcmData(0x2A);
lcmCommand(0xC4);
lcmData(0x8A);
lcmData(0xEE);

lcmCommand(0xC5);//VCOM
lcmData(0x0E);
lcmCommand(0x36);//MX, MY, RGB mode
lcmData(0xC8);

lcmCommand(0xe0);
lcmData(0x02);
lcmData(0x1c);
lcmData(0x07);
lcmData(0x12);
lcmData(0x37);
lcmData(0x32);
lcmData(0x29);
lcmData(0x2d);
lcmData(0x29);
lcmData(0x25);
lcmData(0x2b);
lcmData(0x39);
lcmData(0x00);
lcmData(0x01);
lcmData(0x03);
lcmData(0x10);
lcmCommand(0xe1);
lcmData(0x03);
lcmData(0x1d);
lcmData(0x07);
lcmData(0x06);
lcmData(0x2e);
lcmData(0x2c);
lcmData(0x29);
lcmData(0x2d);
lcmData(0x2e);
lcmData(0x2e);
lcmData(0x37);
lcmData(0x3f);
lcmData(0x00);
lcmData(0x00);
lcmData(0x02);
lcmData(0x10);
lcmCommand(0x2A);
lcmData(0x00);
lcmData(0x02);
lcmData(0x00);
lcmData(0x81);

lcmCommand(0x2B);
lcmData(0x00);
lcmData(0x01);
lcmData(0x00);
lcmData(0xA0);
lcmCommand(0x3A);//65k mode
lcmData(0x05);
lcmCommand(0x29);//Display on

// Set viewport
lcmCommand(0x2A);
lcmData(0 >> 8);
lcmData(0 & 0xFF);
lcmData(128 >> 8);
lcmData(128 & 0xFF);

lcmCommand(0x2B);
lcmData(0 >> 8);
lcmData(0 & 0xFF);
lcmData(160 >> 8);
lcmData(160 & 0xFF);

Прошиваем наш МК и смотрим что получилось. Видим шум на экране? Значит дисплей инициализирован верно!

После инициализации дисплея, мы можем выводить на него данные! Дабы дать возможность процессору заниматься другими делами во время передачи картинки на дисплей, мы настроим один из DMA-каналов. DMA-контроллер занимается пересылкой данных из ОЗУ в другой участок ОЗУ (аппаратный memcpy) или периферию. Как раз для второго случая, т. е. пересылки данных в контроллер SPI, мы и будем использовать DMA!

Аллокейтим фреймбуфер, куда мы будем выводить нашу картинку и настраивает DMA-канал:

int backBufSize = LCM_WIDTH * LCM_HEIGHT * 2 + 1;
backBuffer = (byte*)malloc(backBufSize);

printf("LCM: Setting up DMA channel...\n");
bulkDMAChannel = dma_claim_unused_channel(true);
cfg = dma_channel_get_default_config(bulkDMAChannel);
channel_config_set_transfer_data_size(&cfg, DMA_SIZE_8);
channel_config_set_dreq(&cfg, spi_get_dreq(spi0, true));

Переходим к выводу изображения на дисплей. Для того, чтобы просто установить цвет пикселя в любых координатах экрана, достаточно лишь посчитать смещение от начала указателя на фреймбуфер к определенным координатам экрана. Формула очень простая и понятная: ширина дисплея * Y-координата + x координата и результат предыдущих операций помноженный на число байт в одном пикселе.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

__inline void pixelAt(short x, short y, short color)
{
if(x < 0 || y < 0 || x >= LCM_WIDTH || y >= LCM_HEIGHT)
return;

byte* col = (byte*)&color;
*((short*)&backBuffer[(y * 128 + x) * 2]) = color;
}

В функции есть валидация границ дисплея. Если уверены, что не зайдете за границы дисплея — можете убрать проверку, будет шустрее.

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

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

А вот как с этим всем работать:

stdio_init_all();

sleep_ms(1000);


printf("LCM test by monobogdan\n");


lcmInitInterface();

lcmAllocBackBuffer();

lcmInit();


grDrawBitmapTransparent((void*)&pikabu, PIKABU_WIDTH, PIKABU_HEIGHT, 0, 0);

lcmFlush();


while(1)

{


}

Запускаем и...

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Можно сделать чуть комплекснее, добавив альфа-блендинг и аффинные трансформации (возможность поворота и скейла картинок), но пока-что такой задачи не стоит. Ну что, всё очень просто и понятно? :) Пример прошивки можно найти на моём GitHub!

Производительность такого способ на RP2040 можно увидеть вот в этом видосе (на Пикабу не смог залить из-за ограничения на число медиа-элементов). Обратите внимание, что подход предложенный выше больше подходит именно для динамического вывода изображения без dirty-регионов. Он подойдет для игровых консолей, камер, анимаций или устройств с выводом динамической информации по типу осциллографов. Если вам нужно обновлять картинку реже, например, если вы делаете умные часы с плеером, то нет необходимости занимать довольно большой объем ОЗУ фреймбуфером, ведь вы можете писать напрямую в видеопамять. Тут уже решать в зависимости от конкретной ситуации именно вам :)

❯ Заключение


Вот мы с вами и систематизировали информацию о том, как использовать дисплеи с мобильных телефонов в своих проектах. Надеюсь, информация была достаточно полезной для вас!
Однако, у меня к вам просьба: пожалуйста, не «дербаньте» рабочие девайсы «на запчасти» :(
Это будет не очень гуманно по отношению к нашему «технобалдежу», где мы наоборот стараемся найти применение стареньким девайсам :)

Был ли для вас материал полезен? Пишите в комментариях.

Полезный материал?
Всего голосов:
Какие дисплейчики подключали?
Всего голосов:

❯ Важное объявление для читателей касательно будущей рубрики

Друзья! Я, как и многие мои читатели, помимо программирования и железа обожаю тачки! Особенно те тачки, где что-то нужно доделывать самому… и речь, конечно-же, о ТАЗах! Я долго думал, но всё же решился: сейчас я коплю на будущий интересный проект, связанный с ультрабюджетным электронным дооснащением автомобиля, который старше меня в полтора раза — скорее всего, речь пойдет о ВАЗ 2108/2109/21099, причём не исключено что карбюраторной! В планах довольно крутой проект, заключающийся в следующем: мы спроектируем очень дешевый бортовой компьютер (т.е панель) для управления автомобилем на базе дешевого Б/У планшета за пару сотен рублей. Планшет будет связан с управляющим МК через UART (о подобной коммуникации через хардварные протоколы я уже писал целых две статьи: сам себе Linux смартфон, превращаем планшет с нерабочим тачскрином в игровую консоль), и с планшета мы сможем не только управлять основными системами машины (стеклоподъемники, центральный замок и соленоид багажника), но и собирать и пытаться примерно посчитать некоторую информацию о расходе, километраже и стабильности работы двигателя на карбюраторной(!) машине без электронных систем с завода!

Если вдруг двигатель машины будет живенький и заводиться с полтычка, то может и удаленный прогрев постараюсь реализовать :)

В наши задачи будет входить не только проектирование аппаратной части такого оснащения, но и разработка симпатичного интерфейса для самой панели, дабы было не хуже чем в BMW :D Всеми схемами, исходным кодом и инструкциями я буду делится с вами в каждой статье и, как обычно, расскажу обо всех деталях реализации во всех подробностях! У меня уже есть некоторые идеи и наработки. Собственно, почему-б и не попробовать? Будет новая рубрика в блоге: апгрейд автомобилей глазами электронщика и прожженного программера.

Мобильные экранчики в ваших проектах: большой и понятный о гайд о различных дисплеях! Опрос, Гаджеты, Покупка, Программирование, C++, Raspberry Pi, Arduino, Дисплей, Экран, 2D, Графика, Embedded, Своими руками, Микроконтроллеры, Код, Электроника, Железо, Длиннопост

Фото не моё, из интернета

Если вам нравятся мои статьи, вас интересует развитие такой рубрики и у вас есть желание и возможность — можете помочь проекту копеечкой с помощью формы доната ниже. Пикабу позволяет остаться анонимным и донатить даже без регистрации. Сейчас у меня есть 40 тысяч рублей личных накоплений, на покупку самой машины планирую выделить 70-80 тысяч рублей (я живу в Краснодарском крае, так что здесь ещё есть шансы найти что-то +- живое за такие деньги), так что остаётся собрать около 30-35 тысяч рублей. За каждую копейку я готов отчитаться (по факту покупки машины я сделаю пост с фотографиями авто, ДКП, а также оглашу фронт будущих работ и сразу начну заниматься проектом).

Интересный проект с тазиком?
Всего голосов:
Показать полностью 25 3
[моё] Опрос Гаджеты Покупка Программирование C++ Raspberry Pi Arduino Дисплей Экран 2D Графика Embedded Своими руками Микроконтроллеры Код Электроника Железо Длиннопост
12
128
monobogdan
monobogdan
1 год назад
TECHNO BROTHER

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI?⁠⁠

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Зачастую в процессе разработки собственных устройств или моддинга уже существующих, встаёт задача выполнения стороннего кода: будь то ваши собственные программы с SD-флэшек, или программы, написанные другими пользователями с помощью SDK для вашего устройства. Тема компиляторов и кодогенерации достаточно сложная: чтобы просто загрузить ELF или EXE (PE) программу, вам нужно досконально разбираться в особенностях вашей архитектуры: что такое ABI, релокации, GOT, отличие -fPIE от -fPIC, как писать скрипты для ld и т. п. Недавно я копал SDK для первых версий Symbian и основываясь на решениях из этой ОС понял, каким образом можно сделать крайне «дешевую» загрузку любого нативного кода практически на любом микроконтроллере, совершенно не вникая в особенности кодогенерации под неё! Сегодня мы с вами: узнаем, что происходит в процессе загрузки программы ядром Linux, рассмотрим концепцию, предложенную Symbian Foundation и реализуем её на практике для относительно малоизвестной архитектуры — XTensa (хотя она используется в ESP32, детали её реализации «под капотом» для многих остаются загадкой). Интересно? Тогда добро пожаловать под кат!

❯ Как это работает?


Думаю, для многих моих читателей реализация процесса загрузки exe-программ и dll-библиотек в память процесса оставалась эдаким чёрным ящиком, в детали реализации которого вдаваться не нужно. Отчасти это так и есть: современные ОС разруливают процесс загрузки бинарников в память сами, не требуя от программиста вообще ничего, даже понимания того, куда будет загружена его библиотека или программа.

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост




Давайте для общего понимания вкратце разберемся, как происходит загрузка программ в Windows/Linux:

1. Система создаёт процесс и загружает в память программы секции из ELF/PE. Обычные программы для своей работы используют 3 секции: .text (код), .data (не-инициализированный сегмент памяти для глобальных переменных), .bss (сегмент памяти для инициализированных переменных). Каждому процессу выделяется собственное адресное пространство, называемое виртуальной памятью, которое не позволяет программе испортить память ядра, а также позволяет не зависеть от разметки физической памяти на выполняющей машине. Концепцию виртуальной памяти реализует специальной модуль в процессоре, называемый MMU.

2. Если бы наши программы не использовали никаких зависимостей в виде динамических библиотек, то на этом процесс загрузки можно было бы закончить: каждая программа имеет свой адрес загрузки, относительно которого линкер строит связи между обращениями к коду/данным программы. Фактически, для самых простых программ линкеру остаётся лишь прибавить адрес загрузки программы (например, 0x100) к каждому абсолютному обращению к памяти.
Однако современные программы используют десятки библиотек и для всех предусмотреть собственный адрес загрузки не получится: кто-то где-то всё равно будет пересекаться и вероятно, портить память. Кроме того, современные стандарты безопасности в Linux рекомендуют использовать позиционно-независимый код, дабы использовать преимущества ASLR (Address Space Layout Randomization, или простыми словами возможность загрузить программу в случайное место в памяти, дабы некоторые уязвимости, завязанные на фиксированном адресе загрузки программы перестали работать).

3. Поэтому для решения этой проблемы придуман т. н. динамический линкер, который уже на этапе загрузки программы или библиотеки патчит программу так, чтобы её можно было загрузить в любой участок памяти. Для этого используются данные, полученные от обычного линкера а этапе компиляции программы: помимо .text, .data и .bss, линкер создаёт секции .rel и .rel-plt, которые называются релокациями. Если объяснять совсем условно, то релокации — это просто запись вида «какой абсолютный адрес в коде программы нужно пропатчить» -> «на какое смещение его пропатчить». Самая простая релокация выглядит вот так:

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Где по итогу:

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

.rel-plt же служит для резолвинга вызовов к dll/so: изначально программа ссылается на заранее определенные в процессе компиляции символы, которые уже в процессе загрузки патчатся на физические адреса функций из загруженной библиотеки.

И казалось бы — всё очень просто, пока в дело не вступают GOT (Global Offset Table — глобальная таблица смещений) и особенности реализации конкретного ABI. И ладно бы x86 или ARM, там всё разжевано и понятно, однако на других архитектурах начинаются проблемы и не всегда очевидно что и где за что отвечает.

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

  1. Писать полноценный загрузчик ELF-бинарников. ELF может оказаться громоздким для некоторых окружений и его реализация может оказаться тривиальной не для всех.

  2. Зарезервировать определенный сегмент в памяти (пусть с 0xFFF по 0xFFFF) и скомпилировать нашу программу с адресом загрузки 0xFFF с параметром -fno-pic. В таком случае, линкер сгенерирует обращения к памяти по абсолютным адресам — если переменная лежит по адресу 0xFFF, то программа будет обращаться сразу к этому адресу памяти, без необходимости что либо динамически линковать. Именно такой подход использовался во времена ZX Spectrum, Commodore 64 и MS-DOS (однако там роль «виртуальной памяти» выполняла такая особенность 8086, как сегменты). У такого подхода есть и минусы: относительная невозможность загрузки сразу нескольких программ одновременно, зарезервированное пространство линейно отъест небольшой кусок памяти у основной прошивки, нет возможности динамической аллокации секций. Зато такой код теоретически будет работать быстрее, чем PIC.

    Проблемы реализации такого способа: иногда нужно лезть в систему сборки основной прошивки и патчить скрипт линкера так, чтобы он не трогал определенный регион памяти. В случае esp32, например, это требует патча в сам SDK и возможного «откола» от мейнлайн дистрибутива.

  3. Использовать программу с относительной адресацией, однако без сегментов .bss и .data. Самый простой в реализации способ, который к тому же очень экономичен к памяти, позволяет загружать программу в любое место и пользоваться всеми фишками динамического аллокатора и не требует вмешательств в основную прошивку, кроме примитивного загрузчика программ. Именно его я и предлагаю рассмотреть подробнее.


Недавно мы сидели в чате ELF-сцены (разработка нативных программ под телефоны Siemens, Sony Ericsson, Motorola и LG с помощью хаков) и думали, как же можно реализовать загрузчик сторонних программ на практически неизвестных платформах. Кто-то предлагал взять ELF под основу — однако с его реализацией под некоторые платформы есть трудности, а кто-то предлагал писать «бинлоадер» — самопальный формат бинарников, который получается из, например, тех же эльфов.

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

В это же время я копал SDK для Symbian и хорошо помнил, что в прикладных приложениях для этой ОС нет поддержки глобальных переменных вообще. Да, сегмент .data и .bss полностью отсутствует — переменные предлагается хранить в структурах. Почему так сделано? Всё дело в том, что каждая программа в Symbian — это dll-библиотека, которую загружает EKA и создаёт экземпляр CApaApplication. И дабы была возможность загрузить dll один раз для всех программ (что справедливо для системных библиотек), ребята полностью выкинули возможность использования любых глобальных переменных. А ведь идея интересная!

Однако в таком подходе есть несколько серьезных ограничений:

  • Отсутствие глобальных переменных может стать проблемой при портированиии уже существующего софта, хотя вашим программам ничего не мешает передавать в каждую функцию структуру с глобальным стейтом, который можно при необходимости изменять. Кроме того, нет ограничений на использование C++ (за исключением необходимости ручной реализации new/delete и отсутствием исключений).

  • Отсутствие преинициализированных данных. Вот это уже может стать относительно серьёзной проблемой, у которой, тем не менее, есть свои обходные решения. Например если вы храните команды для инициализации дисплея в таблице, или какие-либо калибровочные данные — вы не сможете их объявить, просто используя инициализаторы в C. Тоже самое касается и строковых литерал. Тут есть два варианта: часть таблиц можно вынести на стек (если эти самые таблицы достаточно маленькие), либо подгружать необходимые данные из бинарника с помощью основной прошивки (например, LoadString и т. п.).


Давайте же на практике посмотрим, имеет ли право на жизнь такой подход!

❯ Практическая реализация


Формат нашего бинарника будет до безобразия прост: небольшой заголовок в начале файла и просто сырой дамп сегмента .text, который можно экспортировать из полученного elf даже без необходимости писать скрипт для линкера. При этом нужно учесть, что ESP32 — это микроконтроллер частично Гарвардской архитектуры, т. е. шина данных и кода у него расположены отдельно. Однако у чипа есть полноценный MMU, который позволяет маппить регионы физической памяти в виртуальную память, чем мы и воспользуемся в итоге!

Заголовок нашего бинарника будет выглядеть вот так:

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Программа общается с основной прошивкой посредством псевдо-syscall'ов: функции, которая в качестве первого аргумента ожидает номер нужной службы и один 32х-битный указатель для описания структуры с параметрами. Реализация syscall'ов — одна из самых простых и неприхотливых с точки зрения обратной совместимости с будущими прошивками.

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Концептуально всё очень просто: GetGlobalStateSize сообщает нашему загрузчику размер структуры для хранения глобального стейта, в то время как Start уже фактически заменяет main() в нашей программе. Необходимости в crt0 нет, поскольку весь необходимый инит выполняет бутлоадер ESP32. Впрочем, при желании вы можете выделить отдельный стек для вашей программы — это повысит надежность, если выполняемая программа удумает испортить стек.

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Собираем нашу программу:

xtensa-esp32-elf-cc.exe test.c -fno-pic -nostdlib -nostartfiles -Wl,--section-start=.text=0x0

xtensa-esp32-elf-objcopy.exe --only-section=.text --output-target binary a.out run.bin

-fno-pic отключает генерацию кода, зависимого от GOT, -nostdlib и -nostartfiles убирает из билда crt0 и stdlib, благодаря чему мы получаем только необходимый код. --section-start задает смещение для загрузки секции .text на 0x0 (в идеале это делать необходимо из скрипта для ld).
objcopy скопирует из полученного ELF только необходимую нам секцию .text.

Как же это работает на практике? Давайте дизассемблируем выходной бинарник и посмотрим, что у нас дает на выхлопе cc:

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Обратите внимание, что Start вызывает подфункции с помощью инструкции CALLX8, которая в отличии от обычного Immediate-версии CALL8, выполняет переход относительно текущего адреса в PC, благодаря чему переход полностью независим от адреса загрузки программы в памяти. А благодаря тому, что все данные, в том числе и указатель на глобальный стейт передаются через стек, нет необходимости релокейтить сегменты данных.

По итогу всё, что нужно от загрузчика бинарников — это загрузить программу в память для инструкций, выделить память для структуры с стейтом программы и передать управление Start. Всё!
Конкретно в случае ESP32, у нас есть два возможных решения задачи загрузки программы в память:

  1. Загрузить программу в IRAM. Такая возможность теоретически есть, однако на практике загрузчик ESP32 устанавливает права только на чтение и выполнение на данный регион памяти. Попытка что-то скопировать туда закончится исключением SIGSEGV. Кроме того, сегмент IRAM относительно небольшой — всего около 200Кб.

  2. Самопрограммирование. Для этого, в esp32 есть два механизма — Partition API и SPI Flash API. Я выбрал Partition API для простоты реализации.


Для нашей прошивки необходимо будет переразметить флэш-память. Для этого запускаем idf.py menuconfig, идём в Partition Table -> Custom partition table CSV. Создаём в папке проекта partitions.csv, куда пишем:

# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
executable, data, undefined, 0x110000, 0x10000

Для заливки программы можно использовать соответствующее Partition API, либо parttool.py:

parttool.py --port "COM41" write_partition --partition-name=executable --input "run.bin"

Переходим к загрузчику программы:

Выполняем сторонние программы на микроконтроллерах с Гарвардской архитектурой: как загружать программы без знания ABI? Опрос, Гаджеты, Программирование, C++, Avr, Arduino, Esp32, Embedded, Своими руками, Самоделки, Esp8266, Assembler, Железо, Микроконтроллеры, Длиннопост

Прошиваем ESP32:

idf.py build

idf.py flash

idf.py monitor

И смотрим результат:

SysCall 25

SysCall 35

SysCall 15

Всё работает!

❯ Заключение


Как видите, ничего сложного в выполнении сторонних программ при условии соблюдении некоторых ограничений нет. Да, в таком подходе есть как серьезные плюсы, так и минусы, однако он делает своё дело и позволяет реализовать запуск игр на кастомных игровых консолях, или сторонних программ на самодельных компьютерах. Ну и конечно же не стоит забывать про плагины! Авось в вашем решении нужна возможность расширения функционала устройства, однако предоставлять исходный код или даже объектные файлы нет возможности — тогда вам может пригодится и такая методика.

Пожалуй, стоит упомянуть ещё один… очень своеобразный метод, который я иногда встречаю при реализации самодельных компьютеров. Люди пишут… эмуляторы 6502/Z80 :)
И если такой подход ещё +- применим к ESP32, то в AVR просадки производительности будут слишком серьезными. Так зачем, если можно использовать все возможности ядра на максимум?

Полезный материал?
Всего голосов:
Приходилось ли загружать сторонний код в ваших устройствах?
Всего голосов:
Показать полностью 9 2
[моё] Опрос Гаджеты Программирование C++ Avr Arduino Esp32 Embedded Своими руками Самоделки Esp8266 Assembler Железо Микроконтроллеры Длиннопост
12
472
monobogdan
monobogdan
1 год назад
TECHNO BROTHER

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей⁠⁠

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост



Китайские производители не перестают удивлять: многие видят явные перспективы рынка одноплатных компьютеров и стараются представить целую линейку девайсов на самых разных чипсетах, а разработчики стараются использовать уже привычное и поддерживаемое долгие годы железо. К ним относятся решения на чипсетах AllWinner, RockChip, Tegra. Другие же стараются взять малоизвестный, но дешевый чип для иного круга применений, развести на нем компактную плату и продавать по цене пачки сухарей, подобные решения появляются регулярно. Один из таких одноплатников я недавно купил на AliExpress — некий DongShan Pi Pico W, на базе экзотического чипсета SigmaStar SSD210, всего за 600 рублей. И тут действительно есть на что посмотреть: два ядра Cortex-A7, контроллер TTL матриц, 2D GPU, Wi-Fi, 64Мб ОЗУ и Embedded Linux на борту. Более того, девайс поставляется в виде System on Module с переходной Evaluation-платой, что позволяет использовать это устройство в составе других гаджетов! Что это за красавец и на что он способен? Читайте в статье!!

❯ Что это за девайс?


Думаю, большинство моих читателей когда-либо слышали об одноплатных компьютерах. Это компактные и достаточно мощные устройства, которые можно использовать как в качестве компактных серверов или даже десктопных машин, так и собрать своё устройство на базе готового одноплатного компьютера. Одноплатники используется во многих сферах: вендинговые автоматы, умные экраны, самопальные игровые консоли и смартфоны, DIY-ноутбуки!

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост



Однако чаще всего можно увидеть обзоры и проекты на базе довольно известных устройств: Raspberry Pi, Orange Pi, Olimex. Эти платы, скажем так, достаточно дорогие: и если Orange Pi One/Zero ещё можно ухватить за 1.000 рублей на вторичке (один из таких я купил еще летом. Узнав о моем блоге, продавец стал моим читателем и вместо одного OPi прислал мне целых два — один в подарок!), а за RPi Zero придется выложить как минимум 2.000 рублей. Однако есть ещё один сегмент одноплатных компьютеров: ультра-дешевые, разработанные на базе чипов для конкретного применения. Один из самых известных представителей — MangoPi/CherryPi R3, который работает на базе AllWinner F1C200s — чипа для… электронных книг!

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост



Информации по дешевым, почти неизвестным одноплатникам довольно мало. У них не очень хорошая поддержка (кроме AllWinner, там почти все чипсеты есть в mainline-ветке Linux), в них могут обнаружится аппаратные баги, да и многие люди вообще не замарачиваются с ними, предпочитая переплатить, но купить что-то более стабильное. Но не я! Я просто обожаю различные ультрадешевые девайсики, поэтому недавно по наводке моего активного читателя NutsUnderline, я заказал интереснейший девайс — DongShan Pi Pico-W. Устройство обошлось мне всего в 600 рублей, но в первую очередь, меня привлек форм-фактор устройства и его чипсет. Некий SigmaStar SSD210!

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост




Я заказал сразу два устройства: первую партию очень быстро разобрали, поэтому я взял «с запасом». Сейчас конкретно этот одноплатник пока-что не доступен в магазине продавца, однако у него же продаются другие устройства на базе SSD210. Можете найти их по ключевому слову: «SSD210» (прямые линки публиковать не буду, дабы не сочли за рекламу). Через месяц оба красавца пришли ко мне и я принялся их изучать.

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост



Какое же было моё удивление, когда я обнаружил, что это по сути System on Module, который вручную надо припаять к Evaluation-плате! Вкратце это значит, что на базе таких SoM вы можете развести плату, протравить её, а затем припаять одноплатник поверх нее и сделать своё полноценное устройство, «без соплей»! Производителю плюсик за такую гибкость — я не очень люблю одноплатники с штырьковыми гребенками. Хотя, конечно, это очень сильно помогает при разработке макета устройства.

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

❯ Характеристики


Но чем он так меня привлек, помимо SoM направленности? Своим крутым чипсетом! Давайте ознакомимся с его характеристиками поближе:

  • Процессор: SigmaStar SSD210. 2 ядра Cortex-A7, работающие на частоте до 1ГГц. 16Кб кэш инструкций и 16Кб кэш данных, плюс 128Кб L2-кэша. В процессоре есть FPU и поддержка SIMD-инструкций Neon (альтернатива SSE в x86). Нехило, правда?

  • Поддержка дисплеев: У чипсета есть выделенный модуль для работы с внешними матрицами. Поддерживаются TTL дисплеи (до 1024x768), SPI-матрицы с клоком до 54МГц (480x320), а также прямой RGB аналоговый RGB сигнал (этот интерфейс можно использовать для подключения к ТВ с тюльпанами или аналоговым матрицам). Про типы дисплеев, вы можете прочитать в моей статье.

  • 2D GPU: Поддержка отрисовки линий, прямоугольников, градиентной заливки, BitBLT, клиппинг, дизеринг, автоматическая конвертация формата пикселя (с RGB888 в RGB565). Это серьёзно снимает нагрузку с ЦПУ при рисовании графики, однако поддерживается ли он в Linux — вопрос другой.

  • ОЗУ: 64Мб DDR2 памяти «бутербродом» прямо с чипсетом, плюс поддержка до 512Мб DDR2 внешней памяти, до 1333Мб/с.

  • Звук: Один моно-выход DAC, два выходных канала I2S, вход микрофона. Входные каналы поддерживают частоту дискретизации до 96КГц. Можно организовать вывод звука лишь подключив внешний усилитель. Внешний ЦАП не обязателен, если вам не нужен стерео-звук.

  • Память: Контроллер NOR/NAND SPI-памяти, до двух параллельно подключенных чипов, плюс поддержка SDIO. BootROM поддерживают загрузку с MicroSD карт.

  • Сеть: Ethernet, на DongShan Pi есть Wi-Fi.

  • USB: Как хост, так и ведомое устройство

  • Периферия: 4 канала ШИМ, GPIO, 4 UART, 2 канала SPI, 2 канала I2C

  • Камера: До двух камер по интерфейсу MIPI CSI

  • Безопасность: Есть аппаратное шифрование.

  • Питание: 0.9В ядро, 1.8В ОЗУ, 3.3В I/O


Очень даже бодро, согласитесь? Вообще, производитель подразумевает SSD210 как чипсет для HMI-дисплеев — т. е. умные дисплеи, которые могут, например, служить стендами в музеях, или служить для заказа билетов в кино. Есть внешние HMI-дисплеи, которыми можно управлять используя другие МК: просто посылая команды и реагируя на нажатия кнопок. Тут мы и видим, как китайский производитель решил применить этот чипсет для другой сферы: одноплатный компьютер для DIY!

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

На SSD210 есть порт Linux, предлагается использовать Embedded Linux в качестве основной системы. Никаких дистрибутивов по типу Ubuntu для устройства нет — предполагается, что вы сами реализуете весь необходимый для ваших программ функционал (отрисовку графики, обработку ввода, звук и т. п.). Есть Build root и исходный код ядра, а также U-Boot.

Помимо этого, вендор предлагает целое SDK для разработки уже готовых устройств на этом чипсете. Но есть один нюанс: документации практически нет :( Такие пакеты предлагаются крупным коммерческим производителям устройств, поэтому и основная поддержка есть только для них. Есть некоторые сэмплы, как, например, использовать графические дисплеи (показан пример с TTL-матрицей 1024x600), но совершенно не ясно как использовать SPI-матрицы, поскольку они требуют отдельной инициализации.

Но сначала наш одноплатник нужно собрать и запустить. И здесь есть множество тонких моментов, которые необходимо знать перед покупкой такого девайса. Переходим к сборке!

❯ Сборка и запуск


Для более удобного процесса разработки нашего устройства, лучше всего заказывать сразу две платы: одну припаять к переходной плате с штырями, а другую использовать на нашем устройстве. Как я уже говорил ранее, одноплатник предлагается в виде System on Module, которые можно при желании распаять на переходной плате:

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Честно сказать, я очень люблю такой тип монтажа и топлю за то, чтобы другие одноплатники не форсировали использование штырьков, а позволяли припаять себя «бутербродом» к другой плате. Обычно SoM дороже чем простые одноплатники, один из примеров — Olimex A20 SoM. Припаиваем основную плату к eval-плате. Обратите внимание, что припой должен находится «скосом» с внешней стороны пинов!

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост
DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

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

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Теперь подключаем питание. На плате уже разведены Step-down преобразователи с 5В на 3.3В (основная логика), 1.8В (DDR2), и 0.9В/1.0В (ядро), нам достаточно подключить лишь 5В, либо запитать плату от 3.7В аккумулятора. Устройство стабильно работает и от 0.5А порта ПК (если не юзать Wi-Fi).

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Для работы с одноплатником, обязательно нужен COM-преобразователь. Открываем Putty, задаем COM-порт, выставляем бодрейт 115200 и отключаем контроль четности. После подачи питания на устройство, в консоли побегут логи, U-Boot начнет загружать систему… однако, есть один важный нюанс…

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Все платы прошиваются на заводе с помощью фирменного флэшера SSD210. Но фирменный флэшер, по каким-то причинам, на некоторых платах не может сохранить U-Boot Environment (переменные окружения, которые в том числе определяют таблицу разделов и коммандлайн ядра).

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Поэтому если ваша плата повисла на CRC Error, нужно ввести следующие команды:

setenv mtdids nand0=nand0

setenv mtdparts ' mtdparts=nand0:0x140000(CIS),0x1a0000(BOOT0),0x1a0000(BOOT1),0x40000(ENV),0x40000(ENV1),0x20000(KEY_CUST),0x500000(KERNEL),0x500000(RECOVERY),0x600000(rootfs),0xa0000(MISC),-(UBI)

setenv bootargs ubi.mtd=UBI,0x800 root=/dev/mtdblock8 rootfstype=squashfs ro init=/linuxrc LX_MEM=0x3FE0000 mma_heap=mma_heap_name0,miu=0,sz=0x1E00000 cma=2M highres=off mmap_reserved=fb,miu=0,sz=0x300000,max_start_off=0x3C00000,max_end_off=0x3F00000 ${mtdparts}

setenv bootcmd ' nand read.e 0x22000000 KERNEL ${kernel_file_size}; dcache on ; bootlogo 0 0 0 0; bootm 0x22000000;nand read.e 0x22000000 RECOVERY ${recovery_file_size}; dcache on ; bootm 0x22000000

setenv autoestart 0

setenv sstar_bbm off

setenv ipl_version "##p3##gdf99011IPL_##########

setenv ipl_version "DUALENV=1 SILENT_CONSOLE=1 CFG_SDMMC_DISABLE=n ALK=1 SPINAND=1 CHIP=pioneer3""

saveenv

После этого отправляем плату в ресет и система загружается как ни в чем не бывало!

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Поскольку на плате не разведен разъем USB, для прошивки нужно распустить нерабочий кабель для зарядки смартфона, либо купить внешний USB-разъем на плате. VBUS кидаем на вход питания, белый провод на DM-, зелёный на DM+. Не забывайте провести общую землю между UART-преобразователем и основным питанием платы, дабы не потерять логи.

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост
DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост
DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Замыкаем два пина в центре платы пинцетом и жмем RESET. Плата определится как MSDC-флэшка (не удивляйтесь). Прошивальщик глючный и бывает не с первого раза может прошить устройство. Если девайс после прошивки не включается — введите команды в консоль U-Boot выше.

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Теперь переходим к самой системе.

❯ Система


Девайс работает на базе ядра Linux 4.9. Тем не менее, производителем заявлена поддержка Mainline-ядра, что даёт надежду на поддержку устройства в будущем.

Таблица разделов устройства организована в виде ubifs. Вообще, предполагается, что для тестов можно будет запускать ваш софт без перезагрузки, однако когда речь заходит о серьезных модификациях, ребут и прошивка устройства глючным софтом — дело неизбежное.

«Из коробки» на устройстве доступен лишь i2cdev, благодаря которому можно свободно общаться с i2c-устройствами из юзерспейса. Хотите получить доступ к SPI? Готовьтесь качать билдрут, вручную включать spidev в конфиге и редактировать DeviceTree, дабы spidev мог получить доступ к физическим spi-устройствам ядра.

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Кроме того, конечно же, есть доступ к GPIO из sysfs.

На самой плате, Wi-Fi реализован в виде внешнего USB-хаба + Wi-Fi адаптера. Чипсет также поддерживает Ethernet.

Для разработки устройств, производитель предлагает отдельное SDK для общения с периферией устройства из юзерспейса. С помощью этого SDK, можно получить доступ к камере, аппаратному декодеру, звуку и настроить матрицу. Судя по всему, общение происходит с помощью ioctl к необходимым устройствам. Это сделано для того, чтобы разработчики не копались в низкоуровневых драйверах, ведь например, ALSA, на устройстве нет совсем.

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Если включить нужные нам модули в юзерспейс (spidev, i2cdev, gpio), то можно будет проектировать устройства более простым путем. Например, подключить дисплейчик и прямо из юзерспейса выводить на него графическую информацию. Это открывает перспективы для самых разных применений: опрос датчиков и хранение информации в внутренней памяти, умные сигнализации, самодельные часы, DIY игровые консоли, самодельные телефоны и т. п. Применений просто куча!

❯ Заключение


Вот мы и посмотрели с вами на дешевые одноплатники, где используются чипсеты, которые разработаны для использования в совершенно других сферах. Девайсы весьма своеобразные и для полноценной работы с ними нужно обладать навыками прожженного линуксоида и иметь навыки системного программирования. Но, чего уж точно нельзя отрицать, так это перспектив подобных девайсов для своих проектов. Да, под них нет готовых гайдов, как для Raspberry Pi или Orange Pi, информации по ним минимум… но если захочется — то всегда можно «сварганить» самопальное устройство за минимальный прайс!

Вероятнее всего, я применю один из этих одноплатников для своего проекта немного позже. И конечно же, я напишу об этом отдельный материал — ведь про экзотические чипсеты на Пикабу пишут не так часто!

DongShan Pi Pico-W: крошечный одноплатник с современным чипсетом за 600 рублей Гаджеты, Покупка, Девайс, Одноплатный компьютер, Компьютер, Минипк, Raspberry pi, Orange pi, Дешево, Своими руками, Embedded, Электронные сигареты, Разработка, Linux, Nix, Длиннопост

Чуть позже выйдет материал про Repka Pi. Их одноплатник получился не менее интересным и как раз таки метит в нишу одноплатников с хорошей поддержкой, где есть уже готовые гайды, информация и даже сами разработчики могут помочь с решением некоторых проблем. Без косяков не обошлось: есть пару аппаратных проблем, о которых я расскажу открыто, но в целом девайс выглядит интересным!

Материал подготовлен при поддержке TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud , дабы не пропускать свежие статьи каждую неделю!

Показать полностью 21
[моё] Гаджеты Покупка Девайс Одноплатный компьютер Компьютер Минипк Raspberry pi Orange pi Дешево Своими руками Embedded Электронные сигареты Разработка Linux Nix Длиннопост
49
339
monobogdan
monobogdan
1 год назад
TECHNO BROTHER

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х?⁠⁠

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост



В наше время большинство портативных устройств работает на базе достаточно мощных микроконтроллеров, которые способны запускать даже интерпретируемый код на Lua/Python. Чего уж там говорить — даже современная кофеварка или умный электрочайник может быть в разы мощнее оригинального IBM-PC, не говоря уже о автомобильных бортовых компьютерах, которые зачастую мощнее топовых ПК из начала нулевых. Но давайте вспомним конец 90-х и начало 2000-х, когда разработка собственной электроники была практически недоступна рядовому пользователю, а микроконтроллеры программировались в основном только на ассемблере. Недавно я нашёл некоторую информацию о том, какой процессор вероятно использовался в таких знакомых нам приставках Brick Game, которые мы называли «Тетрисами»! Более того, мне удалось найти полный даташит с описанием всех модулей этого процессора, который гордо можно назвать «система на кристалле». Какой была разработка микроэлектроники в 90-х? Читайте в статье!

❯ Немного о «Тетрисе»


Пожалуй, Тетрис или Brick Game был одной из самых популярных портативных игровых консолей в странах СНГ. Появившись где-то в конце 90-х, этот гаджет быстро стал бестселлером среди детишек благодаря наличию сразу нескольких игр, полноценного ЖК-экрана, звука и невероятной дешевизны. Не знаю, сколько Тетрис стоил в момент выхода, но в нулевых цена на него была крайне низкой — около 100-200 рублей в зависимости от корпуса. Типичный школяр мог накопить на собственный Тетрис за несколько недель, что делало его самым доступным игровым девайсом на рынке.

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост



Конечно же, на рынке уже были различные консоли с гораздо более богатым функционалом — например GameBoy и даже GameBoy Color с цветным дисплеем, а люди, родившиеся в конце 90-х или начале 2000-х уже застали PlayStation Portable с реально крутой 3D-графикой и телефоны с хорошим игровым потенциалом — как, например, SE K500i. Однако цена на них была непозволительной роскошью для небогатых семей: PSP стоила 250$ (около 7-8 тысяч рублей по тому курсу), плюс каждый UMD-диск с игрой стоил около 1.000 рублей, GameBoy были относительно редкими в России, а телефоны — это всё же прерогатива более юных ребят, да и в нулевых далеко не всем перепадал крутой K500i — чаще всего покупали телефон попроще типа Siemens A55 (грузчика помним?) или Motorola C350 (а мотоциклиста?). Поэтому тетрисы оставались чуть ли не единственным средством развлечения у небогатых ребят.

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост



Ощутимым плюсом было и то, что Тетрис работал от батареек: они были не слишком дорогими в то время, а если носить с собой в кармане парочку, то можно не бояться, что консоль сядет в долгой дороге и продолжать себя забавлять, да и сам Тетрис работал довольно долго, мне хватало на неделю игры (может и меньше). Несмотря на низкое разрешением всего в 10x20 пикселей, Тетрис обладал достаточно большим монохромным дисплеем без подсветки, на котором было комфортно играть.
Ещё одним немаловажным плюсом консоли была возможность «кооперативной» игры и эдакого азарта: будучи неискушенными детьми, многие из нас пытались поставить рекорды и выбить как можно больший счёт в каждой из доступных игр. Чем больше счёт, тем ты круче среди друзей!

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост



Но что же у Тетриса «под капотом»? На чём он работал внутри? Недавно я нашёл информацию о том, что потенциально в Тетрисе могла использоваться 4х-битная система на чипеHoltek HT1130, которая использовалась в самой разной носимой электроники: от часов на батарейках, до полноценных игровых консолей. Причём я ничуть не преувеличиваю, это действительно SoC: уже в 90-х, тайваньская компания смогла объединить звуковой модуль, контроллер ЖК-дисплея, ввод/вывод и таймер в один чип! Однако тут важно понять, что 100% сказать, на чём работал Тетрис, нельзя — процессор спрятан под компаундом и у него нет корпуса с маркировкой, лишь «голый» кристалл. Тем не менее, мы можем предположить, что это был один из чипов Holtek и посмотреть, на чём же работала портативная электроника тех лет поближе!

Заранее прошу прощения за отсутствие нормальных фотографий. Под рукой у меня не оказалось «старого» Тетриса, а на новодельных показывать как-то не очень.

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост



На данный чипсет есть «утёкший» в сеть даташит с полным описанием регистров микроконтроллера и его ТТХ. Чип был спроектирован так, чтобы не требовать практически никакой обвязки в виде конденсаторов/резисторов и других SMD-элементов — он работал фактически напрямую от пальчиковых батареек и его легко было развести на плате даже начинающему инженеру. Микроконтроллер стабильно оперировал при напряжении от 2.4в до 3.3в, что позволяло просто вставить две последовательно соединенные AA или AAA батарейки с напряжением 1.5-1.6в и получить необходимое питание для работы всей «приставки».

❯ Вычислительное ядро


Саму систему на кристалле можно разделить на несколько соединенных модулей в один чип. Основным, конечно же, является 4х-битное вычислительное ядро неизвестной архитектуры, которое компания Holtek разработала сама или лицензировала как IP-ядро у другой компании для использования в собственном чипе (как, например, MediaTek лицензирует у ARM ядра Cortex). Система команд, по крайней мере, описание мнемоник ассемблера в даташите наводят на мысли о некоторой схожести с микроконтроллером Intel 8051 (однако 8051 был 8-битным) и в целом, напоминают типичную интеловскую архитектуру из 80х. Однако только по мнемоникам точно определить архитектуру невозможно: здесь есть «проприетарные» команды типа SOUND и TIMER.

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост
Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост
Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост


Чип работает на частоте 1мгц от встроенного тактового генератора, большинство команд выполняется за один такт, максимум — два. Если говорить совсем грубо, то даже ATMega328 в Arduino условно в 16-раз мощнее HT1130, хотя это совсем некорректное сравнение.

Длина машинного слова HT1130 — 4 бита, что отсылает нас в начало 70х годов, если мы говорим о компьютерах. Это означает, что процессор «аппаратно» мог выполнять операции только с числами от 0 до 16, хотя при программной реализации мог пересчитывать хоть 32х-битные числа. Ширина шины данных — 12 бит, что позволяло адресовать вплоть до 4Кб встроенной ROM-памяти. Кроме того, в МК было встроено 128 ячеек оперативной памяти (или 64 байта), где в00H..7FHхранились временные данные программы (например, позиция танчиков на экране) и сE0H..FFHхранился «буфер» кадра, который определял текущую на экране. Также у микроконтроллера были следующие регистры:

  1. R0-R4 — регистры общего назначения. Пары из регистров используются для адресации памяти.

  2. ACC — регистр-аккумулятор, который хранит результаты текущей операции.

  3. PC — указатель на текущую инструкцию в ROM, которую выполняет процессор.

  4. Стековый регистр — судя по всему, «невидимая» связка регистров, которую процессор использует для хранения PC при вызове функций. Ограничен максимум двумя адресами, что не даёт возможность писать программы с вложенностью более двух функций.


С стековым регистром всё интересно получается. В отличии от привычных нам архитектур, HT1130 не хранит в этом регистре указатель на память, он сам по себе как-бы является стеком. Пример допустимого и недопустимого кода:

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост

Выбор 4х-битного процессора очевиден — они очень недорогие в производстве и достаточно простые. Примеры использования 4х-битных архитектур можно найти даже в советских играх: например, в игре «Волк и яйца» (клоне Nintendo Game & Watch) использовалась «микроЭВМ» КБ1013ВК1-2.
В встраиваемой и переносной электронике, 4х-битные вычислительные ядра продолжают использоваться и сейчас: в калькуляторах, в пультах для управления техникой, в часах. Связано это с простой и дешевизной подобных решений, да и если честно, реализация этих устройств была готова ещё в прошлом веке. Зачем дополнительно тратить деньги на R&D существующих решений? :)

❯ Графика


HT1130 специально разрабатывался для переносимых устройств с новомодными LCD-дисплеями. В те годы было нормой, когда на дисплейной матрице не было собственного контроллера с распространенным интерфейсом по типу 8080 или MIPI: частенько, драйвер дисплея либо выделялся в отдельный чип, либо реализовывался прямо в системе на кристалле. У Brick Game был дисплей разрешением в 10x20 пикселей, причём кастомизированный — с «захардкоженными» значками и сегментными индикаторами:

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост



Работа с дисплеем была не особо сложной: один сегмент памяти был отведен специально под эдакий «фреймбуфер» — всё, что мы записывали туда, контроллер дисплея моментально отображал на нашу ЖК-матрицу. Поскольку дисплей был одноцветным, без градаций цвета, память была организована 1 бит — 1 пиксель. Работать со всем этим было как-то так:

MOV A, 0 ; Первая часть адреса (если я не напутал endianness)

MOV R1, A

MOV A, 0b0111 ; Вторая часть адреса. Не удивляйтесь, что по факту получается 224 при 128 байт ОЗУ - часть адресного пространства была как-бы зарезервирована

MOV R0, A

MOV A, 1 ; Закрасим первый пиксель в строке

MOV [R1R0], A ; И запишем это значение в ОЗУ

Частичным доказательством того, что этот чип мог использоваться в Brick Game — это то, что компания Holtek производила готовые «игры на кристалле» — вероятно, уже запрограммированные с завода HT1130 с определенными играми:

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост



Примечательно, что даташит на готовые игры датируются ноябрём 1998 года, в то время как даташит на HT1130 — 1999. Если у вас появился Тетрис раньше этого времени — напишите пожалуйста в комментариях!

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост

❯ Звук


Помимо этого, чипсет имел собственный генератор звука, или как вы вероятно подумаете — «пищалку». В чип (или SDK, если честно, не особо понятно из даташита) была уже встроена звуковая библиотека — причём половину из них как раз таки для игр, что ещё раз косвенно подтверждает догадки об использовании этого чипа в «Тетрисе». Всего поддерживалось до 16 «каналов», в которых было по 3 тональности. В звуковой библиотеке содержались следующие звуки:

  • Шумы

  • Мелодии

  • Выстрелы

  • Будильники



Управлять звуковым трактом было очень просто — буквально несколькими командами на ассемблере. Команда SOUND <номер канала> выбирала один из предопределенных звуков (причем не совсем ясно, где они хранились — возможно в ROM), а команда SOUND ONE/LOOP воспроизводила его в одном из режимов — один раз или повторяющийся. SOUND OFF же выключала звук совсем. Как-то так:

play:

SOUND A

SOUND ONE

SOUND OFF

CLC ; А если нет, то снова выполняем, пока не переполнится, эта операция очищает флаг переноса

loop:

INC A ; Увеличиваем значение в аккумуляторе

JC play ; Если флаг переноса установлен, то наш "таймер" как-бы переполнился и пора снова проиграть звук

JMP loop;

Совсем немудрено, согласитесь? :)

❯ Порты ввода/вывода и кнопки


Кроме этого, HT1130 имел несколько портов ввода-вывода, которые, однако, назвать GPIO нельзя — было 12 портов для вывода, которые могли читать логический уровень (для кнопок), и 4 пина, который мог задавать логический уровень (например, управлять вибромотором или светодиодом). Настройки портов задавались с помощью флагов: можно было настроить встроенные pull-up резисторы и они могли вызывать прерывания при переходе из высокого уровня в низкий.

Процессор, который использовался в «Тетрисе»: на каких SoC работала недорогая микроэлектроника в 90-х? Гаджеты, Разработка, Тетрис, 90-е, Электроника, Китай, Девайс, Программирование, Микроконтроллеры, Ретро, Микроэлектроника, Embedded, Длиннопост



Выходной порт мог быть сконфигурирован под тип выхода — CMOS или NMOS. Работа с портами шла с помощью команд IN и OUT — как в x86, а обрабатывать их можно было как-то так:

loop: IN A,0b00110010 ; Загрузить в аккумулятор значение порта PM

AND A,0b0001 ; Отсекаем биты состояний других кнопок и проверяем, нажата ли первая кнопка?

JNZ A, btn_pressed ; Если в аккумуляторе не 0 (а значит кнопка нажата) - то переходим на другую метку

JMP loop ; Если нет - то проверяем по новой

btn_pressed:

SOUND 0

SOUND ONE ; Воспроизвести звук при нажатии


❯ Таймер


В чипсете есть встроенный таймер — ну его ж не просто так для часов использовали. :) Основная суть работы аппаратных таймеров заключается в том, что его тактирует какой-либо внешний тактовый генератор с определенным делителем, в нашем случае — от 1 до 6 относительно системного генератора частоты (т.е 1мгц) и с определенной частотой он делает инкремент внутреннего регистра. Как только регистр переполняется — он очищается и вызывается соответствующее прерывание в основном процессоре.

Это позволяет регулировать скорость работы таймера, а посчитать количество тиков в таком случае не особо сложно. Однако учтите, что чем выше делитель таймера (а значит и обратно-пропорционально снижается точность таймера) — тем реже вызываются прерывания и меньше «кушают» наше процессорное время!

❯ Можно ли написать свою программу для Тетриса?


К сожалению, написать какую-нибудь свою игру для этой консоли в домашних условиях невозможно — таких удобных инструментов для прошивки, как у AVR ещё не было. Holtek предлагала собственный SDK, в которое входила IDE, ассемблер и симулятор отладки финальной программы. Однако дабы получить настоящее «хардварное» устройство, необходимо было заказывать у компании Holtek производство кастомизированного чипа с вашей программой на борту.

Чипсет использовал настоящую масочную Read-Only Memory, которая прожигалась один раз и навсегда на заводе. Производитель электроники отсылал скомпилированную программу Holtek, а они в свою очередь производили кастомный чип с прошитой программой. Несмотря на всю простоту ассемблера и устройства в целом, самому под него ничего написать не получится — внешних шин то у него нет. :(

Однако, в наше время можно разработать и собрать «Тетрис» самому: в том числе, с цветным дисплеем и на базе гораздо более мощного железа! Тут тебе и готовые мощные микроконтроллеры, и возможность собрать приставку на базе легендарного процессора Z80, да при желании можно симулировать почти настоящий HT1130 на FPGA!

❯ Заключение


Разработка вычислительной и при этом недорогой электроники в 90-х было весьма веселым занятием. Несмотря на то, что устройства были на первый взгляд достаточно примитивными, в них всё равно крылось много разных нюансов, которые ограничивали программистов во многом.

Однако embedded-разработка тех лет была весьма интересной: когда полноценные игры вмещали в ПЗУ размером пару килобайт, на ремейки Space Invaders на современных движках весом в под сотню мегабайт смотришь с некоторой улыбкой. :)

Спасибо за наводку ресурсу retroscene:
Пост Legnahar, который один из первых опубликовал предположения насчет HT1130 и комментарию =A=L=X= под тем же постом.

Показать полностью 13
[моё] Гаджеты Разработка Тетрис 90-е Электроника Китай Девайс Программирование Микроконтроллеры Ретро Микроэлектроника Embedded Длиннопост
65

Попробовать мобильный офис

Перейти
Партнёрский материал Реклама
specials
specials

Мобильный офис до 100 тысяч рублей⁠⁠

Ноутбуки используют не только для работы: на них смотрят сериалы, редактируют фото, запускают игры и монтируют ролики. Поэтому теперь требования к устройству такие: быть легким для дороги, надежным для горящих дедлайнов и стильным, чтобы не прятать в переговорке. А еще — легко работать в связке с другими гаджетами.

Протестировали TECNO MEGABOOK K15S вместе со смартфоном TECNO CAMON 40 и наушниками TECNO в рабочих и бытовых сценариях от Zoom-звонков до перелета, а теперь рассказываем, как себя показала техника.

Первое впечатление от дизайна ноутбука

Первое, что заметно — это вес. При диагонали 15,6 дюйма и полностью металлическом корпусе K15S весит всего 1,7 кг. Это примерно на 15% меньше, чем аналоги. Устройство не обременяет ни в офисе, ни в такси. Ноутбук поместился в стандартный городской рюкзак, было удобно достать его в кафе за завтраком и по дороге в такси, чтобы быстро отработать клиентские правки.

1/4

Дизайн сдержанный, без ярких акцентов, с матовой поверхностью. Правда, на ней остаются следы от рук. Так что если приходится постоянно открывать ноутбук в присутствии клиентов или партнеров, лучше купить прозрачный кейс. Визуально и тактильно устройство ощущается надежно: не выскальзывает и не двигается по столу, благодаря специальным резиновым накладкам на задней части.

Шарнир работает мягко: чтобы открыть крышку даже одной рукой, не нужно придерживать корпус. Чтобы показать коллеге или клиенту презентацию, достаточно раскрыть экран на 180°. Это удобно и для работы лежа, и для подставок, которые требуют определенного угла обзора.

Также отметим 9 портов: USB-A, USB-C, HDMI, слот для карты памяти — можно забыть о переходниках.

В TECNO MEGABOOK K15S предустановлен Windows 11. Ноутбук готов к работе сразу после включения. Никаких лишних установок и обновлений. Все настроено и оптимизировано для вашей многозадачности.

Экран: яркая картинка и комфорт ночью

Экран — 15,6 дюйма, IPS-матрица с разрешением Full HD. Углы обзора отличные: изображение остается четким, даже если смотреть сбоку, цвета не искажаются. Есть антибликовое покрытие. Тестировали ноутбук при разном освещении: можно спокойно работать у окна. Когда солнце бьет прямо в экран, текст по-прежнему остается читаемым, картинки не искажаются. Это редкость в бюджетных моделях.

1/2

Неважно, работаете вы ночью или играете, выручит клавиатура с регулируемой четырехуровневой подсветкой. При среднем уровне в темноте все видно, глаза не устают. Из плюсов для тревожных людей: включали ноутбук в самолете и электричке, никто вокруг не жаловался на яркость. Все регулируется кнопками, не нужно лишний раз заходить в настройки.

Стеклокерамический крупный тачпад — 15 см. Он не залипает, не промахивается, срабатывает с первого касания. Не возникает дискомфорта, даже если несколько часов редактировать документы без мышки. После перехода с других устройств немного непривычно, что тачпад работает в двух направлениях: нижняя часть отзывается нажатием, верхняя — касанием.

В кнопку питания встроен сканер отпечатка пальцев. К нему можно быстро привыкнуть, особенно если сидишь в опенспейсе или работаешь в дороге. Один легкий тап пускает в систему даже с мокрыми руками. Безопасно, удобно и не нужно постоянно вводить пароли.

Производительность: рендерим видео, открываем вкладки

Ноутбук работает на AMD Ryzen 7 5825U (опционально можно выбрать версию техники Intel Core i5-13420H). Восьмиядерный AMD с поддержкой 16 потоков подходит для ресурсоемких операций вроде рендеринга или работы с большими массивами данных. Встроенная графика Radeon справляется с редактированием видео в Full HD или играми.

1/4

Во время монтажа 30-минутного ролика в DaVinci Resolve и параллельной работе в Photoshop с несколькими большими PSD-файлами система сохраняла стабильность. Не было ни зависаний, ни заметного падения производительности. Ноутбук уверенно держит в фоне 10 приложений одновременно. Если запущены браузер с 20 вкладками, видеозвонок в Telegram, Excel с объемной таблицей и софт для монтажа, система не тормозит и не перегревается. Переход между окнами остается плавным, ничего не «проседает», даже при одновременном скачивании файлов и редактировании видео.

Базовая комплектация включает 16 ГБ оперативной памяти в двух слотах. При необходимости можно легко увеличить этот показатель до 32 ГБ, заменив стандартные модули на более емкие. Помимо установленного SSD на 1 ТБ предусмотрен дополнительный слот, поддерживающий диски объемом до 2 ТБ.

Чтобы во время нагрузки системы охлаждения не выходили из строя, в ноутбук встроен эффективный вентилятор, способный рассеивать до 35 Вт тепла. Устройство не греется, его спокойно можно держать на коленях. Это решение дополнено тремя режимами работы, которые переключаются простой комбинацией клавиш Ctrl+Alt+T. Тихий режим идеален для работы ночью или в общественных местах, сбалансированный подходит для повседневных задач. Производительный, на котором запускали рендеринг видео и игры, практически не шумит.

Автономность: 15 часов без подзарядки

Протестили автономность MEGABOOK K15S в условиях, знакомых каждому деловому путешественнику. Утром перед вылетом зарядили ноутбук до 100% и взяли его в рейс Москва — Калининград. В зале ожидания провели созвон, потом три часа смотрели сериал и в дороге до отеля редактировали документы. К моменту приезда оставалось 40% заряда: хватило бы еще на пару часов продуктивной работы.

1/3

MEGABOOK K15S может автономно работать до 15 часов и позволяет не оглядываться на индикатор заряда. Заявленное время достигается при типичном офисном использовании: одновременная работа с документами в Word и Excel, ведение переписки, видеоконференции, веб-серфинг.

Если все же понадобится, за  час восполняется до 70% батареи. Компактный адаптер мощностью 65 Вт на базе нитрида галлия поместился даже в карман пиджака. Один блок питания заряжает и ноутбук, и смартфон, и наушники. Экономия места: не нужно никаких дополнительных проводов.

Звук, который реально слышно

В TECNO MEGABOOK K15S установлены два мощных динамика по 2.5 Вт. Звук с глубокими низами, без пластикового дребезжания, объемный. Благодаря DTS можно смотреть видео даже в шумном помещении. В тестах специально включали сцены с шагами и выстрелами: локализация настолько точная, что в наушниках нет необходимости.

Та же стабильность и в микрофоне. Благодаря AI-шумоподавлению голос передается чисто. Во время тестовых звонков из оживленного кафе собеседник не услышал ни разговоры за соседним столом, ни городской шум. И все это — на расстоянии до пяти метров.

Кстати, о созвонах. В ноутбуке встроена обновленная камера. Она отслеживает положение лица, а еще есть физическая шторка приватности. Например, можно закрыть шторку для комфортных видеоконференций.

Для тех, кто предпочитает гарнитуру, идеально подойдут беспроводные наушники TECNO FreeHear 1 из экосистемы бренда. Когда не хотелось делиться разговорами с окружающими, подключали их. Чистый звук с акцентом на средние частоты, 11-мм драйверы, которые выдают неожиданную детализацию. Музыку слушать приятно: и фоновый плейлист на телефоне, и вечерний сериал на ноутбуке. Автономно работают наушники 6 часов, с кейсом — до 30 часов. 

1/2

Bluetooth 5.4 обеспечивает стабильное соединение на расстоянии до 10 метров. Удобная C-образная форма разработана специально для длительного ношения — после восьмичасового рабочего дня в ушах не возникает дискомфорта. Наушники поддерживают одновременное подключение к ноутбуку и смартфону. Переключение между устройствами происходит быстро и без заминок.

Через фирменное приложение Welife можно выбрать один из четырех эквалайзеров и отследить местоположение гарнитуры в случае утери. А еще кастомизировать виджет для управления наушниками. Функция настройки персонализированного дизайна доступна для устройств на Android и позволяет гибко изменить внешний вид окна подключения: вплоть до установки фоновой картинки или собственного фото.

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

Бесшовная синхронизация со смартфоном

Благодаря функции OneLeap ноутбук синхронизируется со смартфоном TECNO. Подключение происходит за пару секунд: достаточно один раз подтвердить сопряжение. После этого открывается доступ к бесшовному переключению между устройствами — объединенному буферу обмена, дублированию экранов и передаче файлов без кабелей и пересылок в мессенджерах.

Функция выручила, когда нужно было открыть приложение, у которого нет веб-версии. Удобно работает и буфер обмена: скопировал текст на одном устройстве — вставил на другом. Например, код, полученный в сообщении на телефоне, вводится в браузере на ноутбуке. Экономит минуты, а иногда и нервы. А когда в дороге пропал Wi-Fi, ноутбук сам подключился к мобильному интернету через смартфон.

1/2

TECNO CAMON 40 и сам по себе — мощный рабочий инструмент.  Смартфон выделяется камерой высокого качества 50 Мп, ярким AMOLED-экраном 120 Гц и множеством функций, которые упрощают процесс мобильной съёмки и использование искусственного интеллекта TECNO AI.

Телефон работает на HIOS 15.0.1 на базе Android 15.В фирменную оболочку встроен искусственный интеллект:

  • Голосовой помощник Ella. Отвечает на вопросы, помогает с задачами и управлением устройством.

  • Решение задач. Наводите камеру на задачу, ИИ решает ее.

  • AI Редактор фотографий. Интеллектуальная обработка в одно касание.

  • Быстрый поиск. Находит адрес на экране и запускает навигацию, распознает объекты и события, автоматически добавляет их в календарь.

Технические характеристики

  • Процессор и память. 8 ядер, 16 потоков, Кэш L3 16 МБ, частота до 4.5 ГГц Графический процессор AMD Radeon™ graphics SSD 512 ГБ или 1 ТБ, М.2, 2280, PCle 3.0 Nvme DDR4 16 ГБ, 3200 МГц.

  • Дисплей. 15.6", TFT, Full HD (1920×1080), 16:9, 280нит, 45% NTSC, 16.7 млн цветов, 60 Гц, 141 ррі.

  • Веб-камера. 1 Мп, шторка приватности.

  • Порты. 9 портов: 1*TF Card (microSD), 1*HDMI 1.4, 1*USB-A 3.1,

    1*USB-A 3.2, 1*3.5mm аудиовход, *Ethernet RJ45 до 1 Гбит, 2*Туре-С (Full Function), 1*слот для замка Kensington.

  • Другое. Сканер отпечатка пальца в кнопке питания. Клавиатура с подсветкой (4 уровня яркости). Тачпад с поддержкой одновременно 4 касаний.

  • Батарея. 70 Вт∙ч (6150 мА∙ч), Li-Pol, 11.55 B 65 Вт Type-C GaN, 20 В, 3.25 А, кабель 1.8 м (Туре-С-Type-C).

  • Габариты. 17.3 мм (высота), 359.5 мм (ширина), 236 мм (глубина).

  • Вес. 1,7 кг.


Если хотите создать собственную экосистему, в которой технологии подстроятся под ритм дня, попробуйте технику TECNO. Мощный ноутбук, быстрый смартфон и наушники соединяются в единое пространство. Быстрое переключение между устройствами, синхронизация файлов и стабильное соединение без лишних настроек.

КУПИТЬ НОУТБУК TECNO

Реклама TECNO Mobile Limited, Юридический адрес: Flat N, 16/F., Block B, Универсальный промышленный центр, 19-25 Shan MeiStreet, Fotan, New Territories, Гонконг

Показать полностью 17
Электроника Гаджеты Ноутбук Длиннопост
938
monobogdan
monobogdan
1 год назад
TECHNO BROTHER

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android⁠⁠

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост



Для многих разработчиков приложений далеко не секрет, что экосистема Android не предполагает написание полностью нативных приложений: в этой платформе очень многое завязано на Java и без ART можно запустить только простые службы без какого-либо интерфейса. Однако, есть один способ писать практически под «голый» Linux, не перекомпилируя ядро и при этом пользоваться самыми интересными фишками устройства без оверхеда в виде тяжелого Android: ускорение 3D-графики (OpenGLES), микшер звука, ввод с различных устройств, OTG, Wi-Fi и если очень постараться — даже 3G. Это открывает множество разных интересных применений старым устройствам: «железо» смартфонов зачастую гораздо мощнее современных недорогих одноплатников. Сегодня я покажу вам, как написать и запустить программу, которая полностью написанное на C без Android, на No-Name Android-смартфоне практически без модификаций. Интересно? Жду вас в статье!

❯ Что нам нужно знать?


Даже относительно старые устройства флагманского сегмента обладают весьма неплохими характеристиками. Зачастую они гораздо мощнее современных дешевых одноплатников и могут выполнять самые разные задачи: эмуляция консолей, работа в качестве плееров, да даже просто сделать настольные часики самому было бы здорово. Но есть одно но — это Android. Платформа от Google может тормозить даже на достаточно мощном железе, что резко ограничивает потенциально возможные применения подобных гаджетов. Да и многие программисты не особо хотят заморачиваться и учить API Android для реализации каких-то своих проектов.

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


Но конечно же, есть один способ писать нативные программы, при этом используя все ресурсы смартфона/планшета. Для этого нужно понимание, как работает процесс загрузки на многих Android-гаджетах:

  1. Первичный загрузчик (BootROM) инициализирует какую-то часть периферии и загружает вторичный загрузчик (U-boot/LK).

  2. Вторичный загрузчик, используя определенные аргументы (например зажата ли какая-то кнопка) выбирает, с какого раздела грузить ядро системы.

  3. После загрузки ядра Linux и подключения ramdisk начинается выполнение процессов системы.


Как раз в третьем пункте и лежит ключ к способу, который будем использовать мы. Дело в том, что в смартфоне обычно есть несколько boot-разделов и у каждого свой образ ядра Linux со своим ramdisk. Первый из них — это знакомый моддерамboot.img, который отвечает за загрузку системы и инициализирует железо/монтирует разделы/подготавливает окружение к работе (.rc файлы) и запускает главный процесс Android —zygote. При этом используется собственная реализация init от Android.

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


Второй, не менее знакомый многим раздел —recovery, отвечает за так называемый режим восстановления, в котором мы можем сбросить данные до заводских настроек/очистить кэши или прошить кастомную прошивку. Вероятно, многие из вас замечали, насколько быстро ваш девайс загружает этот режим, гораздо быстрее, чем загрузка обычного Android. И именно в его реализацию нам нужнозаглянуть(я намеренно выбрал бранч версии 2.3 — т.е Gingerbread для простоты):

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


А recovery оказывается самой обычной нативной программой, написанной на C со своим небольшим фреймворком для работы с графикой и вводом. В процессе загрузки режима recovery, скрипт запускает одноименную программу в /sbin/, благодаря которому мы видим простую и понятную менюшку. Так почему бы не использовать этот раздел в своих целях и не написать какую-нибудь нативную программу самому?

Как я уже говорил выше, в этом режиме доступны многие аппаратные возможности вашего смартфона, за исключением модема. Используя полученную информацию, предлагаю написать наше небольшое приложение под Android-смартфон без Android сами!

❯ Подготавливаем окружение


В первую очередь, хотелось бы отметить, что программы под «голый» смартфон можно писать не только на C/C++. Нам доступен как минимум FPC, который довольно давно умеет компилировать голые бинарники под Android. Кроме того, мы можем портировать маленькие embedded-версии интерпретаторов таких языков, как lua, micropython и duktape (JS).

Однако в случае нативных программ, есть два важных правила, которые необходимо понимать. Во-первых, в Android используется собственную реализацию стандартной библиотеки libc — bionic, в то время как на десктопных дистрибутивах используется glibc. Между собой они не совместимы — именно поэтому вы не можете просто взять и запустить консольную программу для Raspberry Pi, например.

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


А второе правило заключается в том, что начиная с версии 4.1, Androidтребует, чтобы все нативные программы были скомпилированы в режиме -fPIE — т. е. выходной код должен не зависеть от адреса загрузки программы в виртуальную память. Для этого достаточно добавить ключ -fPIE, однако учтите, что если вы разрабатываете программу под Android 4.0 и ниже, то fPIE наоборот необходимо убрать — старые версии Androidнеподдерживают такой способ генерации кода и будут вылетать с Segmentation fault.

Для разработки нам понадобится ndk — там есть все необходимые заголовочники и компиляторы для нашей работы. Я используюndk r9c, поскольку в свежих версиях Google регулярно может что-то сломать.
ndk-build, к сожалению, здесь работать не будет, поэтому Makefile придется написать самому. Я составил полностью рабочий Makefile, который без проблем скомпилирует валидную программу, вам остаётся лишь поменять NDK_DIR.

NDK_DIR = D:/android-ndk-r11c/

TOOLCHAIN_DIR = $(NDK_DIR)toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/

GCC = $(TOOLCHAIN_DIR)arm-linux-androideabi-g++

PLAT_DIR = $(NDK_DIR)platforms/android-17/arch-arm/usr/

LINK_LIBS = -l:libEGL.so -l:libGLESv1_CM.so

OUTPUT_NAME = cmdprog

build:

$(GCC) -I $(PLAT_DIR)include/ -L $(PLAT_DIR)lib/ -fPIE -Wl,-dynamic-linker=/sbin/linker $(LINK_LIBS) -static -o $(OUTPUT_NAME) main.cpp micro2d.cpp


После этого пишем простенькую программу, которая должна вывести «Test» и компилируем её.

❯ Деплоим на устройство


Несмотря на то, что грузиться мы будем в режим recovery, нам всё равно будет доступен adb, через который мы сможем запускать и отлаживать нашу программу. Это очень удобно, однако по умолчанию adb включен только в TWRP, который нужно сначала найти или портировать под ваш девайс (на большинство старых брендовых устройств порты есть, на нонейм придется портировать самому — гайды есть в интернете). Под ваше устройство есть TWRP? Отлично, распаковываете recovery.img с помощью так называемой «кухни» (MTKImgTools как вариант):

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


Открываете init.recovery.service.rc и убираете оттуда запуск одноименной службы (можно просто оставить файл пустым).

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


Запаковываем образ обратно тем же MTKImgTools и прошиваем флэшером для вашего устройства — в моём случае, это SP Flash Tool (MediaTek):

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


Заходим в режим рекавери и видим зависшую заставку устройства и звук подключения устройства к ПК. Если у вас установлены драйвера, то вы сможете без проблем зайти в adb shell и попасть в терминал для управления устройством. Теперь можно закинуть программу — прямо в корень рамдиска (записывается программа в ОЗУ, но при переполнении, телефон уйдет в ребут — осторожнее с этим). Пишем:

adb push cmdprog /: adb shell chmod 777 cmdprog ./cmdprog


И видим результат. Наша программа запускается и работает!

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


Это просто отлично. Однако я ведь обещал вам, что мы напишем программу, которая сможет выводить графику и обрабатывать ввод, предлагаю перейти к практической реализации!

❯ Выводим графику


Для вывода графики без оконных систем, мы будем использовать API фреймбуфера Linux, которое позволяет нам получить прямой доступ к массиву пикселей на экране. Однако учтите, что этот способ полностью программный и может оказаться тормозным для вашего приложения: скорость работы прямо-пропорциональна разрешению дисплея вашего устройства. Чем выше разрешение, тем ниже филлрейт. В моём случае, матрица была с разрешением 960x540, 32млн цветов, IPS — очень недурно, согласны?

Фреймбуфер Linux может работать с самыми разными форматами пикселя, имейте это ввиду. На некоторых устройствах может быть 16-битный формат (262 тысячи цветов, RGB565), на моём же оказался 32х-битный с выравниванием по строкам (имейте это также ввиду). 32х битный формат. Работать с ним легко: открываем устройство /dev/graphics/fb0, получаем параметры (разрешение, формат пикселя), делаем mmap для отображения буфера с пикселями на экране в память нашего процесса и выделяем второй буфер для двойной буферизации дабы избежать неприятных мерцаний.

void m2dAllocFrameBuffer()

{

fbDev = open(PRIMARY_FB, O_RDWR);

fb_var_screeninfo vInfo; fb_fix_screeninfo fInfo;

ioctl(fbDev, FBIOGET_VSCREENINFO, &vInfo);

ioctl(fbDev, FBIOGET_FSCREENINFO, &fInfo); fbDesc.width = vInfo.xres;

fbDesc.height = vInfo.yres;

fbDesc.pixels = (unsigned char*)mmap(0, fInfo.smem_len, PROT_WRITE, MAP_SHARED, fbDev, 0); f

bDesc.length = fInfo.smem_len; fbDesc.lineLength = fInfo.line_length;

backBuffer = (unsigned char*)malloc(fInfo.smem_len); memset(backBuffer, 128, fInfo.smem_len);

printf("Framebuffer is %s %ix%ix%i\n", (char*)&fInfo.id, fbDesc.width, fbDesc.height, vInfo.bits_per_pixel, fInfo.type);

}


Если не сделать предыдущий шаг и запускать нашу программу параллельно с recovery, то они обе будут пытаться друг друга «перекрыть» — эдакий race condition:

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


После этого пишем простенькие функции для блиттинга картинок (в том числе с альфа-блендингом). В инлайнах и критичных к скорости функциям лучше не делать условия на проверку границ нашего буфера — лучше «отрезать» ненужное еще на этапе просчета ширины/высоты:

__inline void pixelAt(int x, int y, byte r, byte g, byte b, float alpha)

{

if(x < 0 || y < 0 || x >= fbDesc.width || y >= fbDesc.height) return;

unsigned char* absPtr = &backBuffer[(y * fbDesc.lineLength) + (x * 4)];

if(alpha >= 0.99f)

{

absPtr[0] = b;

absPtr[1] = g;

absPtr[2] = r;

}

else {

absPtr[0] = (byte)(b * alpha + absPtr[0] * (1.0f - alpha));

absPtr[1] = (byte)(g * alpha + absPtr[1] * (1.0f - alpha));

absPtr[2] = (byte)(r * alpha + absPtr[2] * (1.0f - alpha));

} absPtr[3] = 255; }

for(int i = 0; i < image->height; i++)

{

for(int j = 0; j < image->width; j++)

{

byte* ptr = &image->pixels[((image->height - i) * image->width + j) * 3]; pixelAt(x + j, y + i, ptr[0], ptr[1], ptr[2], alpha);

}

}


И загрузчик TGA:

CImage* m2dLoadImage(char* fileName) {

FILE* f = fopen(fileName, "r");

printf("m2dLoadImage: Loading %s\n", fileName);

if(!f)

{

printf("m2dLoadImage: Failed to load %s\n", fileName);

return 0;

}

CTgaHeader hdr;

fread(&hdr, sizeof(hdr), 1, f);

if(hdr.paletteType)

{

printf("m2dLoadImage: Palette images are unsupported\n");

return 0;

}

if(hdr.bpp != 24) {

printf("m2dLoadImage: Unsupported BPP\n");

return 0;

}

byte* buf = (byte*)malloc(hdr.width * hdr.height * (hdr.bpp / 8));

assert(buf);

fread(buf, hdr.width * hdr.height * (hdr.bpp / 8), 1, f);

fclose(f);

CImage* ret = (CImage*)malloc(sizeof(CImage));

ret->width = hdr.width;

ret->height = hdr.height;

ret->pixels = buf;

printf("m2dLoadImage: Loaded %s %ix%i\n", fileName, ret->width, ret->height);

return ret;

}


И попробуем вывести картинку:

m2dInit();

test = m2dLoadImage("test.tga");

test2 = m2dLoadImage("habr.tga");

while(1)

{

m2dClear();

m2dDrawImage(test, 0, 0, 1.0f);

m2dDrawImage(test2, tsX - (test2->width / 2), tsY - (test2->height / 2), 0.5f);

m2dFlush();

}

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост



Не забываем про порядок пикселей в TGA (BGR, вместо RGB), меняем канали b и r местами в pixelAt и наслаждаемся картинкой на большом и классном IPS-дисплее:

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост
Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


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

Есть вариант для быстрой и динамичной графики: использовать GLES, который без проблем доступен и из recovery. Однако, насколько мне известно (в исходники драйверов посмотреть не могу), указать фреймбуфер в качестве окна не получится, поэтому в качестве Surface для рендертаргета у нас будет служить Pixmap (так называемый off-screen rendering), которому нужно задать правильный формат пикселя (см. документацию EGL). Рисуем туда картинку с аппаратным ускорением и затем просто копируем в фреймбуфер с помощью memcpy.

❯ Обработка нажатий


Однако, ни о каких GUI-программах не идёт речь, если мы не умеет обрабатывать нажатия на экране с полноценным мультитачем! Благо, даже механизм обработки событий в Linux очень простой и приятный: мы точно также открываем устройство и просто читаем из него события в фиксированную структуру. Эта черта мне очень нравится в архитектуре Linux!

Каждое устройство, которое может передавать данные о нажатиях, находится в папке /dev/input/ и имеет имя вида event. Как узнать нужный нам event? Нам нужен mtk-tpd — реализация драйвера тачскрина от MediaTek (у вашего чипсета может быть по своему), для этого загружаемся в Android и пишем getevent. Он покажет доступные в системе устройства ввода — в моём случае, это event2:

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост


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

// Open input device evDev = open(INPUT_EVENT_TPD, O_RDWR | O_NONBLOCK);


После этого, читаем события с помощью read и обрабатываем их. На устройствах с резистивным тачскрином, передается просто ABS_POSITION_X, на устройствах с поддержкой нескольких касаний — используетсяпротокол MT. Когда пользователь нажал на экран, посылается нажатие BTN_TOUCH с значением 1, а когда отпускает — соответственно BTN_TOUCH с значением 0. Разные драйверы тачскрина используют разные координатные системы (насколько я понял), в случае MediaTek — это абсолютные координаты на дисплее (вплоть до ширины и высоты). На данный момент, я реализовал поддержку только одного касания, но при желании можно добавить трекинг нескольких нажатий:

void m2dUpdateInput()

{

input_event ev;

int ret = 0;

while((ret = read(evDev, &ev, sizeof(input_event)) != -1))

{

if(ev.code == ABS_MT_POSITION_X) tsState.x = ev.value;

if(ev.code == ABS_MT_POSITION_Y) tsState.y = ev.value;

if(ev.code == BTN_TOUCH) tsState.isPressed = ev.value == 1;

}

tsState.cb(tsState.isPressed, tsState.x, tsState.y); }


Теперь мы можем «возить» логотип Хабра по всему экрану:

void onTouchUpdate(bool isTouching, int x, int y) {

if(isTouching)

{

tsX = x;

tsY = y;

}

}

int main(int argc, char** argv) {

printf("Test\n");

m2dInit();

test = m2dLoadImage("test.tga");

test2 = m2dLoadImage("habr.tga");

printf("Volume: %i %i\n", vol, muteState);

m2dAttachTouchCallback(&onTouchUpdate);

while(1) {

m2dUpdateInput();

m2dClear();

m2dDrawImage(test, 0, 0, 1.0f);

m2dDrawImage(test2, tsX - (test2->width / 2), tsY - (test2->height / 2), 0.5f);

m2dFlush();

}

return 0;

}

Исходники закрыты, но мы не сдадимся: Пишем полностью нативное GUI-приложение под No-Name смартфон без Android Гаджеты, Смартфон, Linux, Телефон, IT, Хакеры, Hacking, Программирование, Embedded, C++, Одноплатный компьютер, Nix, Unix, Ядро, Kernel, Android, Длиннопост



В целом, это уже можно назвать минимально-необходимым минимумом для взаимодействия с устройством и использованию всех его возможностей на максимум без Android. Более того, такой метод заработает почти на любом устройстве, в том числе и китайских NoName, где ни о каких исходниках ядра и речи нет. Теперь вы можете попытаться использовать ваше старое Android-устройство для чего-нибудь полезного без необходимости изучать API Android.

❯ Звук, модем и другие возможности


Для звука нам придётся использовать ALSA — поскольку эта подсистема звука сейчас используется в большинстве устройств на Linux. Судя по всему, тут есть режим эмуляции старого и удобного OSS, поскольку устройства /dev/snd/dsp присутствует. Однако, вывод в него какого либо PCM-потока не даёт ничего, поэтому нам пригодится ALSA-lib.

Другой вопрос касается модема и сети. И если Wi-Fi ещё можно поднять (wpa_supplicant можно взять из раздела /system/), то с модемом будут проблемы — нет единого протокола по общению с ним и кое-где, чтобы его заставить работать, нужно будет немного попотеть. Не стесняйтесь изучать исходники ядра (MediaTek охотно делится реализацией вообще всего — там и RIL, и драйвер общения с модемом) и смотреть интересующие вас фишки!

❯ Заключение


Как мы с вами видим, у старых девайсов все еще есть перспективы стать полезными в какой-либо сфере даже без Android на борту. На тех устройствах, где нет порта Ubuntu или обычного десктопного Linux, всё равно сохраняется возможность писать нативные программы и попытаться приносить пользу.

Не стесняйтесь лезть и изучать вендорские исходники — это даёт понимание, как работают устройства изнутри. Собственно, благодаря такому ежедневному копанию исходников системы и появилась данная статья! :)

Показать полностью 14
[моё] Гаджеты Смартфон Linux Телефон IT Хакеры Hacking Программирование Embedded C++ Одноплатный компьютер Nix Unix Ядро Kernel Android Длиннопост
138
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии