2017年12月9日土曜日

Rustで書かれたArduinoのプログラムをビルドしてLチカする方法


注意

2020.08.02追記
AVR-RustがRust本家に取り込まれたことにより関連ライブラリをインストールすればAVR-Rustの環境を整えられるようになったため、今から取り組む場合は下記の新しい設定方法の解説記事やAVR-Rust本家の資料を参考にして、環境を整えるのが良いと思います。

2020版: RustのArduino向けプログラムでLチカする方法

この記事の内容は古くなってしまいましたが、古い手順が参考になるときがあるかもしれないため、消さずに残します。

背景

スパコンを作っている会社の中の方の記事を読んで、RustとLLVMに興味がわきました。

Rustとは速度、安全性、並行性を重視した、(C++の代替として使われることを想定して開発されている?)プログラミング言語です。
LLVMとは、コンパイラのツールチェーンを管理するために開発されているプロジェクトです。

LLVMについて調べていたら、Arduinoに使われているAVRのプロセッサがLLVMでサポートされていることが分かりました。
さらに調べてみると、LLVMを利用しているavr-rustを使えば、RustでArduinoのプログラムを書けることが分かりました。
調べながら試してみたところ、Arduino UnoとNanoでLチカ(LEDを点滅させること)に成功しました。

備忘録を兼ねてLチカまでの手順をざっくりと共有します。

全体像

  1. 使ったもの
  2. Rustをインストール
  3. avr-rust/rustをインストール
  4. ビルドとアップロードに必要なプログラムをインストール
  5. blinkプログラムのダウンロード
  6. blinkプログラムのビルドとアップロード
  7. まとめ
  8. 参考

使ったもの

PC

この記事の内容はUbuntu17.10で動作することを確認しました。

atmega328pが載っているArduino

下記のArduinoで動作することを確認しました。

Arduinoとして動いているatmega328pであれば、Arduino IDEでプログラムをアップロードする時のように、USBでPCと接続すればRustのコードから作ったファイルをアップロードできます。

Arduinoのブートローダーが書き込まれていないatmega32uを使って記事の内容を実施したい方は、LチカしたいAVRマイコン以外にプログラムを書き込むための装置が必要です。
また、hexファイルアップロード時のコマンドも記事の内容とは若干異なります。
この記事ではその説明はしませんが、そういうことがしたい場合はSparkFunさんのこの記事(Installing an Arduino Bootloader)が参考になると思います。

Rustをインストール

Rustのインストールドキュメントに従い、下記のコマンドでインストールしました。
curl https://sh.rustup.rs -sSf | sh

avr-rustをインストール

avr-rustのreadmeを参考にしつつ、下記のコマンドでgitpojects/avr-rust/rustに関連ファイルを配置しつつ、ビルドしてインストールしました。
# ディレクトリを作って、その中に移動します
mkdir -p ~/gitprojects/avr-rust
cd ~/gitprojects/avr-rust

# ダウンロードして初期設定を行います。30分くらいかかりました
git clone https://github.com/avr-rust/rust.git
cd rust
mkdir build && cd build
../rust/configure \
  --enable-debug \
  --disable-docs \
  --enable-llvm-assertions \
  --enable-debug-assertions \
  --enable-optimize \
  --prefix=/opt/avr-rust

# 2時間くらいかかりました
make

# sudoを付けてmake installしようとするとエラーが出るので、sudo無しで実行できるようにローカルユーザーでも操作できるインストール先のディレクトリを作りました
sudo mkdir /opt/avr-rust
sudo chown ${USER} /opt/avr-rust

# インストールします
make install

# rustにavr-toolchainを追加します
rustup toolchain link avr-toolchain $(realpath $(find . -name 'stage1'))

ビルドとアップロードに必要なプログラムをインストール

avrマイコン向けのビルドやファイルアップロードに必要なプログラムを下記のコマンドでインストールしました。
sudo apt install avr-gcc avr-libc avrdude

また、次の手順でダウンロードするavr-rustのblinkプログラムは、(あまり良くわかっていないですが)xargoというstdライブラリ無しでRustのビルドを実行するためのライブラリを使っているので、そちらもインストールしておきます。
cargo install xargo

blinkプログラムのダウンロード

下記のコマンドで、~/gitprojects/avr-rust/blinkにLチカのためのサンプルプログラムをダウンロードしました。
cd ~/gitprojects/avr-rust
git clone https://github.com/avr-rust/blink.git

Lチカの動作を記述しているRustのコードは~/gitprojects/avr-rust/blink/src/main.rsにあります。

blinkプログラムのビルドとアップロード

下記のコマンドでatmega328p向けのhexファイルを作ります。
# Lチカプログラムのディレクトリに移動します
cd ~/gitprojects/avr-rust/blink

# Rustをelfファイルにビルドします
XARGO_RUST_SRC=/opt/avr-rust rustup run avr-toolchain xargo build --target avr-atmega328p --release

# elfファイルがあるディレクトリに移動します
cd target/avr-atmega328p/release

# elfファイルをhexファイルに変換します
avr-objcopy -O ihex -R .eeprom blink.elf blink.hex

hexファイルのアップロードはUnoとNanoで通信速度が異なります。
ポート名も異なりますが、環境によって異なると思うので、適宜変更してください。

Unoには115200bpsでアップロードできます。
avrdude -p m328p -P /dev/ttyACM0 -c arduino -b 115200 -U flash:w:blink.hex

静止画では分からない、Lチカの様子をご覧ください。


Nanoには57600bpsでアップロードできます。
avrdude -p m328p -P /dev/ttyUSB0 -c arduino -b 57600 -U flash:w:blink.hex

静止画では分からないLチカの様子を再びご覧ください。


まとめ

Rustで書かれたLチカプログラムをatmega328uが載っているArduinoで実行できました。

LLVMのデバイスリストに載っているAVRのプロセッサならビルドできても良さそうな気がしますが、avr-rust/arduinoのreadmeに「Arduino Uno向け」と書かれているので、の今の所atmega328pだけのサポートに留まっているようです。
個人的にPro Microを良く使うため、atmega32u4向けのビルドと実行に成功した方が居れば、情報共有していただけるととても嬉しいです。

参考

Programming an AVR Microcontroller
Programming Arduino Nano with avrdude

更新履歴

2018.11.11
chownとしたいところがchmodになっていたので、修正しました。
2020.08.02
2020版の設定方法に関する情報をページ先頭に注意として追加しました。
タイトル画像を2020年区別がつくように、2017の文字が入っているものに変更しました。

0 件のコメント :