LoginSignup
1
3

More than 1 year has passed since last update.

組み込みrustのバージョンアップ

Posted at

背景

組み込みrustという本を買ったが、だいぶバージョンが古いクレートを使っていて苦戦してしまった
そこでバージョンを上げてソースコードを修正してやろうというつもりである。
本のリンク
https://www.c-r.com/book/detail/1403

クレートに関して

wio_terminal = "0.6.1"
を使う。本のほうは0.3だった。
以下が今回更新したクレートのver
wio_terminal = "0.6.1"
cortex-m = "0.7.3"
cortex-m-rt = "0.7"
embedded-graphics = "0.7.1"
heapless = "0.7.15"

本のver
wio_terminal = "0.3"
cortex-m = "0.6.4"
cortex-m-rt = "0.6.13"
embedded-graphics = "0.6.2"
heapless = "0.5.6"

ちなみにcargo.tomlのedition、本だと"2018"ですがクレートのver上げると"2021"にしないと
note: std is required by memchr because it does not declare #![no_std]
みたいなエラーが出ます

ソースコードに関して

自作のソースコードである。いや本のやつ使えよというツッコミかと思いますが・・・参考にならなくてごめんなさい・・・
おおよそ上の本の書き方をまぜまぜしただけなのでなんとなく
必要なものが分かる程度認識でお願いします。

最初にまとめ

・ピン配置の型の書き方
・メソッドにportを引数として入れなくてよくなった
・embedded-graphicsのマクロが使えない

直すところ

ピンの型

pub struct Led {
    pin: Pa15<Output<PushPull>>,
}

この書き方昔はOKだったのだが
https://docs.rs/atsamd-hal/0.12.0/atsamd_hal/common/gpio/v1/type.Pa15.html
今は実はない
https://docs.rs/atsamd-hal/latest/atsamd_hal/?search=pin15
これのpa15のところを見てみると
https://docs.rs/atsamd-hal/latest/atsamd_hal/gpio/pin/struct.Pins.html#structfield.pa15
どうやら書き方としては
Pin<PA15, Reset>
を使えばよさそうである
Mの部分は初期化前はリセット、初期化後はそのピンの動作モードをいれてやればよい

ピンのメソッドの変化

    pub fn new(pin: Pin<PA15,Reset>, port: &mut Port) -> Led {
        Led {
            pin: pin.into_push_pull_output(port),
        }
    }

引数にポートを入れているが
https://docs.rs/atsamd-hal/0.12.0/atsamd_hal/common/gpio/v1/struct.Pin.html
最新のもののメソッドを見てるといらなくなっている。
https://docs.rs/atsamd-hal/latest/atsamd_hal/gpio/pin/struct.Pin.html
またそれに伴いlib、mainともにport関連の変数を削除してやる。newの引数とか。

ピンのモードの変化

pub struct Myadc {
    pb8: Pb8<PfB>,
}
impl Myadc {
    // PC26ピンを入力モードに設定する
    pub fn new(pin: Pb8<Input<Floating>>, port: &mut Port) -> Myadc {
        Myadc {
            pb8: pin.into_function_b(port),

        }
    }

Pb8<PfB>は上記と同様にPin<PB08, AlternateB>にしてやればよいが
pin.into_function_b(port)をどうする?
Struct atsamd_hal::gpio::pin::Pin の項を見てみると
pub fn into_alternate<C: AlternateConfig>(self) -> Pin<I, Alternate<C>>
を使ってやればよさそうだが、前と違ってこの行でオルタネートBを選択しないので
オルタネートBになってくれるのか不安がある。⇒とりあえず動きはした

UART

