четверг, 13 апреля 2017 г.

Я — экспериментатор...

Порой бывает полезно отойти на пару шагов от мэйнстрима и попробовать что-то новое, вроде как "сыграть новым мячом на старом поле". Эксперимент в этой статье — программирование для микроконтроллеров на базе ARM Cotrex M3+ (линейка STM32) на новом и современном языке низкого уровня Rust.

До меня больших успехов добились иностранные комрады, но в статьях нет результатов и сравнений, так что чтобы оценить, нужно самому собрать и посмотреть глазами.
1. Компилятор
Чтобы собирать "ржавые" программы для микроконтроллера, нужен кросс-компилятор. Так вот, в данном случае он не нужен. Ну, почти ☺ Объяснение тому очень простое: Rust сам не создаёт код под платформу, а генерирует Си-код, который потом отдаётся обычному Си-компилятору. Поэтому, правильно, кросс-Rust, как таковой, не нужен, а нужен обычный Rust и кросс-gcc. Впрочем, это же не проблема, т.к. он и так уже есть. Не хватает лишь core-библиотеки языка, собранной под нужную платформу.
Есть одна тонкость. Компилятор Rust и его окружение бывают двух видов: stable и nightly. Так вот, если у вас уже есть stable, например, из вашего дистрибутива, то он абсолютно бесполезен. Серьёзно. Они, как будто, существуют в парралельных вселенных, хотя собираются из одних и тех же исходников: библиотеки, собранные для stable не принимаются nightly и наоборот. На самом деле, даже собственную libcore стабильный компилятор собрать не может %)
Поэтому сносим стабильный Rust, скачиваем компилятор (rustc), библиотеку (rust-std) и исходники. Версии (или git-коммит) у всех трёх должны совпадать! Устанавливаем компилятор и библиотеку (вероятно, в /usr/local) и проверяем сборкой какого нибудь "Hello, world". Успешно? идём дальше!
Далее разворачиваем где-нибудь исходники и компилируем кросс-библиотеку core:
rustc -C opt-level=2 -Z no-landing-pads --target thumbv7m-none-eabi -g path-to-rust/src/libcore/lib.rs
Довольно быстро получаем libcore.rlib которую помещаем, опять же, в дерево rust, например в папку /usr/local/lib/rustlib/thumbv7m-none-eabi/lib/
На этом шаге уже можно компилировать какие-нибудь исходники в объектные файлы (*.o), которые можно уже линковать в прошивки.
Проверим это прямо на микроконтроллере:
  1. Берём демонстрационный код
  2. Собираем
  3. Запускаем на STM32
Результаты по размеру кода: 8360 байт против 3916 байт (без rust-кода). Итого добавление минимальной rust-функции отъело 4444 байта флеш-памяти.
Продолжение следует.