Renodeお試し

シミュレータ Renode を試してみる

概要

おいそれと評価ボードを買えないボンビーの味方、シミュレータ(エミュレータ)。
QEMUが有名だけど、 最近はRenodeというのもあるらしい。

[!NOTE] wokwiというのもある。
見た目がきれいで惹かれるけど、VScodeで実行する環境のライセンスが よく分からんかった(30日は無料らしいけど、その後無料で更新できるのか、有料になるのか読み取れなかった)
至れり尽くせりなのはイヤだという天邪鬼気質もあるけど…

ということで、Renodeをちらっと試してみた時のメモ。

Renodeのドキュメントはhttps://renode.readthedocs.io/en/latest/にあります
ソースやリリースバイナリはGithubにあります。

準備

環境

今回はWindows11上のWSLのUbuntu 22.04で試してみます。

Renodeのインストール

インストール用バイナリはgithubhttps://builds.renode.ioにあります。

プラットフォームはmono版と.NET版がありますが、ここではmono版を使います。
debファイルがあるので、aptでもインストールできますが、ここではポータブル版を使います。

以下のように実行します。

cd /proj
wget https://builds.renode.io/renode-latest.linux-portable.tar.gz
mkdir renode_portable
tar xvf  renode-latest.linux-portable.tar.gz -C renode_portable --strip-components=1

これで /proj/renode_portable に必要なファイルが展開されます。
ここにPATHを通すため、~/.bashrcに以下を追加します。

# renodeのインストール先をpathに追加
export PATH=/proj/renode_portable:$PATH

renodeの依存パッケージのインストール

sudo apt install mono-devel policykit-1 libgtk2.0-0 screen uml-utilities gtk-sharp2 libc6-dev libicu-dev gcc python3 python3-pip

[!NOTE] monoのリポジトリを追加してインストールする情報が散見されるが、ubuntu22.04のaptリポジトリにはmono-develも入っているらしい。
なので、普通にapt installだけでインストールできる。
ただし、最新版が欲しい場合は以下でインストールする。

sudo apt install ca-certificates gnupg
sudo gpg --homedir /tmp --no-default-keyring --keyring /usr/share/keyrings/mono-official-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb [signed-by=/usr/share/keyrings/mono-official-archive-keyring.gpg] https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
sudo apt update
sudo apt install mono-devel

gccのインストール

Renodeの実行自体にコンパイラは不要ですが、実行するバイナリを作成するのに必要なので、gccをインストールします。

ダウンロードサイト:ARM Developer GNU Arm Embedded Toolchain Downloads

以下の手順でインストールします(ファイル名/ディレクトリ名はダウンロードしたバージョンに合わせて変更)。

cd /proj
wget https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi.tar.xz
tar xvf arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi.tar.xz 

# 依存パッケージのインストール
sudo apt install libncursesw5

PATHを通すため、~/.bashrcに以下を追加

# arm-gccのインストール先をpathに追加
export PATH=/proj/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi/bin:$PATH

[!NOTE] コンパイラだけならapt install gcc-arm-none-eabiでインストールできますが、 gdbが入ってないので上のサイトからダウンロードして使用します。

その他インストール

ターゲットプログラムのbuild時にcmakeも使用するのでインストールしておきます。

sudo apt install cmake

デモの実行

ドキュメントのRunning your first demo にしたがって実行してみます。

renodeを起動します。

renode

renodeウィンドウが開くのでそこで以下を入力

s @scripts/single-node/stm32f4_discovery.resc

[!NOTE]

i @scripts/single-node/stm32f4_discovery.resc
s

と実行しても可。
iincludeのalias
sstartのalias

[!NOTE] renode起動時に以下のようにパラメータとしてrescファイルを指定することもできます。
これはincludeコマンドを実行するのと同義(というか起動時にincludeコマンドが実行されている)。

renode /proj/renode_portable/scripts/single-node/stm32f4_discovery.resc

rescファイルのパスは絶対パス/カレントディレクトリからの相対パスで指定可能。
@を使ったrenodeインストールディレクトリからの相対パスは指定不可。

プログラムが実行されると uart4ウィンドウが開いてなにやら色々表示されます。

