---
# System prepended metadata

title: '卒研経過報告 #11'

---

# 卒研経過報告 #11
Rustによる組み込みプログラミング
マイコンWio terminalを用いたRustとC言語の信頼性，安全性の比較検証、考察

[先週のレジュメ](https://hackmd.io/@Fteam/r1JFOvjvF)

### 型状態プログラミング
今回はマイコンのピン設定を誤り，コード内で誤った動作をプログラマが記述しまった例を取り上げる．
rustではこのような誤りを防ぐ仕組みが導入されており，例えばGPIOピンのインスタンスを出力設定にしないと，highレベルを出力するメソッド(set_high())を呼び出せないようになっている．

- Arduino IDE環境でビルド
wio tirminalのボタン１を押している時間だけLEDが点灯するC++(arduino言語)のプログラム．
入力に設定したGPIOピンにhigh,lowレベルを出力するよう設定する．
```cpp=
void setup() {
  //pinMode(WIO_KEY_A, INPUT_PULLUP);
  //pinMode(LED_BUILTIN, OUTPUT);
  pinMode(WIO_KEY_A, INPUT_PULLUP);
  pinMode(LED_BUILTIN, INPUT_PULLUP);  //誤りOUTPUT->INPUT_PULLUP
}

void loop() {
  int value = digitalRead(WIO_KEY_A);
  
  if(value == HIGH){
        digitalWrite(LED_BUILTIN, LOW);
  }else{
        digitalWrite(LED_BUILTIN, HIGH);
  }
}
```
**実行結果**
コンパイルエラーが発生することなく，意図した通りボタンを押したときだけLED点灯．

---
上記のコード4,5行目を出力として設定し再試行．
```cpp=4
  pinMode(WIO_KEY_A, OUTPUT);  //誤りINPUT_PULLUP->OUTPUT
  pinMode(LED_BUILTIN, OUTPUT);
```
**実行結果**
コンパイルエラーは発生せず，wio Terminalも動作なし．

- rust


LEDとボタンの入出力には、

LEDにつながっているGPIOピンを出力に設定してhigh/lowを制御するとLEDが点灯/消灯
highを出力するとLEDが点灯

ボタンにつながっているGPIOピンを入力に設定してhigh/lowを読み取るとボタンが押されているかどうかがわかる
ボタンを押すとlowが入力される

ボタン1を押している間、ユーザLEDを点灯させるプログラム
```rust=
#![no_std]
#![no_main]

use panic_halt as _;
use wio_terminal as wio;

use wio::entry;
use wio::pac::Peripherals;
use wio::prelude::*; // 主要な構造体やトレイトをインポートする

#[entry]
fn main() -> ! {
    // PACのperipheralsオブジェクトを取得する
    let peripherals = Peripherals::take().unwrap();
    //PORTを消費して、GPIOピンがまとめられたオブジェクトを初期化する
    let mut pins = wio::Pins::new(peripherals.PORT);
    
    //ユーザLEDのGPIOピンを出力状態に設定する
    //let led =pins.user_led.into_push_pull_output(&mut pins.port);
    //誤りであえて入力状態に設定する
    let led =pins.user_led.into_floating_input(&mut pins.port);
    //ボタン1のGPIOピンを入力状態に設定する
    let button1 = pins.button1.into_floating_input(&mut pins.port);

    
    loop {
        if button1.is_low().unwrap(){
            //ボタン1が押されていればユーザLEDを点灯する
            led.set_high().unwrap();
        }else{
            //ボタンが押されていなければユーザLEDを消灯する
            led.set_low().unwrap();
        }
    }
}

```
入力に設定したuser_ledに対して出力の操作である
set_high()
set_low() を呼び出すと
以下のようなエラーになる

```
led.set_low().unwrap();
    |                   ^^^^^^^ method cannot be called on 
    `wio_terminal::atsamd_hal::gpio::Pin<PA15, wio_terminal::atsamd_hal::gpio::v2::Input<wio_terminal::atsamd_hal::gpio::v2::Floating>>` due to unsatisfied trait bounds
```

Rustでは型状態プログラミングによってコンパイル時にこのような不正な操作を検出する



## 参考文献
[1] rustプログラミング入門　オーム社
[２] 基礎から学ぶ組込みRust C&R研究所
[公式ドキュメント](https://doc.rust-jp.rs/book-ja/ch08-02-strings.html)
[seeed:ユーザー定義ボタン](https://wiki.seeedstudio.com/jp/Wio-Terminal-Buttons/)
[](https://tomo-wait-for-it-yuki.hatenablog.com/entry/2019/01/30/163235)



