シミュレータ Renode を試してみる
おいそれと評価ボードを買えないボンビーの味方、シミュレータ(エミュレータ)。
QEMUが有名だけど、
最近はRenodeというのもあるらしい。
[!NOTE] wokwiというのもある。
見た目がきれいで惹かれるけど、VScodeで実行する環境のライセンスが よく分からんかった(30日は無料らしいけど、その後無料で更新できるのか、有料になるのか読み取れなかった)
至れり尽くせりなのはイヤだという天邪鬼気質もあるけど…
ということで、Renodeをちらっと試してみた時のメモ。
Renodeのドキュメントはhttps://renode.readthedocs.io/en/latest/にあります
ソースやリリースバイナリはGithubにあります。
今回はWindows11上のWSLのUbuntu 22.04で試してみます。
インストール用バイナリはgithub やhttps://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
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
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と実行しても可。
iはincludeのalias
sはstartのalias
[!NOTE] renode起動時に以下のようにパラメータとしてrescファイルを指定することもできます。
これはincludeコマンドを実行するのと同義(というか起動時にincludeコマンドが実行されている)。renode /proj/renode_portable/scripts/single-node/stm32f4_discovery.rescrescファイルのパスは絶対パス/カレントディレクトリからの相対パスで指定可能。
@を使ったrenodeインストールディレクトリからの相対パスは指定不可。
プログラムが実行されると uart4ウィンドウが開いてなにやら色々表示されます。
renodeウィンドウでquitと入力する(CTRL+Dでも可)と終了します。
renodeウィンドウが見難かったら以下のように-Pオプションでポート番号を指定して実行し、
renode -P 1234
他のターミナルから以下のように実行すると普段使っているターミナルから制御できます。
telnet localhost 1234
renode起動時に--console オプションを指定すると、起動したターミナルがコンソールになります。
renode --cnsole
ログが同じターミナルに表示されるので見難くなったりするかもしれんけど
ドキュメント の説明は分かり難いので、解説記事 Getting Started with STM32F4 Emulation using Renode の手順を試してみます。
まずはリポジトリを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)しておきます。
フルパスで記述されている部分を修正します。
修正内容は以下。
$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
元がwindows用なので、linuxで実行できるように実行属性を付与します。
中身はそのまま。
chmod +x build-debug.bat
ホストOS側のVScodeを起動します。
WSLなので、ターミナルから以下のコマンドで起動してカレントディレクトリを開きます。
code .
VScodeの拡張機能で
エクスプローラサイドパネルからsrc/main.cを開き、main() のどこかにブレークポイントを設定。
デバッグサイドパネルで 「Debug application in Renode」 を選んで実行。
RenoteターミナルとUART2ウィンドウが開き、設定したブレークポイントで停止するはず。
実行を再開すると、UART2ウィンドウにHello World!と表示され、無限ループに入る。
組み込みプログラムなので、ターゲットボードの動作を目で見たくなるのが人情…
ということで、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ディレクトリ下がプログラムソースです。
メインルーチンと割り込みハンドラなど。
printf/scanfなどを使用するためのsyscallルーチンを定義。
コンソール入出力のための最低限の処理だけを定義しています。
bootルーチン、ベクタテーブル、デフォルト割り込みハンドラなど。
初期化処理(C言語部)
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ターミナルでquitコマンドを実行して Renodeを終了します。
VScodeでデバッグする前にbuildディレクトリを削除しておいてください。
code .
VSCodeで
GUI部品を表示するため、ブラウザで 起動したWebサーバ(localhost:8000) にアクセスします。
ページにLEDとスイッチが表示されます。
ターゲットプログラムの動作に応じてLEDが順次点灯/消灯していきます。
スイッチをクリックするとON/OFFがトグルします。
このスイッチの情報はターゲットプログラムのメインループで表示されます。
またON時は割り込みハンドラが起動され、UARTコンソールに割り込みメッセージが表示されます。
デバッグは他の環境と同じなので、ここでは何も書きません。