    let mut serial = sets.uart.init(
        &mut clocks,
        115200.hz(),
        peripherals.SERCOM2,
        &mut peripherals.MCLK,
        &mut sets.port,
    );

UARTに関して、単純に古いものと比べると新しいほうにはportがいらなくなっているだけ
古い↓
https://docs.rs/wio_terminal/0.3.0/wio_terminal/struct.UART.html
新しい↓
https://docs.rs/wio_terminal/0.6.1/wio_terminal/struct.Uart.html

クレートnb

error[E0659]: `nb` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
   --> src\main.rs:152:26
    |
152 |         let mut x :u16 = nb::block!(groove.read(&mut pb8)).unwrap();
    |                          ^^ ambiguous name
    |
    = note: `nb` could refer to a crate passed with `--extern`
    = help: use `::nb` to refer to this crate unambiguously
note: `nb` could also refer to the crate imported here
   --> src\main.rs:20:5
    |
20  | use wio::prelude::*;
    |     ^^^^^^^^^^^^^^^
    = help: consider adding an explicit import of `nb` to disambiguate
    = help: or use `crate::nb` to refer to this crate unambiguously

nbクレートで怒られる。最新ではwio::prelude でインポートするようになったからだ
https://docs.rs/wio_terminal/latest/wio_terminal/prelude/index.html
とりあえずクレートを明示する方法で対処することに。
use crate::nb を追加で対処(ちなみに最新verは0.1のままだったのでwio::preludeのやつでよかったかも)

クレートembedded_graphics

fn draw<T>(display: &mut T , x:u16) -> Result<(), T::Error>
where
    T: embedded_graphics::DrawTarget<Rgb565>,
{
    // カウント表示エリアをクリアする
    const FONT_WIDTH: i32 = 24;
    const FONT_HEIGHT: i32 = 32;
    egrectangle!(
//~以下省略
}

このdrawメソッドは本の例そのままになるが使われているクレートの
Embedded graphics、0.6.2から0.7.1にあげたらマクロ無くなってた
https://docs.rs/embedded-graphics/0.7.1/embedded_graphics/all.html
昔のはある
https://docs.rs/embedded-graphics/0.6.2/embedded_graphics/all.html

ちなみにwioのクレートのバージョンだけ上げたとしてマクロの後のdrawメソッドを使うだけでエラー出る
どうもwioのバージョン上げたらili9341~のトレイトが実装されなくなった?
132 | .draw(&mut display)
| ---- ^^^^^^^^^^^^ the trait DrawTarget<Rgb565> is not implemented for ili9341::Ili9341<display_interface_spi::SPIInterface<Spi<wio_terminal::atsamd_hal::sercom::spi::Config<wio_terminal::atsamd_hal::sercom::spi::Pads<SERCOM7, IoSet4, NoneT, wio_terminal::atsamd_hal::gpio::Pin<PB19, wio_terminal::atsamd_hal::gpio::Alternate<wio_terminal::atsamd_hal::gpio::D>>, wio_terminal::atsamd_hal::gpio::Pin<PB20, wio_terminal::atsamd_hal::gpio::Alternate<wio_terminal::atsamd_hal::gpio::D>>>>, wio_terminal::atsamd_hal::sercom::spi::Tx>, wio_terminal::atsamd_hal::gpio::Pin<PC06, wio_terminal::atsamd_hal::gpio::Output<wio_terminal::atsamd_hal::gpio::PushPull>>, wio_terminal::atsamd_hal::gpio::Pin<PB21, wio_terminal::atsamd_hal::gpio::Output<wio_terminal::atsamd_hal::gpio::PushPull>>>, wio_terminal::atsamd_hal::gpio::Pin<PC07, wio_terminal::atsamd_hal::gpio::Output<wio_terminal::atsamd_hal::gpio::PushPull>>>

まずdisplayはsets.display.init()で帰ってきた型なのでそれを見てみる
古い型
type LCD = Ili9341<SPIInterface<SPIMaster7<Sercom7Pad2<Pb18<PfD>>, Sercom7Pad3<Pb19<PfD>>, Sercom7Pad1<Pb20<PfD>>>, Pc6<Output<PushPull>>, Pb21<Output<PushPull>>>, Pc7<Output<PushPull>>>;
新しい
pub type LCD = Ili9341<SPIInterface<LcdSpi, LcdDc, LcdCs>, LcdReset>;
だいぶ名前は違うが中身はそのままな気がする。なんでだろう。
いずれにせよ最新版ではegrectangle!のようなマクロを使えなくなったので大幅に変更する必要がある。

今回の自分の場合は実はテキストだけ表示させればいいのでexampleを使おうと思う
https://github.com/atsamd-rs/atsamd/blob/master/boards/wio_terminal/examples/usb_serial_display.rs

Terminal構造体とそのメソッドを使えるようにすればよさそう。細かいやり方は省略。
ただ、このやり方だと文字列はいいが数値を取り扱えない。今回の自分の場合はStringにしてやった

use heapless::String;
let mut x :u16 = 1;
let s: String<8> = String::from(x);
t.write_str(&s);

embedded-graphicsに関してはグラフ表示したいと思っているので別途記事つくるかも?

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3