Arduinoの上でさびを走らせる方法
もともと投稿しました.creativcoder.dev
これを書くとき、およそ1ヵ月前、さびAVRフォークは合併されましたupstream . これは、今すぐ実行することによって、AVR MicroControllerボードのための錆プログラムをコンパイルすることができることを意味します
私は常に物理オブジェクトを操作して、影響を与えるためにコードを使うという考えに魅了されました.これはおそらくArduinoと多分ESP 8266と発見F 3の上でさびによる私の冒険のブログ記事のシリーズであるでしょう.(私はこれらも同様に嘘をついています).この最初のポストでシリーズから離れてキックオフ.
ターゲットオーディエンス:このポストは、Arduinoで錆に埋め込まれたシステムとのヘッドスタートを望む心の中で初心者に初心者で書かれています.一旦このポストを終えたならば、あなたは基本を通してembedded rust book . ポストのコードはLinuxマシン( arch linux )でコンパイルされています.
我々はArduino Unoの上でさびを走らせる方法に関する旋風旅行をします.そして、それはおそらく最も有名で、ホビイスト組込みのドメインで開発ボードを使用しました.The Arduino Uno ATVGA 328 Pに基づきます.そして、それは家族AVRの下で落ちている8ビットのマイクロコントローラです.avrはマイクロチップ技術によって1996年以来開発されたマイクロコントローラのファミリーである.あなたがそれについてもっと読みたいならば、ここで頭を進めてくださいAVR-Rust book
その簡単な歴史を脇に、それを取得しましょう!
我々は、LEDを点滅させているArduinoのHello Worldをします.それは非常に簡単な運動だが、初心者として学ぶことがたくさんあります.
まず、実行して新しい貨物プロジェクトを作成します.
このために、依存している木枠のいくつかが不安定な特徴を使用するので、毎晩のツールチェーンに切り替える必要があります.それで実行します.
次に必要なパッケージをインストールします.
私はアーチのLinuxのディストリビューション
で、
それらのありがとうRahix これを一緒に置くために.
また、AVRターゲット用のカーゴのメタデータをビルドする必要があります.ファイルを作成します
依存関係を除いて、下にコードを加えましょう
(クイックヒント:あなたは走ることができます
我々は、その機能を持っていない埋め込まれた環境にあるstandard library crate さびのヒープ割り当てAPI、スレッド、ネットワークAPIなどに依存するので、我々は
次に
標準ライブラリでは、定義された動作があります.しかしながら、標準ライブラリのないプログラムでは、パニックになっている動作は未定義です.振舞いは、Councho\[ PanicHunler ]関数を宣言することで選択できます.ソース:[ソース]embedded rust book ]
動きましょう:
関数が返すことのないNone型.
LEDを点滅させるには、いくつかのコードラインを必要とし、関連するピンをハイまたはローに設定します.UNOでATMEGA 328 Pチップのピンダイアグラムを見てみましょう.
上の図では、マイクロコントローラ上の様々なピンに気づくことができます.ほとんどのマイクロコントローラは、すべてでなければ、デバイスが外部回路にデジタル値を読み書きすることを可能にするピンを含む.それらのうちのいくつかはI/Oポートに分類されます.
ポートは標準インターフェイスを表すピンのグループです.これらのポートはポートレジスタによって制御されます.これは我々のコードで変更できる特殊バイト変数として考えられます.
ATMEGA 328 Pの場合、3つのポートレジスタがあります. アナログピン0〜5用 デジタルピン0〜7 デジタルピン8〜13用 詳細はこちらPort Manipulation
UNOを見れば、ビルトインLEDに接続されたデジタルピン13があります.
我々は、LEDを操作するために、すなわち、それをハイまたはローに設定するために、我々のコードのピンへのアクセスを必要とします.
より多くのコードを加えましょう:
まず、インスタンスを作成します
周辺機器は、外部デバイス、センサーなどを使用してチップ/CPUとの通信をブリッジするデバイスです.
周辺機器の例は、あなたのタイマー、カウンタ、シリアルポートなどです.
組込プロセッサは、一連の制御およびステータスレジスタを経て周辺機器と相互作用する.
次に、新しい
次に変数を定義する
DDRレジスタは、特定のポートのピンが入力か出力かどうか決定します.DDRレジスタは8ビット長であり、各ビットはそのI/Oポート上のピンに対応する.例えば、DDRBの第1ビット(ビット0)は、PB 0が入力または出力であるかを判定し、一方、最後のビット(ビット7)は、PB 7が入力または出力であるかどうかを判定する.私はまだ完全にDDRレジスタを理解するためにもう少し読む必要があります.
次に、我々は
と回数
こちらが
以下は完全なコードです.
さびを実行しているArduinoの我々の最初のまばたきプログラム!
アクセス許可時にアクセス許可が拒否された場合
シリアルインタフェースにアクセスできるLinuxユーザグループに.
まず、グループを使用します.
私はいくつかの埋め込まれた趣味プロジェクトを計画している、私は彼らが進行中として将来的にそれらについて書きます.ここではGithub 上記のコードのために.
あなたがさびた埋め込まれたスペースの開発において最新に続くことを望むならばembedded rust working group
次回まで!
これを書くとき、およそ1ヵ月前、さびAVRフォークは合併されましたupstream . これは、今すぐ実行することによって、AVR MicroControllerボードのための錆プログラムをコンパイルすることができることを意味します
cargo +nightly build
, 提供する.cargo/config.toml
あなたの目標avr-unknown-unknown
). それは巨大です!私は常に物理オブジェクトを操作して、影響を与えるためにコードを使うという考えに魅了されました.これはおそらくArduinoと多分ESP 8266と発見F 3の上でさびによる私の冒険のブログ記事のシリーズであるでしょう.(私はこれらも同様に嘘をついています).この最初のポストでシリーズから離れてキックオフ.
ターゲットオーディエンス:このポストは、Arduinoで錆に埋め込まれたシステムとのヘッドスタートを望む心の中で初心者に初心者で書かれています.一旦このポストを終えたならば、あなたは基本を通してembedded rust book . ポストのコードはLinuxマシン( arch linux )でコンパイルされています.
rustc 1.47.0-nightly (22ee68dc5 2020-08-05)
.我々はArduino Unoの上でさびを走らせる方法に関する旋風旅行をします.そして、それはおそらく最も有名で、ホビイスト組込みのドメインで開発ボードを使用しました.The Arduino Uno ATVGA 328 Pに基づきます.そして、それは家族AVRの下で落ちている8ビットのマイクロコントローラです.avrはマイクロチップ技術によって1996年以来開発されたマイクロコントローラのファミリーである.あなたがそれについてもっと読みたいならば、ここで頭を進めてくださいAVR-Rust book
その簡単な歴史を脇に、それを取得しましょう!
我々は、LEDを点滅させているArduinoのHello Worldをします.それは非常に簡単な運動だが、初心者として学ぶことがたくさんあります.
プロジェクトの設定
まず、実行して新しい貨物プロジェクトを作成します.
cargo new rust-arduino-blink
AVRターゲット(ターゲットトリプル)のプロジェクトをクロスコンパイルする必要があります.avr-unknown-unknown
).このために、依存している木枠のいくつかが不安定な特徴を使用するので、毎晩のツールチェーンに切り替える必要があります.それで実行します.
rustup override set nightly
上記のコマンドは、現在のディレクトリだけを選択するためのツールチェーンを毎晩上書きします.次に必要なパッケージをインストールします.
pacman -S avr-gcc
The avr-gcc
パッケージはリンカを使用する必要があります.pacman -S arduino-avr-core
The arduino-avr-core
パッケージにはavrdude マイクロプロセッサのROMとEEPROMの内容をアップロードし,操作するツールである.私はアーチのLinuxのディストリビューション
pacman
パッケージマネージャーです.で、
Cargo.toml
次の依存関係を追加します.[dependencies]
# A panic handler is needed. This is a crate with the most basic one.
panic-halt = "0.2.0"
[dependencies.arduino-uno]
git = "https://github.com/Rahix/avr-hal"
rev = "536c5d"
avr-hal
ボードによって分離された木箱の束を含むカーゴワークスペースですarduino-uno
クレートは一つそれらのありがとうRahix これを一緒に置くために.
また、AVRターゲット用のカーゴのメタデータをビルドする必要があります.ファイルを作成します
avr-atmega328p
プロジェクトのルートで次のコンテンツを入力します.{
"llvm-target": "avr-unknown-unknown",
"cpu": "atmega328p",
"target-endian": "little",
"target-pointer-width": "16",
"target-c-int-width": "16",
"os": "unknown",
"target-env": "",
"target-vendor": "unknown",
"arch": "avr",
"data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",
"executables": true,
"linker": "avr-gcc",
"linker-flavor": "gcc",
"pre-link-args": {
"gcc": ["-Os", "-mmcu=atmega328p"]
},
"exe-suffix": ".elf",
"post-link-args": {
"gcc": ["-Wl,--gc-sections"]
},
"singlethread": false,
"no-builtins": false,
"no-default-libraries": false,
"eh-frame-header": false
}
で参照.cargo/config.toml
:[build]
target = "avr-atmega328p.json"
[unstable]
build-std = ["core"]
これにより、ビルドの設定が完了します.コードを書きましょう
依存関係を除いて、下にコードを加えましょう
main.rs
そして、それを段階的に進めます.(クイックヒント:あなたは走ることができます
cargo doc --open
あなたのディレクトリには、このプロジェクトのドキュメントを用意します.// main.rs
#![no_std]
#![no_main]
まず、いくつかのグローバル属性を指定する必要があります.コンパイラは、異なる環境にあることを知っています.我々は、その機能を持っていない埋め込まれた環境にあるstandard library crate さびのヒープ割り当てAPI、スレッド、ネットワークAPIなどに依存するので、我々は
#[no_std]
属性は上部にある.また、デフォルトのエントリポイントをオーバーライドする必要がありますfn main()
) 使用#[no_main]
プログラムに自分のエントリポイントを提供し、定義することになるからです.エントリポイントを定義するには、arduino_uno
crateカスタムエントリポイントを定義します.通常使用するボードの枠は、あなたにエントリマクロを提供します.次に
use
必要な項目をスコープ内の依存するcratesから取得するステートメント.extern crate panic_halt;
use arduino_uno::prelude::*;
use arduino_uno::hal::port::portb::PB5;
use arduino_uno::hal::port::mode::Output;
注意panic_halt
クレート?パニックハンドラが必要です.標準ライブラリでは、定義された動作があります.しかしながら、標準ライブラリのないプログラムでは、パニックになっている動作は未定義です.振舞いは、Councho\[ PanicHunler ]関数を宣言することで選択できます.ソース:[ソース]embedded rust book ]
動きましょう:
#[arduino_uno::entry]
fn main() -> ! {
}
それから私たちはmain
関数はentry
属性マクロarduino_uno
クレート.The !
is関数が返すことのないNone型.
LEDを点滅させるには、いくつかのコードラインを必要とし、関連するピンをハイまたはローに設定します.UNOでATMEGA 328 Pチップのピンダイアグラムを見てみましょう.
上の図では、マイクロコントローラ上の様々なピンに気づくことができます.ほとんどのマイクロコントローラは、すべてでなければ、デバイスが外部回路にデジタル値を読み書きすることを可能にするピンを含む.それらのうちのいくつかはI/Oポートに分類されます.
ポートは標準インターフェイスを表すピンのグループです.これらのポートはポートレジスタによって制御されます.これは我々のコードで変更できる特殊バイト変数として考えられます.
ATMEGA 328 Pの場合、3つのポートレジスタがあります.
UNOを見れば、ビルトインLEDに接続されたデジタルピン13があります.
我々は、LEDを操作するために、すなわち、それをハイまたはローに設定するために、我々のコードのピンへのアクセスを必要とします.
より多くのコードを加えましょう:
#[arduino_uno::entry]
fn main() -> ! {
let peripherals = arduino_uno::Peripherals::take().unwrap();
let mut pins = arduino_uno::Pins::new(
peripherals.PORTB,
peripherals.PORTC,
peripherals.PORTD,
);
let mut led = pins.d13.into_output(&mut pins.ddr);
loop {
stutter_blink(&mut led, 25);
}
}
上のコードで多くのことが起こっている!まず、インスタンスを作成します
Peripheral
UNOのすべての周辺機器のリストです.周辺機器は、外部デバイス、センサーなどを使用してチップ/CPUとの通信をブリッジするデバイスです.
周辺機器の例は、あなたのタイマー、カウンタ、シリアルポートなどです.
組込プロセッサは、一連の制御およびステータスレジスタを経て周辺機器と相互作用する.
次に、新しい
Pin
周辺インスタンスからのポートでのインスタンス渡しperipherals
.次に変数を定義する
led
それは、LEDが接続されているピン番号を保持します.これは出力ピンとしてピン13を設定することによって作成されますinto_output
メソッドd13
ピンと私たちへの変な参照で渡すddr
レジスタ.DDRレジスタは、特定のポートのピンが入力か出力かどうか決定します.DDRレジスタは8ビット長であり、各ビットはそのI/Oポート上のピンに対応する.例えば、DDRBの第1ビット(ビット0)は、PB 0が入力または出力であるかを判定し、一方、最後のビット(ビット7)は、PB 7が入力または出力であるかどうかを判定する.私はまだ完全にDDRレジスタを理解するためにもう少し読む必要があります.
次に、我々は
loop {}
呼び出しstutter_blink
関数は、我々のled
インスタンスと回数
25
) 我々が瞬きたいです.こちらが
stutter_blink
関数定義fn stutter_blink(led: &mut PB5<Output>, times: usize) {
(0..times).map(|i| i * 10).for_each(|i| {
led.toggle().void_unwrap();
arduino_uno::delay_ms(i as u16);
});
}
私たちがStutterSoundsブリンクで行うすべては、LEDの上の呼び出しトグルであり、続いてArduinoCount UNOモジュールからdelaylose ms呼び出しをします.これはすべてイテレータで行います.私たちは漸近的にLEDトグルを目立つ量で遅らせることができるように、範囲(0 . times .)をマップしてあとに続きます.私たちは確実にforループを使用してこれを行うことができました、そして、それはより読みやすいです、しかし、私は我々がさびからすべての高いレベルAPIと抽象を使うことができるということを証明したかったです.私たちは、抽象化がゼロコストである組み込みシステムのための機能コードを書いています.それは私が知っている限り錆だけで可能なことです!以下は完全なコードです.
// main.rs
#![no_std]
#![no_main]
extern crate panic_halt;
use arduino_uno::prelude::*;
use arduino_uno::hal::port::portb::PB5;
use arduino_uno::hal::port::mode::Output;
fn stutter_blink(led: &mut PB5<Output>, times: usize) {
(0..times).map(|i| i * 10).for_each(|i| {
led.toggle().void_unwrap();
arduino_uno::delay_ms(i as u16);
});
}
#[arduino_uno::entry]
fn main() -> ! {
let peripherals = arduino_uno::Peripherals::take().unwrap();
let mut pins = arduino_uno::Pins::new(
peripherals.PORTB,
peripherals.PORTC,
peripherals.PORTD,
);
let mut led = pins.d13.into_output(&mut pins.ddr);
loop {
stutter_blink(&mut led, 25);
}
}
この木箱を作りましょう.cargo build
すべてがうまくいくなら、ELFファイルを見るべきですrust-arduino-blink.elf
生成下target/avr-atmega328p/debug/
ディレクトリ.それは私たちのウノにフラッシュする必要がバイナリです.ELFファイルをフラッシュするにはavrdude
ユーティリティ.ルートディレクトリにスクリプトを作りましょうflash.sh
それでcargo build
私たちの宇野を点滅させた後で#! /usr/bin/zsh
set -e
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
echo "usage: $0 <path-to-binary.elf>" >&2
exit 1
fi
if [ "$#" -lt 1 ]; then
echo "$0: Expecting a .elf file" >&2
exit 1
fi
sudo -u creativcoder cargo build
avrdude -q -C/etc/avrdude.conf -patmega328p -carduino -P/dev/ttyACM0 -D "-Uflash:w:$1:e"
これにより、実行できます( UNOがUSBケーブル経由で接続されているか確認してください)../flash.sh target/avr-atmega328p/debug/rust-arduino-blink.elf
そこに行くさびを実行しているArduinoの我々の最初のまばたきプログラム!
アクセス許可時にアクセス許可が拒否された場合
/dev/ttyACM0
. ユーザーを追加する必要がありますシリアルインタフェースにアクセスできるLinuxユーザグループに.
まず、グループを使用します.
ls -l /dev/ttyACM0
私のマシンで次の出力を得るcrw-rw---- 1 root uucp 166, 0 Aug 19 03:29 /dev/ttyACM0
ユーザー名をuucp
グループを実行します.sudo usermod -a -G uucp creativcoder
提案/コメント/訂正最も歓迎します.私はいくつかの埋め込まれた趣味プロジェクトを計画している、私は彼らが進行中として将来的にそれらについて書きます.ここではGithub 上記のコードのために.
あなたがさびた埋め込まれたスペースの開発において最新に続くことを望むならばembedded rust working group
次回まで!
Reference
この問題について(Arduinoの上でさびを走らせる方法), 我々は、より多くの情報をここで見つけました https://dev.to/creativcoder/how-to-run-rust-on-arduino-uno-40c0テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol