ラズピコでRust(13) embedded-hal Ver1.0.0を試す

ラズピコでRust(13) embedded-hal Ver1.0.0を試す

皆さん こんにちは。
ポンコツRustacean の moon です。

今回は embedded-hal Ver1.0.0 の話題です。

この記事は開発環境を構築することを前提にしています。
環境構築について知りたい方は こちらの記事 をご覧になってください。

このサイトは 書籍 基礎から学ぶ組込みRust を参考にしています。

これまでに GPIO , UART , SPI , I2C など を扱ってきましたが embedded-hal のバージョンは 0.2.x を使ってきました。

このところセンサーで温度等を計測し、RTCを使った時刻と併せて液晶に表示するところまでRustのコードを書いてきました。

最後にSDカードに記録してみようと思ったのですが、軽く調べた感じだと embedded-hal のバージョンは 1.0.0 を使うのが近道のようです。

embedded-hal Ver1.0.0 はずっと気になっていたのですが難しそうな気がして手を出せずにいました。

ちょうど良い機会なので、重い腰を上げてトライしてみることにしました。

embedded-hal

「embedded-hal って何?」という方は先ほど紹介した書籍に詳しく書かれていますので、手にとってご覧になることをお薦めします。

ひと言でいうと抽象化するための手段です。
各メーカーのマイコンに HAL があり、更にそれをもう少し大きな枠で囲ったイメージでしょうか。

トレイトという規格のようなものをつくり、それに合わせて各メーカーのマイコンのHALを実装します。

そのトレイトのメソッドを使えば共通化が図れるというものです。

(トレイトは C++ で言うところのインターフェースに似た機能です)

HALとBSP

embedded-halのバージョンを上げるということは、各マイコンのHALのバージョンにも気をつける必要があります。
少なくとも embedded-hal Ver1.0.0 が生まれた日以降の HAL を使う必要があるはずです。

トレイトのメソッドのシグネチャに合わせてマイコンHALへの実装を行う必要があるためです。

ラズピコのマイコンは RP2040 でしたね。
このHALのクレートは r02040-hal です。

crates.io で検索すると ver0.10.2 が最新なので、こちらを使ってみることにします。

HALに対してBSP (board support package)というものがあり、これは各ボードに対するクレートです。

ラズピコの場合は rp-pico がそのクレートで最新の 0.9.0 を使うことにします。

パッケージの複製を作成する

まず私のGitHubリポジトリにあるRustのひな形をベースに別名でパッケージをつくります。
ひな形は以前作成したデバッグ環境用のものですから、その複製もデバッグできるようになります。

新しいパッケージ名を rp2040-ehv1 として git clone します。
xxxxは皆さんのユーザー名です。
カレントディレクトリを rp2040-ehv1 に移してから、code . で VSCode を起動します。

ehv1 は embedded-hal version1 の略です。

C:\Users\xxxx>cd pprp
C:\Users\xxxx\pprp>git clone https://github.com/moons3925/rp2040.git rp2040-ehv1
C:\Users\xxxx\pprp>cd rp2040-ehv1
C:\Users\xxxx\pprp\rp2040-ehv1>code .

launch.jsonを編集する

EXPLORER – ツリーの .vscode 下にある launch.json をクリックして編集します。

executable: の名称を rp2040 から rp2040-ehv1 に変更します。

"executable": "./target/thumbv6m-none-eabi/debug/rp2040-ehv1",

Cargo.tomlを編集する

個々のバージョンが違っていたりするとエラーが出たりしてやっかいですので。。
以下をコピペしてください。

[package]
edition = "2021"
name = "rp2040-ehv1"
version = "0.1.0"
license = "MIT OR Apache-2.0"

[dependencies]

rp-pico = "0.9.0"
rp2040-hal = "0.10.2"
embedded-hal = "1.0.0"
panic-halt = "0.2.0"
cortex-m-rt = "0.7.3"
cortex-m = "0.7.7"

main.rsを編集する

#![no_std]
#![no_main]

use embedded_hal::digital::OutputPin;
use panic_halt as _;
use rp_pico::entry;
use rp_pico::hal;
use rp_pico::hal::pac;
use rp_pico::hal::prelude::*;
#[entry]
fn main() -> ! {
    let mut pac = pac::Peripherals::take().unwrap();
    let core = pac::CorePeripherals::take().unwrap();

    let mut watchdog = hal::Watchdog::new(pac.WATCHDOG);

    let clocks = hal::clocks::init_clocks_and_plls(
        rp_pico::XOSC_CRYSTAL_FREQ,
        pac.XOSC,
        pac.CLOCKS,
        pac.PLL_SYS,
        pac.PLL_USB,
        &mut pac.RESETS,
        &mut watchdog,
    )
    .ok()
    .unwrap();

    let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());

    let sio = hal::Sio::new(pac.SIO);

    let pins = rp_pico::Pins::new(
        pac.IO_BANK0,
        pac.PADS_BANK0,
        sio.gpio_bank0,
        &mut pac.RESETS,
    );

    let mut led_pin = pins.led.into_push_pull_output();

    loop {
        led_pin.set_high().unwrap();
        delay.delay_ms(100);
        led_pin.set_low().unwrap();
        delay.delay_ms(100);
    }
}

ビルドして実行する

Run – Start Debugging (F5) からプログラムを実行します。

Lチカすれば成功です。

embedded-hal Version1.0.0の証明

プログラムの先頭に以下のコードがあります。
OutputPinはembedded_halのトレイトのひとつです。

use embedded_hal::digital::OutputPin;

version0.2.xの時は digital::v2::OutputPin と言う風に v2 が間に入っていました。
v2 無しでビルドが通っているので Version0.2.x でないことがわかります。

ご興味のある方はVersion1.0.0のファイルやフォルダ構成をご確認ください。

Cargo.toml の [dependencies] に列挙したクレートは自PCのハードディスク内に取り込まれます。
私の場合、embedded-halの格納場所は以下にありました。
m3925は皆さんのユーザー名に置き換えてください。
あと、index.crates.io- の後の英数字はランダムな値になるのかも知れません。

C:\Users\m3925\.cargo\registry\src\index.crates.io-6f17d22bba15001f\embedded-hal-1.0.0

ここのsrc下のdigital.rsを開くと OutputPin トレイトの記述が見つかります。

そして set_low() , set_high() などがトレイトのメソッドになります。

これらのシグネチャに合わせてマイコンHALの実装を行います。

GitHubにアップ

GitHubの rp2040-ehv1 にプロジェクトをアップしましたので参考になさってください。

お疲れさまでした。

embedded-halカテゴリの最新記事