Ryuz's tech blog

FPGAなどの技術ブログ

RustでRTOSを作ってみる試み

はじめに

組込みRustの勉強ついでに RTOS(リアルタイムOS)っぽいものを作ってみようと試みたちょっとしたサンプル的なものです。

以前の記事の後、放置状態だったのですが、今回簡単なサンプルだけ動くようにして crates.io にも登録したので続編となります。

本命はこれとは別に進めているFPGARTOSの方なのですが、FPGA版からも一部クレートを流用している関係で、先にこちらを整理した方が良さそうに感じていったん整理したというものです。

主なターゲットはZynqMP の RPU(Cortex-R5) となります。FPGA版と異なり、CPUのみで動作します。

リポジトリhttps://github.com/ryuz/pudding-rtos にあります。

本記事では Ultra96V2 でサンプルを試す流れを解説します。

環境準備

環境

Ultra96V2などの ZynqMP 環境でAPU(Cortex-R5)上で、Debianなどが動く状態になっており、APUからRPUを認識できるようになっている想定です。

今回、サンプルの出力を UART から行う為、結果を確認するにはAES-ACC-U96-JTAGなどのUARTが取り出せる治具が必要です。

なお、今回ビルドもUltra96のAPU(Cortex-A53のLinux)で行ってしまう想定ですが、コンパイル自体はPCなどの別環境でも可能です。

Rust インストール

https://www.rust-lang.org/ja/tools/install

に従ってインストールください

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

のような感じになるかと思います。

ロスコンパイラ準備

下記のような感じでUltra96V2 の Debian 上でクロスコンパイラを準備ください。

sudo apt install gcc-arm-none-eabi
sudo apt install libnewlib-arm-none-eabi

APU(Cortex-A53)の上で動くLinux から、RPU(Cortex-R5)用のプログラムをコンパイルできるようになります。

Rustの準備

下記のように Rust 側も準備します。

rustup update
rustup install nightly
rustup default nightly

rustup target add armv7r-none-eabi
cargo install cargo-binutils
rustup component add llvm-tools-preview

サンプルの試し方

次にサンプルの動かし方です。

ビルド方法

まず Ultra96 の Debian上にて、下記のようにリポジトリを取得します。

git clone https://github.com/ryuz/pudding-rtos.git
cd pudding-rtos

なお、この記事を執筆時点のバージョンが欲しい場合は

git checkout ab178c483981f819fbf2d3e10dfa3bcafea36953

とすれば取得できます。

次にサンプルのディレクトリで

cd samples/zynqmp_rpu_hello
make

とすればビルド出来ます。

cargo build

でもよいのですが、この後のCortex-R5へのコードのダウンロードなどを Makefile で記述しているので Makefile 経由としています。

実行方法

実行するには

make run

とすれば動き始め、UART1 に出力を行い、TeraTerm などでUARTを覗くと、下記のような出力が観測できます。

UART出力の様子

いわゆる食事する哲学者の問題 を見たてて、5つのタスクがセマフォをランダムに取り合いながら、考えたりおなかをすかしたりしながら動きます。

おわりに

今回の動作に関わるクレートは下記の2つです。

まだドキュメントその他さっぱりですが、余裕があれば少しづつ整備したいと思います。

主に、pac の方を FPGA版RTOSで引用するのにクレート登録したかったというのが、今回の整備の最大の動機だった気がします。