Go выходит за пределы серверов: теперь язык добрался до железа

mr. Cooper 2 дня назад Инсайды и новости
Go выходит за пределы серверов: теперь язык добрался до железа

Go долго жил в довольно понятной нише: серверы, API, микросервисы, Kubernetes, сетевые инструменты. Если разработчику нужно было писать код для железа, выбор обычно выглядел совсем иначе - C, C++, а теперь ещё и Rust.

Но эта граница постепенно сдвигается.

TinyGo 0.42 получил новые возможности для embedded-разработки, а сам проект всё глубже уходит в мир микроконтроллеров, беспроводных устройств и систем, которые работают ещё до запуска операционной системы. В новой версии появились recoverable panic, поддержка Go 1.27 и LLVM 22, UEFI target, а вокруг проекта развивается готовый Starter Kit с ESP32-C3.

Для проекта, который когда-то было легко воспринимать как способ «запустить немного Go на маленькой плате», это уже довольно серьёзное развитие.

TinyGo постепенно разбирается с теми ограничениями, из-за которых Go долго оставался чужим для embedded-разработки: памятью, runtime, поддержкой конкретного железа и поведением программы при ошибках.

Почему обычный Go здесь не подходит

Микроконтроллер - совсем не сервер.

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

Сам Go изначально создавался под другие условия. Его runtime рассчитан на среду, где ресурсов достаточно.

TinyGo решает проблему на уровне компиляции: Go-код превращается в более компактные программы, которые можно запускать в том числе на микроконтроллерах.

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

И вот здесь изменения последних версий TinyGo становятся особенно заметны.

Panic теперь можно перехватывать

Одна из заметных новинок TinyGo 0.42 - recoverable runtime panics.

В обычном Go panic останавливает выполнение текущей горутины, а recover() позволяет перехватить панику внутри defer. Для разработчиков Go это давно знакомый механизм.

В TinyGo его возможности были гораздо более ограниченными.

Теперь некоторые runtime-ошибки можно обрабатывать привычным способом. Например, речь идёт о разыменовании nil-указателя, выходе за границы slice или map и делении на ноль. Для этого можно использовать обычные defer и recover.

При этом TinyGo не пытается сделать восстанавливаемой любую ошибку. Нехватка памяти, например, остаётся фатальной.

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

Go может работать ещё до запуска операционной системы

В TinyGo 0.42 появился новый UEFI target.

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

Для Go это довольно необычная территория.

Получается любопытная ситуация: язык, который чаще всего связывают с HTTP-серверами, backend и инфраструктурой, теперь можно использовать для приложения, запускающегося ещё до загрузки ОС.

Это не значит, что Go внезапно начал конкурировать с C или Rust во всей firmware-разработке. До такого вывода пока очень далеко.

Но сам UEFI target хорошо показывает направление TinyGo. Проект постепенно спускается туда, где Go раньше практически не использовали.

Микроконтроллер превращается в сетевое устройство

Ещё один важный кусок этой истории появился в TinyGo 0.41.

Проект расширил работу с беспроводными возможностями ESP32-C3 и ESP32-S3. Появилась нативная поддержка Wi-Fi и Bluetooth через espradio, а утилита espflasher упростила загрузку программ на устройства.

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

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

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

Но TinyGo развивается не только вокруг железа

Есть ещё одно направление - WebAssembly.

TinyGo умеет компилировать Go в компактные .wasm-бинарники и WASI-приложения. Это позволяет использовать Go в средах, где WebAssembly выступает самостоятельным runtime, в том числе в edge-сценариях.

Причём возможности здесь уже довольно серьёзные. TinyGo поддерживает работу с горутинами в WebAssembly-окружениях, а Binaryen Asyncify позволяет использовать стандартные Go goroutines при GOMAXPROCS=1.

Показательный пример - typescript-go, новый компилятор TypeScript от Microsoft, написанный на Go. Команде TinyGo удалось собрать его целиком в WebAssembly.

Это уже далеко от классического сценария «скомпилировали небольшую программу для платы».

Получается, TinyGo одновременно двигается в нескольких направлениях: микроконтроллеры, WebAssembly и edge-среды.

У проекта появилось и своё железо

Вместе с программными изменениями развивается TinyGo Starter Kit, созданный совместно с Seeed Studio.

В комплект входит XIAO ESP32-C3, Grove Base и 11 модульных компонентов. Среди них датчики температуры, света и касания, OLED-дисплей, зуммер и RGB-компоненты.

На первый взгляд это просто набор для обучения.

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

Готовый комплект сокращает этот путь. Можно взять плату, подключить модуль и сразу экспериментировать с Go.

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

Но C и Rust никуда не делись

Здесь легко переоценить происходящее.

Embedded-разработка требует гораздо большего контроля, чем обычный backend. Имеют значение конкретный процессор, объём памяти, периферия, драйверы, ограничения runtime и поведение программы при сбоях.

В некоторых проектах критичны предсказуемость выполнения и возможность контролировать практически каждый уровень системы.

Поэтому появление recover, UEFI или Wi-Fi-поддержки ещё не превращает TinyGo в универсальную замену C или Rust.

Но аргумент против Go постепенно меняется.

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

Теперь часть этих ограничений последовательно снимается.

Go всё дальше уходит от образа только серверного языка

Именно это в истории TinyGo кажется мне самым интересным.

Проект уже не ограничивается демонстрацией того, что Go вообще можно запустить на микроконтроллере. Разработчики добавляют нормальную обработку runtime-паник, новые платформы, Wi-Fi и Bluetooth, инструменты прошивки, WebAssembly и готовое железо.

При этом направления начинают пересекаться.

Go уже давно чувствует себя уверенно на сервере. Через WebAssembly он выходит в другие runtime и edge-среды. TinyGo переносит его на микроконтроллеры. UEFI позволяет использовать Go ещё до загрузки операционной системы.

До универсального языка «для всего» ему по-прежнему далеко.

Но образ Go как языка исключительно для backend и инфраструктуры постепенно устаревает. TinyGo 0.42 - ещё один довольно наглядный пример того, насколько далеко этот сдвиг уже зашёл.

Комментарии

Пока нет комментариев. Будьте первым, кто напишет.

Чтобы оставить комментарий, войдите в аккаунт.

Похожие статьи