renodeウィンドウでquitと入力する(CTRL+Dでも可)と終了します。

おまけ

その1

renodeウィンドウが見難かったら以下のように-Pオプションでポート番号を指定して実行し、

renode -P 1234

他のターミナルから以下のように実行すると普段使っているターミナルから制御できます。

telnet localhost 1234

その2

renode起動時に--console オプションを指定すると、起動したターミナルがコンソールになります。

renode --cnsole

ログが同じターミナルに表示されるので見難くなったりするかもしれんけど

VScodeでデバッグ

ドキュメント の説明は分かり難いので、解説記事 Getting Started with STM32F4 Emulation using Renode の手順を試してみます。

サンプルのリポジトリをclone

まずはリポジトリをcloneします。
適当なディレクトリで以下のコマンドを実行します。

git clone https://github.com/PhanCuong91/data.git

とりあえず動作確認

VScodeでデバッグする前にターゲットプログラムのbuildが行えるか、 buildしたバイナリが実行できるか確認しておきます。
プログラムのbuildは以下のコマンドで行います。

cd data/renode
bash build.bat

[!NOTE] batファイルなので、Windowsのバッチファイルですが、 中身はLinuxでもそのまま実行できる内容なので、 そのままシェルスクリプトとして実行します。

こんな感じでbuildが実行されます。

Release build.
-- The C compiler identification is GNU 13.3.1
-- The CXX compiler identification is GNU 13.3.1
-- The ASM compiler identification is GNU
-- Found assembler: /proj/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /proj/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /proj/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /work/data/renode/build

正常にbuildできていればbuild/src/STM32F4Template.elfが出来ています。

renodeを実行し、renodeターミナルで以下のように入力し、プログラムを実行します。

mach create
machine LoadPlatformDescription @platforms/boards/stm32f4_discovery-kit.repl
sysbus LoadELF @/work/data/renode/build/src/STM32F4Template.elf 
showAnalyzer sysbus.usart2
start

UART2ウィンドウに以下のように表示されればOK。

Hello World!

確認したらrenodeを終了します。

次の作業に備えて、buildディレクトリを削除(またはrename)しておきます。

VScodeでのデバッグ

rescファイルの修正

フルパスで記述されている部分を修正します。

修正内容は以下。
$ORIGINを使用してrescファイルからの相対パス指定に変更。
これにより、ダブルクォーテーションで囲む必要はなくなる。

diff --git a/renode/renode-config.resc b/renode/renode-config.resc
index 2729cd1..fcb4f34 100644
--- a/renode/renode-config.resc
+++ b/renode/renode-config.resc
@@ -2,8 +2,8 @@
 :description: This script runs the usart_printf example on stm32f4 discovery

 $name?="STM32F4_Discovery"
-$cmm_repl?="C:\working\data\renode\add-ccm.repl"
-$bin_path?="C:\working\data\renode\build\src\STM32F4Template.elf"
+$cmm_repl?=$ORIGIN/add-ccm.repl
+$bin_path?=$ORIGIN/build/src/STM32F4Template.elf

 # create Socket Terminal for UART
 emulation CreateServerSocketTerminal 3456 "term" false

buildスクリプトに実行属性を付与

元がwindows用なので、linuxで実行できるように実行属性を付与します。
中身はそのまま。

chmod +x build-debug.bat

VScodeを起動

ホストOS側のVScodeを起動します。
WSLなので、ターミナルから以下のコマンドで起動してカレントディレクトリを開きます。

code .

VScodeの拡張機能のインストール

VScodeの拡張機能で

実行

エクスプローラサイドパネルからsrc/main.cを開き、main() のどこかにブレークポイントを設定。
デバッグサイドパネルで 「Debug application in Renode」 を選んで実行。
RenoteターミナルとUART2ウィンドウが開き、設定したブレークポイントで停止するはず。
実行を再開すると、UART2ウィンドウにHello World!と表示され、無限ループに入る。

Renode interactive visualization example

組み込みプログラムなので、ターゲットボードの動作を目で見たくなるのが人情…
ということで、Renode interactive visualization exampleを実行してみます。

[!NOTE] WSLのネットワークモードは mirrored にしておきます (ほかのモードでも動くかもしれんけど、試してないので)

