今回から、Renode というオープンソースの組込みデバイスのエミュレータを試していきます。
簡単に言うと、QEMU と同じ位置付けの OSS です。QEMU よりも、組込みデバイスのサポートが充実しているようです。
それでは、やっていきます。
はじめに
「QEMUを動かす」の記事一覧です。良かったら参考にしてください。
QEMUを動かすの記事一覧
まず、Renode の公式サイトは以下です。
https://renode.io/
Renode の公式のドキュメントは以下です。
https://renode.readthedocs.io/en/latest/
また、GitHub は以下です。
https://github.com/renode/renode
今回は、Renode のインストールと、サンプルソースの動作確認をやっていきます。
Renodeのインストール
インストール手順は、公式の GitHub に書かれているので、それに従います。
と言っても、Renode 自体は、portable を選べば、解凍するだけです。
依存しているパッケージとして、mono-complete パッケージを先にインストールする必要があります。
それではやっていきます。
mono-completeのインストール
以下の公式サイトの手順に従います。
今回は、VirtualBox の Ubuntu 22.04 にインストールしますが、Ubuntu 20.04 の手順までしか書かれてないですね。Ubuntu 20.04 の手順に従います。
Download - Stable | Mono
$ sudo apt install ca-certificates gnupg
ca-certificates はすでに最新バージョン (20230311ubuntu0.22.04.1) です。
gnupg はすでに最新バージョン (2.2.27-3ubuntu2.1) です。
$ 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
gpg: keybox'/usr/share/keyrings/mono-official-archive-keyring.gpg'が作成されました
gpg: /tmp/trustdb.gpg: 信用データベースができました
gpg: 鍵A6A19B38D3D831EF: 公開鍵"Xamarin Public Jenkins (auto-signing) <releng@xamarin.com>"をインポートしました
gpg: 処理数の合計: 1
gpg: インポート: 1
$ 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
deb [signed-by=/usr/share/keyrings/mono-official-archive-keyring.gpg] https://download.mono-project.com/repo/ubuntu stable-focal main
$ sudo apt update
$ sudo apt install mono-devel
結構多きかったですね。
$ mono -V
Mono JIT compiler version 6.12.0.200 (tarball Tue Jul 11 21:37:50 UTC 2023)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS: __thread
SIGSEGV: altstack
Notifications: epoll
Architecture: amd64
Disabled: none
Misc: softdebug
Interpreter: yes
LLVM: yes(610)
Suspend: hybrid
GC: sgen (concurrent by default)
バージョン 6.12 がインストールされました。Renode には、バージョン 5.2 以上が必要という条件でした。
依存関係のパッケージインストール
続いて、他の依存関係のパッケージをインストールします。
$ sudo apt-get install policykit-1 libgtk2.0-0 screen uml-utilities gtk-sharp2 libc6-dev gcc python3 python3-pip
Renodeのダウンロードとインストール
Renode 用に専用の作業ディレクトリを作って、そこに Renode をダウンロードします。
$ mkdir renode
$ cd renode
$ wget https://github.com/renode/renode/releases/download/v1.15.0/renode-1.15.0.linux-portable.tar.gz
公式の手順では、解凍に -C
と --strip-components=1
を使っていますが、同じことを実現するのに、別の手順を使うのは、効率が良くないと思います。
ということで、普通のやり方にします。
$ tar zxvf renode-1.15.0.linux-portable.tar.gz
$ renode_1.15.0_portable/renode -v
Renode v1.15.0.27975
build: 9111b18e-202403181532
build type: Release
runtime: Mono 4.0.30319.42000
Renode のインストールは以上です。
STM32で動作確認
公式のドキュメントには、STM32 のチュートリアルは見当たりませんでした。代わりに以下のページを見つけました。
interrupt.memfault.com
少し古いですが、このページのチュートリアルをやっていきます。
サンプルソースのビルド
起動方法が現在のものとは異なっていたり、エミュレーション開始時の挙動が少し異なります。
$ git clone https://github.com/memfault/interrupt.git
$ cd interrupt/example/renode/
$ make
git clone https://github.com/libopencm3/libopencm3.git libopencm3
Cloning into 'libopencm3'...
remote: Enumerating objects: 30727, done.
remote: Counting objects: 100% (149/149), done.
remote: Compressing objects: 100% (104/104), done.
remote: Total 30727 (delta 83), reused 75 (delta 45), pack-reused 30578
Receiving objects: 100% (30727/30727), 7.04 MiB | 25.76 MiB/s, done.
Resolving deltas: 100% (20039/20039), done.
Initializing OPENCM3 Lib
git -C libopencm3 checkout 89074d6a13ed7febba04d3c421ce7bf2b7972156
Note: switching to '89074d6a13ed7febba04d3c421ce7bf2b7972156'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 89074d6a stm32h7: fix inverted VOS settings for Vcore.
make -C libopencm3
make[1]: ディレクトリ '/home/daisuke/svn_/renode/interrupt/example/renode/libopencm3' に入ります
GENHDR include/libopencm3/stm32/f0/irq.json
/usr/bin/env: `python': そのようなファイルやディレクトリはありません
make[1]: *** [Makefile:59: include/libopencm3/stm32/f0/irq.json.genhdr] エラー 127
make[1]: ディレクトリ '/home/daisuke/svn_/renode/interrupt/example/renode/libopencm3' から出ます
make: *** [Makefile:17: libopencm3/89074d6a13ed7febba04d3c421ce7bf2b7972156] エラー 2
エラーが出ました。Git でエラーが出てるようです?ので、対処します。
$ cd libopencm3/
$ git switch -
$ cd ..
$ make
Initializing OPENCM3 Lib
git -C libopencm3 checkout 89074d6a13ed7febba04d3c421ce7bf2b7972156
HEAD is now at 89074d6a stm32h7: fix inverted VOS settings for Vcore.
make -C libopencm3
make[1]: ディレクトリ '/home/daisuke/svn_/renode/interrupt/example/renode/libopencm3' に入ります
GENHDR include/libopencm3/stm32/f0/irq.json
/usr/bin/env: `python': そのようなファイルやディレクトリはありません
make[1]: *** [Makefile:59: include/libopencm3/stm32/f0/irq.json.genhdr] エラー 127
make[1]: ディレクトリ '/home/daisuke/svn_/renode/interrupt/example/renode/libopencm3' から出ます
make: *** [Makefile:17: libopencm3/89074d6a13ed7febba04d3c421ce7bf2b7972156] エラー 2
Git は原因ではなかったかもしれません。python
が無いと言われてます。python3
はあるので、シンボリックリンクを作って対応します。
$ which python3
/usr/bin/python3
$ cd /usr/bin/
$ sudo ln -s python3 python
$ cd -
$ make
Initializing OPENCM3 Lib
git -C libopencm3 checkout 89074d6a13ed7febba04d3c421ce7bf2b7972156
HEAD is now at 89074d6a stm32h7: fix inverted VOS settings for Vcore.
make -C libopencm3
make[1]: ディレクトリ '/home/daisuke/svn_/renode/interrupt/example/renode/libopencm3' に入ります
GENHDR include/libopencm3/stm32/f0/irq.json
GENHDR include/libopencm3/stm32/f1/irq.json
GENHDR include/libopencm3/stm32/f2/irq.json
(長いので省略)
CC sync.c
CC dwt.c
AR libopencm3_pac55xx.a
make[1]: ディレクトリ '/home/daisuke/svn_/renode/interrupt/example/renode/libopencm3' から出ます
touch libopencm3/89074d6a13ed7febba04d3c421ce7bf2b7972156
Building renode example app
make -f Makefile_renode_example.mk
make[1]: ディレクトリ '/home/daisuke/svn_/renode/interrupt/example/renode' に入ります
CC renode-example.c
GENLNK stm32f407vgt6
LD renode-example.elf
OBJCOPY renode-example.bin
make[1]: ディレクトリ '/home/daisuke/svn_/renode/interrupt/example/renode' から出ます
ビルドは成功したようです。
実行してみる
Renode は解凍したディレクトリ以下のパスを、@xxx
という形で、相対パスで指定できるようです。生成された ELFファイルのシンボリックリンクを Renode のディレクトリに作ることにします。
$ cd renode_1.15.0_portable/
$ ln -s ../interrupt/example/renode/renode-example.elf
それでは、Renode を起動していきます。
$ ./renode
Renode を起動すると、Renode モニターと呼ばれる、Renode 用のコンソールが自動的に立ち上がります(下図の右側のウィンドウ)。
Renodeを起動したところ
この Renode モニターで、以下のように、環境の構築、評価ボードの指定、ELF ファイルのロード、UART 用のモニターの起動、GDB の設定などを行い、最後に start でエミュレーションを開始します。
(monitor) mach create
(machine-0) machine LoadPlatformDescription @platforms/boards/stm32f4_discovery-kit
.repl
(machine-0) sysbus LoadELF @renode-example.elf
(machine-0) showAnalyzer sysbus.usart2
(machine-0) machine StartGdbServer 3333
(machine-0) start
しかし、チュートリアルにもあるように、今回の評価ボードの設定が、CCM メモリに対応していないため、以下のような大量の警告が出ます。
18:04:50.1427 [WARNING] sysbus: [cpu: 0x8000D94] WriteDoubleWord to non existing peripheral at 0x1004CC3C, value 0x0.
チュートリアルの方で、CCM の設定を作ってくれているので、それを使います。拡張子が repl のファイルは、REnode PLatform という Renode の設定ファイルです。
$ cp ../interrupt/example/renode/add-ccm.repl ./
$ cat add-ccm.repl
ccm: Memory.MappedMemory @ sysbus 0x10000000
size: 0x10000
ついでに、シェルスクリプトのように、自動的に設定などを実行するファイルもコピーしておきます。この拡張子が resc のファイルも Renode で使うファイルで、REnode SCripts から来ているようです。
先ほど、手動で実行した内容が、書かれています。
$ cp ../interrupt/example/renode/renode-config.resc ./
cat renode-config.resc
name: STM32F4 Discovery Printf
description: This script runs the usart_printf example on stm32f4 discovery
$name?="STM32F4_Discovery"
$bin?=@renode-example.elf
mach create $name
machine LoadPlatformDescription @platforms/boards/stm32f4_discovery-kit.repl
machine LoadPlatformDescription @add-ccm.repl
showAnalyzer sysbus.usart2
machine StartGdbServer 3333
macro reset
"""
sysbus LoadELF $bin
"""
runMacro $reset
では、今度は、rescファイルを使って実行します。Renode の起動に引数として、rescファイルを指定することが出来ます。
$ ./renode renode-config.resc
起動した Renodeモニターに、「start」を入力します。
hello worldが出た
USART で警告が出てるのが気になりますが、とりあえず、動作したようです。
おわりに
今回は、QEMU に似た、Renode というエミュレータを動かしてみました。
少し使ってみた印象としては、QEMU より扱いやすく、UI(ユーザインタフェース)が洗練されている感じです。QEMU は、CCMデータRAM に対応していませんでしたが、Renode は、設定を追加するだけで対応できました。
また、QEMU は、Eclipse で使えましたが、Renode は、VSCode のデバッグに公式のドキュメントとして対応しています(QEMU も VSCode で動かせると思います)。
次回は、Renode で GDB を使ってデバッグをしてみたいと思います。
この記事が誰かの役に立てば嬉しいです。
最後になりましたが、エンジニアグループのランキングに参加中です。
気楽にポチッとよろしくお願いいたします🙇
今回は以上です!
最後までお読みいただき、ありがとうございました。