STM32(ARM Cortex-M)をQEMUで動かす(環境構築編) - 土日の勉強ノート

土日の勉強ノート

AI、機械学習、最適化、Pythonなどについて、技術調査、技術書の理解した内容、ソフトウェア/ツール作成について書いていきます

STM32(ARM Cortex-M)をQEMUで動かす(環境構築編)

今回から 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 をクリックします。

New Projectの画面
New Projectの画面

Project name は任意ですが、「stm32f4discovery_sample」として、Project type は「Empty Project」を選び、Toolchains は「Arm Cross GCC」を選択して、Next をクリックします。

C Projectの画面
C Projectの画面

あとは、全てデフォルトで、Next をクリックすればいいとのことです。

Nextをクリックします
Nextをクリックします

Finishをクリックします。

Finishをクリックします
Finishをクリックします

元の起動画面に戻ってきました。Welcomeの画面を閉じておきます。すると、クッキーを受け入れるかどうかの画面が出たので、「Allow cookies」をクリックします。

クッキーの受け入れ確認の画面
クッキーの受け入れ確認の画面

サンプルソースのインポート

ダウンロードしたサンプルソースをインポートします。File→Importをクリックします。

インポートを開く
インポートを開く

General→File Systemをクリックして、Nextをクリックします。

General→File Systemをクリック
General→File Systemをクリック

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) を選択します。

TagetProcessorの設定
TagetProcessorの設定

そのまま、下の 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 と入力しておきます。

GNU Arm Cross C Linker の設定画面
GNU Arm Cross C Linker の設定画面

次は、MCU をクリックして開き、Build Tools Path をクリックします。Build tools folder に「/usr/bin」を入力します。設定は以上なので、Apply and Close をクリックします。

Build Tools Pathの設定画面
Build Tools Pathの設定画面

デバッグの設定

続いて、デバッグ実行の設定を行います。

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 を指定してください。

Debuggerタブの設定画面
Debuggerタブの設定画面

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 のパスを、フルパスで指定し直してください。

GDBをフルパスで指定する
GDBをフルパスで指定する

Eclipse のメモリ割り当てを増やす

私の場合は、動かなかった原因が複数あったので、Eclipse のメモリが不足していたことが原因だったかどうかは、分かりませんが、デフォルトの割り当て量が少ないらしいので、増やした方がいいかもしれません。

eclipse の実行ファイルがある同じディレクトリに、eclipse.ini というファイルがあります。これをエディタで開いてください。

デフォルトでは、「-Xms256m(起動時のヒープサイズで256MB)」と、「-Xmx1024m(最大ヒープサイズで1024MB)」になっていると思います。ここを変更すると、Eclipse のメモリ割り当て量を増やすことができます。

Eclipse の設定ファイル
Eclipse の設定ファイル

何とか動きました!

苦労しましたが、ようやく動きました。STM32F4 の評価ボードの画像ファイルの真ん中あたりの LED が点滅しているのと、デバッグログが出力されています。

Lチカ動きました!
Lチカ動きました!

実機が無くても、Lチカを動かすことが出来るのは、とても興味深いです(実機で動かす方が全然簡単ですけど(笑))。

おわりに

とても長い環境構築編になりましたが、動いて良かったです。

Webの関連する記事をいくつか見ましたが、私が見た限りは、QEMU を STM32 で動いた、という記事は少なかったと思います。

動いただけで、だいぶ満足してしまいましたが、次回以降、この環境を使って、いろいろやっていこうと思います。

最後になりましたが、エンジニアグループのランキングに参加中です。

気楽にポチッとよろしくお願いいたします🙇

今回は以上です!

最後までお読みいただき、ありがとうございました。