github からソースを取得します。

git clone https://github.com/antmicro/renode-board-visualization.git
cd renode-board-visualization/

Renodeを実行します。
(バイナリファイルがあるのでbuildは不要。というよりソースファイルはない)

renode scripts/blinky.resc

rescファイルにstartコマンドが書いてあるので、 起動と同時にターゲットプログラムが実行されます。

renodeを起動したターミナルにはGPIOアクセスのログが以下のように表示されます。
(ログが表示されるか否かはPeripheralのエミュレーションプログラムによるので、 どのCPUても表示されるわけではありません)

11:28:31.6894 [NOISY] gpio0: Setting pin 24 output to False
11:28:32.6891 [NOISY] gpio0: Setting pin 24 output to True
11:28:33.6891 [NOISY] gpio0: Setting pin 24 output to False
11:28:34.6892 [NOISY] gpio0: Setting pin 24 output to True
11:28:35.6892 [NOISY] gpio0: Setting pin 24 output to False

renodeコンソールで以下のコマンドを実行します。
これによりWebサーバが起動します。

serveVisualization 8000

ブラウザで 起動したWebサーバ(localhost:8000) にアクセスします。
ページが表示され、ボード左上のLED(赤色)が点滅しているのが確認できます。

Webサーバを停止するため、renodeコンソールで以下のコマンドを実行します。

stopVisualization

Renodeを終了します。

[!NOTE] Webサーバを停止せずにRenodeを終了しても構いません。
停止せずに終了すると終了時に python で たくさんEXCEPTIONが起こるので 気持ち悪い人はWebサーバを停止してから終了しましょう。

自分の環境を作ってみた

以上を踏まえて、一通り作ってみました。
(公式サンプルにはターゲットプログラムのソースがないので、 ソースからビルドする部分も含めて試してみたかった)

作った環境はgithubに登録しておきました。
https://github.com/ippei8jp/renode_my_sample

リポジトリのクローン

git clone https://github.com/ippei8jp/renode_my_sample.git
cd renode_my_sample

ソース構成

srcディレクトリ下がプログラムソースです。

main.c

メインルーチンと割り込みハンドラなど。

syscalls.c

printf/scanfなどを使用するためのsyscallルーチンを定義。
コンソール入出力のための最低限の処理だけを定義しています。

startup_stm32f40_41xxx.s

bootルーチン、ベクタテーブル、デフォルト割り込みハンドラなど。

system_stm32f4xx.c

初期化処理(C言語部)

CMakeLists.txt

cmake処理定義ファイル。
ソースファイルを追加したときなどはここに追加していく。

ビルド&実行

mkdir build && cd build
cmake ..
make
cd ..
renode script/renode-config.resc

ブラウザで接続

GUI部品を表示するため、ブラウザで 起動したWebサーバ(localhost:8000) にアクセスします。
ページにLEDとスイッチが表示されます。

ターゲットプログラム実行

renodeターミナルでstartコマンドを実行するとターゲットプログラムが実行されます。

ブラウザの表示

ターゲットプログラムの動作に応じてLEDが順次点灯/消灯していきます。 スイッチをクリックするとON/OFFがトグルします。
このスイッチの情報はターゲットプログラムのメインループで表示されます。
またON時は割り込みハンドラが起動され、UARTコンソールに割り込みメッセージが表示されます。

Renode終了

renodeターミナルでquitコマンドを実行して Renodeを終了します。

VScodeでデバッグ

VScodeでデバッグする前にbuildディレクトリを削除しておいてください。

VScodeでcloneしたディレクトリを開く

code .

ビルド

VSCodeで

ブラウザで接続

GUI部品を表示するため、ブラウザで 起動したWebサーバ(localhost:8000) にアクセスします。
ページにLEDとスイッチが表示されます。

ブラウザの表示

ターゲットプログラムの動作に応じてLEDが順次点灯/消灯していきます。 スイッチをクリックするとON/OFFがトグルします。
このスイッチの情報はターゲットプログラムのメインループで表示されます。
またON時は割り込みハンドラが起動され、UARTコンソールに割り込みメッセージが表示されます。

デバッグ

デバッグは他の環境と同じなので、ここでは何も書きません。