今回から QEMU をやっていきます。QEMU とは、実機が無くてもプロセッサ(CPU、評価ボード)を動かせるエミュレータです。
現在は、QEMU は、Linux を動かすことが多いようですが、私自身が QEMU の経験が少ないので、まずはマイコンをターゲットにしてやっていきます。
ターゲットとするマイコンは、Interface 2022年 7月号 で扱っていた STM32F4-Discovery にしたいと思います。
結論としては、無事に動きました。だいぶ苦労したので、手順としてまとめておきます。
参考文献
はじめに
「QEMUを動かす」の記事一覧です。良かったら参考にしてください。
QEMUを動かすの記事一覧
Webを検索すると、数年前は QEMU Arm で STM32 を動かす情報がヒットしますが、最近はあまり情報がありません。
まずは、その変遷を整理して、Interface 2022年 7月号 を参考にしながら、最新の QEMU Arm の環境を構築して、動かしていこうと思います。
調べた QEMU Arm の歴史
QEMU のフォークであるGNU ARM Eclipseプロジェクトは、ARM開発のためのツールや、Eclipseプラグインなどを開発するプロジェクトだったらしい。
以下によると、GNU ARM Eclipseプロジェクト(GNU ARM Eclipse QEMU含む)は、RISC-Vを対応することになったので、2019年5月に、GNU MCU Eclipseプロジェクトに名前を変えたとのこと。
github.com
以下は、GNU MCU Eclipse QEMU の GitHub だが、5年前にアーカイブ化されてる。xPack の GNU MCU Eclipse QEMU へのリンクが書かれてる。
github.com
以下によると、その後、2019年半ばに、今度は、QEMUバイナリは、GNU MCU Eclipseプロジェクトは、xPackプロジェクトに移動したらしい。
gnu-mcu-eclipse.github.io
以下は、移動先の xPackプロジェクトの QEMU Arm。
xpack.github.io
リリースのリンクをたどると、最新は xPack QEMU Arm v8.2.2-1 で、2024/4/2 にリリースされたらしいです。これを使っていきます。
xPack QEMU Arm 環境構築
Interface 2022年 7月号 では、Windows上に xPack QEMU Arm 環境を構築していましたが、ここでは、VirtualBox の Ubuntu 22.04 に環境を構築していきます。
xPack QEMU Arm のダウンロードとインストール
xPack QEMU Arm を以下からダウンロードします。
github.com
darwin(MAC用)、linux(Linux用)、win32(Windows用)があり、Linux はさらに、x64、arm64、arm があります。
今回は、Ubuntu 22.04 なので、xpack-qemu-arm-8.2.2-1-linux-x64.tar.gz を使います。
一応、ハッシュをチェックしておきます。一致したので、解凍します。
あと、qemu-system-gnuarmeclipse
を実行すればいいのですが、長いのでエイリアスを設定しておきます(.bashrcにも設定しておきます)。
$ cd Downloads/
$ sha256sum xpack-qemu-arm-8.2.2-1-linux-x64.tar.gz
ed3f322aa72d0dc062b51ca0eef9272c30e4252b979762c9037db6d60c456fb1 xpack-qemu-arm-8.2.2-1-linux-x64.tar.gz
$ cat xpack-qemu-arm-8.2.2-1-linux-x64.tar.gz.sha
ed3f322aa72d0dc062b51ca0eef9272c30e4252b979762c9037db6d60c456fb1 xpack-qemu-arm-8.2.2-1-linux-x64.tar.gz
$ tar zxvf xpack-qemu-arm-8.2.2-1-linux-x64.tar.gz
$ alias qemu='~/Downloads/xpack-qemu-arm-8.2.2-1/bin/qemu-system-gnuarmeclipse'
$ qemu -version
xPack QEMU emulator version 2.8.0 (v2.8.0-17-xpack-legacy)
Copyright (c) 2003-2016 Fabrice Bellard and the QEMU Project developers
これでインストール完了です。
Java(OpenJDK)のインストール
Eclipse の前に、Java環境(OpenJDK)をインストールします。
以前に、Java環境の構築については、「Java開発環境構築(OpenJDK+Visual Studio Code) - daisukeの技術ブログ」で書きましたが、このときはWindows環境でした。
今回は、Ubuntu 22.04 に、OpenJDK をインストールしていきます。と思ったら、既にインストールされてました(笑)。
$ sudo apt install openjdk-17-jdk
$ java -version
openjdk version "17.0.10" 2024-01-16
OpenJDK Runtime Environment (build 17.0.10+7-Ubuntu-122.04.1)
OpenJDK 64-Bit Server VM (build 17.0.10+7-Ubuntu-122.04.1, mixed mode, sharing)
Eclipse IDE のインストール
続いて、Eclipse IDE をインストールしていきます。
ダウンロード先について、少し注意が必要です。
公式のダウンロードサイトは、https://www.eclipse.org/downloads/packages/ だと思います。
でも、Interface 2022年 7月号 に書かれてるのは、このURL(https://github.com/eclipse-embed-cdt/org.eclipse.epp.packages/releases)でした。見てみると、バージョンが、2020-09 と、だいぶ古いですが、以下のような内容が書かれていました。公式サイトの Eclipse は 32bitバイナリを生成しなくなったと理解しました。
The official Eclipse build scripts no longer produce 32-bit binaries.
マイコン(STM32F4-Discovery)は 32bit なので、私の理解が正しければ、公式サイトの Eclipse は今回の用途に合いません。少し古いですが、Interface 2022年 7月号 に従って、このURL(https://github.com/eclipse-embed-cdt/org.eclipse.epp.packages/releases)から、eclipse-embedcdt-2020-09-R-linux.gtk.x86_64.tar.gz
ダウンロードします。
一応、ハッシュをチェックします。
$ sha256sum eclipse-embedcdt-2020-09-R-linux.gtk.x86_64.tar.gz
17ade7c4871ef7bc59d1d9dd0c6946d3767c3ef5e50d2e64c06d6d252643151c eclipse-embedcdt-2020-09-R-linux.gtk.x86_64.tar.gz
$ cat eclipse-embedcdt-2020-09-R-linux.gtk.x86_64.tar.gz.sha
17ade7c4871ef7bc59d1d9dd0c6946d3767c3ef5e50d2e64c06d6d252643151c eclipse-embedcdt-2020-09-R-linux.gtk.x86_64.tar.gz
一致したので、解凍します。eclipse というディレクトリが作られて、その中の eclipse というファイルが実行ファイルです。エイリアスを設定しておきます(.bashrcにも書いておきます)。
$ tar zxvf eclipse-embedcdt-2020-09-R-linux.gtk.x86_64.tar.gz
$ tree eclipse -L 1
eclipse
|-- artifacts.xml
|-- configuration
|-- dropins
|-- eclipse
|-- eclipse.ini
|-- features
|-- icon.xpm
|-- notice.html
|-- p2
|-- plugins
`-- readme
$ alias eclipse='~/Downloads/eclipse/eclipse'
クロスコンパイラのインストール
ARM用のクロスコンパイラをインストールします。
いつも、どのパッケージを入れるのかを悩むので、メモしておきます。
- gcc-arm-linux-gnueabi:Linux用 浮動小数点数演算ハードウェア非搭載用(armelアーキテクチャ用)
- gcc-arm-linux-gnueabihf:Linux用 浮動小数点数演算ハードウェア搭載用(armhfアーキテクチャ用)
- gcc-arm-none-eabi:Linuxではない、マイコン用
abi は、アプリケーションバイナリインターフェイスの略です。
今回は、マイコン用ということで、gcc-arm-none-eabi をインストールしていきます。
$ sudo apt install gcc-arm-none-eabi
これで準備完了です!
Eclipse IDE のプロジェクト作成
サンプルソースのダウンロード
Interfaceのホームページから、サンプルソースをダウンロードします。
下記の「7月号 仮想から実機まで マイコン開発入門」の「特集 第3部第1章 エミュレータQEMUを活用した開発の手引き」の「関連ファイル一式」をダウンロードします。
www.cqpub.co.jp
適当な場所に置いて、解凍しておきます。
Eclipse IDE のプロジェクト作成
Eclipse を起動します。
$ eclipse
なぜか、ウィンドウがこんな小さな状態で起動しました。大きくすることもできません。
Web画像検索して、同じウィンドウのキャプチャ画像を見つけました。プロジェクトを保存するデフォルトのディレクトリの指定のようです。
デフォルトで入力されていたパスをコピーして、エディタに貼って確認しました。このままで大丈夫です。あと、チェックボックスは、このディレクトリを今後も使うかどうかのチェックだったので、チェックを入れておきます。
適当に、タブを3回押して、リターンキーを押して、先に進みました。なぜか終了しました。あ、どうやら、Cancelを押してしまったようですね、4回が正解だったようです(笑)
再度起動してみると、今度はちゃんと表示されました。再度、チェックを入れて、Launchをクリックします。
ここからは、Interface 2022年 7月号 に従って進めます。File→New→Projectをクリックします。
C/C++ のフォルダアイコンをクリックして開き、C Project を選択して、Next をクリックします。
Project name は任意ですが、「stm32f4discovery_sample」として、Project type は「Empty Project」を選び、Toolchains は「Arm Cross GCC」を選択して、Next をクリックします。
あとは、全てデフォルトで、Next をクリックすればいいとのことです。
Finishをクリックします。
元の起動画面に戻ってきました。Welcomeの画面を閉じておきます。すると、クッキーを受け入れるかどうかの画面が出たので、「Allow cookies」をクリックします。
サンプルソースのインポート
ダウンロードしたサンプルソースをインポートします。File→Importをクリックします。
General→File Systemをクリックして、Nextをクリックします。
Browse... をクリックして、解凍したディレクトリを開きます。すると、指定したディレクトリのファイルが見えるので、board.c、board.h、main.c、startup.S、stm32f407vg.ld を選択して、Finish をクリックします。
プロジェクトの設定
Project→Properties をクリックします。
C/C++ Build の Settings をクリックします。TargetProcessor をクリックして、Arm family を cortex-m4 を選択します。Float ABI は QEMU が FPU に対応していないため、Library (soft) を選択します。
そのまま、下の GNU Arm Cross C Linker の General をクリックします。Script files の プラスアイコンをクリックして、「../stm32f407vg.ld」を入力して OK をクリックします。
(追記)
セミホスティング機能を有効にするためリンカフラグの追加が必要でした。GNU Arm Cross C Linker の Miscellaneous を開きます。右下の Other linker flags に、-specs=nosys.specs -specs=nano.specs -specs=rdimon.specs -lc -lrdimon
と入力しておきます。
次は、MCU をクリックして開き、Build Tools Path をクリックします。Build tools folder に「/usr/bin」を入力します。設定は以上なので、Apply and Close をクリックします。
デバッグの設定
続いて、デバッグ実行の設定を行います。
Run→Debug Configurations... をクリックします。
左の GDB QEMU Debuggin をダブルクリックします。すると、「stm32f4discovery_sample Debug」という項目がすぐ下に作られます。
Mainタブの C/C++ Application に、stm32f4discovery_sample.elf と入力します。
(追記)
このように、Interface 2022年 7月号 には書かれてましたが、これでは動きませんでした。
この時点では、まだ ELFファイルは作られてなく、この後、ビルド、デバッグ実行の段階で、ELFファイルが作られます。そのとき、ELFファイルが見つかりません、とエラーが出ます。
ビルドした後で、もう一度、デバッグコンフィグレーションを開いて、作られた ELFファイルを「Brouwse...」で指定(フルパス指定)してください。これが一番簡単です(Interface 2022年 7月号 が、先にビルドする手順にしてくれてたら良かったんですけど)。
次に、Debugger タブを開き、Board name に「STM32F4-Discovery」を入力し、Device name に「STM32F407VG」 と入力します。
これで完了なので、Apply をクリックして、Close をクリックします。
(追記)
ここも、これだけでは動きませんでした。
Executable path(QEMUのパスの指定)が何も設定されていませんでした。ここは、「Browse...」をクリックして、QEMU を解凍したディレクトリの qemu-system-gnuarmeclipse を指定してください。
Eclipse IDE でデバッグ
では、早速デバッグしてみます。デバッグのアイコン(虫のアイコン)をクリックします。
動きました!デバッグも出来ました!
と言いたかったんですが、全く動きません(笑)
エラーが出て、解決して、を繰り返しました。
というわけで、ここからは、本当にデバッグ編です(プログラムにバグは無いですが)。
簡単な内容については、上の記事を修正しました。
GDB を新しいものに更新する
上でインストールしたクロスコンパイラに入ってる GDB では動きませんでした。
以下のサイトで、入手した GDB で動きました。
github.com
Ubuntu 22.04 で、apt でインストールした GDB のバージョン
$ arm-none-eabi-gdb --version
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
新しくダウンロードした GDB のバージョン
$ xpack-arm-none-eabi-gcc-13.2.1-1.1/bin/arm-none-eabi-gdb --version
GNU gdb (xPack GNU Arm Embedded GCC x86_64) 13.2.90.20231008-git
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
普通にバージョンが表示されるので、GDB に問題があることが分かるまで、だいぶ時間がかかりました。バージョンの問題だったので、環境によっては問題が発生しないかもしれません。
もし、これでも解決しない場合は、eclipse を起動したコンソール(端末)のログを見てください。もし、「Unable to find full path for "${cross_prefix}gdb${cross_suffix}"」というメッセージが出ていたら、これは、Eclipse のバグだそうです。
デバッグコンフィグレーションを開いて、GDB のパスを、フルパスで指定し直してください。
Eclipse のメモリ割り当てを増やす
私の場合は、動かなかった原因が複数あったので、Eclipse のメモリが不足していたことが原因だったかどうかは、分かりませんが、デフォルトの割り当て量が少ないらしいので、増やした方がいいかもしれません。
eclipse の実行ファイルがある同じディレクトリに、eclipse.ini というファイルがあります。これをエディタで開いてください。
デフォルトでは、「-Xms256m(起動時のヒープサイズで256MB)」と、「-Xmx1024m(最大ヒープサイズで1024MB)」になっていると思います。ここを変更すると、Eclipse のメモリ割り当て量を増やすことができます。
何とか動きました!
苦労しましたが、ようやく動きました。STM32F4 の評価ボードの画像ファイルの真ん中あたりの LED が点滅しているのと、デバッグログが出力されています。
実機が無くても、Lチカを動かすことが出来るのは、とても興味深いです(実機で動かす方が全然簡単ですけど(笑))。
おわりに
とても長い環境構築編になりましたが、動いて良かったです。
Webの関連する記事をいくつか見ましたが、私が見た限りは、QEMU を STM32 で動いた、という記事は少なかったと思います。
動いただけで、だいぶ満足してしまいましたが、次回以降、この環境を使って、いろいろやっていこうと思います。
最後になりましたが、エンジニアグループのランキングに参加中です。
気楽にポチッとよろしくお願いいたします🙇
今回は以上です!
最後までお読みいただき、ありがとうございました。