Создание беспроводного термостата на Rust для Raspberry Pi — часть 2

Создание беспроводного термостата на Rust для Raspberry Pi — часть 2

1 ноября 2022 г.

Эта статья — вторая часть моей серии о создании беспроводного термостата на Rust для Raspberry Pi. Вы можете найти начало серии здесь. Весь исходный код проекта находится здесь.

Когда я подошел к задаче создания собственного исполняемого файла Rust для Raspberry Pi, одной из первых вещей, которые мне пришлось решить, было создание среды разработки для кросс-компиляции. Raspberry Pi работает под управлением Unix, но нам нужно скомпилировать исполняемые файлы для процессора ARM Pi.

Моя первая попытка следовала процессу, описанному в главе о кросс-компиляции Книги о Rustup. Мне нужно было найти подходящую цель для Raspberry Pi Zero (моя цель): arm-unknown-linux-gnueabihf. Эта цель будет немного отличаться, если вы хотите ориентироваться на Pi 3 или Pi 4 — тогда вы можете использовать target=armv7-unknown-linux-gnueabihf. Pi Zero использует версию процессора ARM v6, более крупные Pi используют версию v7 ​​(или выше).

Кросс-компиляция казалась простой, и, следуя указаниям Rustup Book, я добавил кросс-компиляцию в свою среду:

rustup target add arm-unknown-linux-gnueabihf
cargo build –target= arm-unknown-linux-gnueabihf

Но это не работает из коробки. Даже документация предупреждает вас: «Обратите внимание, что добавление цели rustup устанавливает только стандартную библиотеку Rust для данной цели. Обычно для кросс-компиляции необходимы другие инструменты, в частности компоновщик». Затем мое приложение использовало SSL, и мне также нужен был способ кросс-компиляции библиотеки OpenSSL для Pi. Я выполняю сборку под WSL2 (Ubuntu) на компьютере с Windows — настройка потребует некоторых усилий.

К счастью, есть более простой способ! Команда Rust Embedded Devices Tools публикует набор образов Docker, содержащих полный набор инструментов для большого количество целей кросс-компиляции. Более того, они создали «перекрестный» инструмент, который автоматизирует весь процесс запуска подходящего контейнера Docker, прикрепления вашего кода к контейнеру и запуска процесса компиляции. Инкрементные сборки полностью поддерживаются, поэтому кросс-компиляция не занимает много времени по сравнению с собственной компиляцией.

Чтобы настроить это, сначала установите инструмент «крест»:

cargo install cross

Затем скомпилировать любой проект для новой цели так же просто, как заменить «груз» на «крест» в вашей команде. Мне также пришлось передать флаг функций, чтобы получить библиотеку OpenSSL, созданную из исходного кода для целевой платформы:

cross build --release –target=arm-unknown-linux-gnueabihf --features vendored-openssl

Эта команда создаст исполняемый файл релиза по адресу ./target/arm-unknown-linux-gnueabihf/release/thermostat-pi (мой проект — «thermostat-pi»).

Для другой части проекта мне нужно было выполнить кросс-компиляцию в x86_64-unknown-linux-musl, чтобы создать AWS Lambda с использованием Rust. SDK AWS Rust документирует шаги и включает «контейнерный подход». который использует крест:

cross build --release --target x86_64-unknown-linux-musl

Вы можете найти проект lambda в папке ./push_temp в репозитории исходного кода.< /p>

Все эти команды сборки слишком длинные, чтобы я мог их запомнить. История командной строки очень помогает, но возвращение к проекту после продолжительного перерыва может означать повторный поиск команд сборки. Вместо этого я недавно нашел just, облегченную версию make, специально созданную для выполнения команд. Вы можете создать justfile, используя синтаксис, подобный Makefile make, для определения набора команд. Поддерживаются зависимости, что позволяет вам объединять различные команды по мере необходимости. Для проекта ./push_temp очень простой файл justfile выглядит так:

build: 
    cross build --release --target x86_64-unknown-linux-musl
    cp target/x86_64-unknown-linux-musl/release/push_temp bootstrap
test:
    curl -X POST -F "record_date=2022:02:03T15:50:00" -F "thermostat_on=true" -F "temperature=55" -F "thermostat_value=60" https://5zvz7wehuh.execute-api.us-east-2.amazonaws.com/test_lambda

Эта настройка позволяет использовать простую команду just build — насколько я помню! Тестовая цель отправляет пробную транзакцию в мою лямбда-функцию — опять же, сохраняя в центральном месте более длинную команду, которую я могу повторно использовать по мере необходимости.

Я также создал justfile для запуска кросс-компиляции основного проекта и автоматизировал развертывание исполняемого файла на Raspberry Pi. Созданный мной файл justfile выглядит следующим образом:

TARGET_HOST := "mhentges@shop-therm.local"
TARGET_PATH := "/home/mhentges/thermostat-pi"
TARGET_ARCH := "arm-unknown-linux-gnueabihf"
SOURCE_PATH := "./target/" + TARGET_ARCH + "/release/thermostat-pi"

check:
    cargo check

build:
    cross build --release --target= --features vendored-openssl
    rsync ./configuration.yaml :/home/mhentges/configuration.yaml
    rsync  :
    #ssh -t  

clippy:
    cargo clippy

Этот сценарий использует SSH, доступный между вашим хост-компьютером и PI, настроенный с помощью аутентификация с открытым ключом.

Использование инструментов Cross — это секретный соус, который упрощает кросс-компиляцию для Rust. Независимо от того, используете ли вы Windows, macOS, Linux или арендуете облачную среду разработки, вы можете настроить среду кросс-компиляции с помощью нескольких простых команд. Затем используется только для обеспечения автоматизации, позволяющей легко выполнять этапы сборки и развертывания.


Также опубликовано здесь.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE