4. Platform - точка входа
Platform - единственный объект, через который прошивка получает доступ к «железу» и ко всем включённым сервисам. Это абстрактный интерфейс: конкретную реализацию (ESP32 или симулятор) возвращает GetPlatform().
Platform *plat = GetPlatform();
GetPlatform() - синглтон, вызывать можно откуда угодно и сколько угодно раз.
Время и задержки
| Метод |
Описание |
uint32_t nowMs() |
Монотонное время с запуска, мс. |
uint64_t nowUs() |
Монотонное время, мкс |
void delayMs(uint32_t ms) |
Пауза без нагрузки на CPU (уступает планировщику FreeRTOS) |
bool shouldQuit() const |
Запрос на выход: в симуляторе - закрытие окна, на ESP32 всегда false |
GPIO
| Метод |
Описание |
void pinModeInput(uint8_t pin, InputMode mode) |
Настроить пин как вход: InputMode::Floating / Pullup / Pulldown |
bool digitalRead(uint8_t pin) |
Цифровое чтение входа |
int16_t analogRead(uint8_t pin) |
Чтение АЦП (сырой код, 0…4095). ADC-юнит и канал выбираются автоматически по номеру пина (при неверном пине вернёт 0) |
Память
| Метод |
Описание |
void *alloc(size_t bytes, AllocCaps caps) |
Аллокация. Вернёт nullptr при нехватке памяти. AllocCaps::PreferInternal - сначала внутренняя RAM (нужно для DMA-буферов), при нехватке - внешняя |
void free(void *ptr) |
Освобождение памяти из alloc. nullptr безопасен |
void *allocAligned(size_t bytes, size_t align, AllocCaps caps) |
Аллокация с выравниванием (align меньше sizeof(void*) поднимается до него) |
void freeAligned(void *ptr) |
Освобождение памяти из allocAligned |
uint32_t freeHeapTotal() |
Свободно всего, байт |
uint32_t freeHeapInternal() |
Свободно во внутренней RAM, байт |
uint32_t largestFreeBlock() |
Крупнейший непрерывный блок, байт |
uint32_t minFreeHeap() |
Исторический минимум свободной кучи, байт |
Память, выделенную alloc, освобождайте только free, а из allocAligned - только freeAligned. Смешивать их нельзя.
void *buf = plat->alloc(4096, AllocCaps::PreferInternal); // DMA-буфер
if (!buf)
return;
// ...
plat->free(buf);
Дисплей
| Метод |
Описание |
bool configDisplay(const DisplayConfig &cfg) |
Сконфигурировать SPI-транспорт и драйвер панели. Можно вызывать повторно (смена параметров). false - если width/height нулевые или конфигурация не принята драйвером |
bool beginDisplay(uint8_t rotation) |
Инициализировать панель, поворот 0..3. Вызывается после успешного configDisplay |
bool setDisplayRotation(uint8_t rotation) |
Сменить поворот на лету, без повторной инициализации |
Display *display() |
Интерфейс дисплея; nullptr, если дисплей не сконфигурирован или не запущен |
Ошибки
if (!plat->configDisplay(cfg))
{
PlatformError code = plat->lastError(); // enum
const char *text = plat->lastErrorText(); // "invalid display config", ...
}
PlatformError |
Текст |
Когда возникает |
None |
ok |
Ошибок нет |
InvalidDisplayConfig |
invalid display config |
Нулевое разрешение; вызов beginDisplay/setDisplayRotation до успешной конфигурации |
DisplayConfigureFailed |
display configure failed |
Драйвер не принял параметры |
DisplayBeginFailed |
display begin failed |
Не удалось выполнить инициализацию панели |
DisplayIoFailed |
display io failed |
Ошибка SPI-передачи (в т. ч. при смене поворота) |
lastError() также возвращает DisplayIoFailed, если драйвер панели зафиксировал сбой ввода-вывода, даже когда последняя операция платформы прошла успешно. platformErrorText(PlatformError) даёт текст для любого значения.
Сервисы
| Метод |
Возвращает |
net::Backend *network() |
WiFi-бэкенд или nullptr, если модуль выключен |
ota::Backend *update() |
OTA-бэкенд или nullptr |
Touch *touch() |
Тач или nullptr |
Audio *audio() |
Микшер или nullptr |
prefs::Backend *prefs() |
Хранилище настроек или nullptr |
Для WiFi, OTA, Prefs и Storage обычно удобнее свободные функции (net::wifiService(), prefs::setU8(...), storage::open(...)) - они сами достают бэкенд из платформы. Прямые указатели нужны, когда хочется хранить интерфейс у себя.
DisplayConfig
struct DisplayConfig
{
int8_t mosi = -1; // пины SPI; -1 = не используется
int8_t sclk = -1;
int8_t cs = -1; // chip select
int8_t dc = -1; // data/command
int8_t rst = -1; // аппаратный reset; -1 - не подключён
uint16_t width = 0; // разрешение панели в пикселях (обязательно)
uint16_t height = 0;
uint32_t hz = 0; // частота SPI, Гц
uint8_t order = 0; // порядок каналов в MADCTL: 0 = RGB, 1 = BGR
bool invert = true; // инверсия цвета (нужна большинству IPS-панелей)
bool swap = false; // байтовый своп RGB565 перед отправкой
int16_t xOffset = 0; // сдвиг окна для панелей, у которых контроллер
int16_t yOffset = 0; // больше стекла (например, 240×320 внутри)
};