見出し画像

連載21-QEMUでハードウェアなし開発

今回は、QEMUを使って、ハードウェアがない状態で開発する方法についてご紹介します。


1.QEMUって

一言で言うとハードウェアのシミュレータです。

組み込みのソフトウェア開発を開始するためには、まずハードウェアが手元にないと、ビルドまでしかできませんよね。

しかしQEMUを使うと、ハードウェアを仮想的に実現してくれます。

そうはいっても、動くのってCPUと割り込みとメモリくらいでしょ?
と、お思いかもしれません。

違います。

定義しさえすれば、いろんなハードウェアをエミュレートできます。
UARTとか、I2Cとか、SPIとか。。。

QEMUの公式サイトはこちらです。
https://www.qemu.org/

QEMUには、
・Full-system emulation:CPUのブートからすべてエミュレートする
・User-mode emulation:ユーザ―モードアプリのみエミュレートする
があります。
SOLIDは、Full-system emulation版を組み込んでいます。
すなわち、リセットベクタフェッチから始まるCPUの動作を模倣しています。

1.1 SOLIDのQEMUサポート

SOLIDでは、標準構成で、複数CPUs(32 or 64ビット、単一 or マルチCPU)、割り込み、メモリに加え、UARTが使用できます。

SDKを購入すると、その他のハードウェアを追加することも可能です。

お願いすると有償サポートもしてもらえます。

UARTだけなので完全にとはいかなくとも、以下のような要求を満たせそうですね。
・評価ボードが出来上がるまで時間がかかる。
・ソフトウェア開発者全員にいきわたる台数の評価ボードを作るのが難しい。
・評価ボードを送付できない拠点でソフトウェアの開発を行いたい。

とはいえ、UARTだけでも、
・ソフトウェアの基幹部分を作成しておきたい
・ARMコアの勉強をしたい
等の目的に使用できますね。

2.QEMUを動かす

では早速試してみましょう。

SOLID for QEMUについては、以下URLで解説されています。
https://solid.kmckk.com/SOLID/doc/latest/qemu/qemu.html

ここからは、チュートリアルに従って試していきましょう。

2.1 エミュレータ環境のインストール

まずSOLID-QEMU-<バージョン>.exeというファイルを入手します。
(SOLIDのライセンスを契約すると、入手できます)

インストールは簡単です。
そのSOLID-QEMU-<バージョン>.exeを実行すればOKです。

詳細は以下URLをご覧ください。
https://solid.kmckk.com/SOLID/doc/latest/qemu/tutorial/install.html

2.2 サンプルプロジェクトの実行

以下URLに従って実行していきます。
https://solid.kmckk.com/SOLID/doc/latest/qemu/tutorial/samples.html

マルチコアのデモプロジェクトを動かしてみます。
(サンプルプロジェクトは既に取得しています。)

① ソリューションファイルqemu-virtmini-aarch64-fmp3-2CPU-test-stack-usage-recog-Sを開きます。

② PARTNER-JetをPCに接続
ビルドにはライセンスが必要なので、PARTNER-Jet2をPCに接続して、ライセンスが取得できるようにしておきます。

③ ビルド
通常通りビルドします。

④ デバッグ開始します。
[Partner QEMU Debug Engine]ボタン押下でデバッグが開始されます。

⑤ 実行中
プログラムが実行されました。
Qemu-system-aarch64.exeが自動的に起動され、ログ出力が表示されています。

2.3 ブレーク

では、ブレークしてみて、ローカル変数を表示したりしてみましょう。
あらかじめブレークポイントを設定しておき、デバッグ開始してみます。

ブレークで停止し、デバッグに必要そうなウインドウをいろいろ開けてみました。

ローカル変数も表示されているし、RTOSビューアも、並列スタックも、各コア状態も。。。
ハードウェアがある場合と変わりませんね。

2.4 MMU例外を出してみる

例外をわざと発生させてみて、ハードウェアがある場合と同じかどうかみてみましょう。
発生させる例外はMMU例外にしましょう。

0番地付近は仮想アドレスに物理メモリがマップされていません。

という事で、0番地にライトアクセスをしてみましょう。
適当に以下のコードを追加し、ビルドして実行してみます。

uint32_t *p;
p = 0;
*p = 0;

[デバッグ例外]ウインドウが表示され、Data Abort Exceptionと通知してくれました。

ハードウェアがある場合はこちら。同じですね。

https://note.com/yn_2022/n/ne8a0329d2fb1#c957e24e-1e6e-4948-97c0-a817de80a97a

2.5 スタックオーバーフロー検出

次にスタックオーバーフローを発生させてみます。

void rec_func(){
   rec_func();
}

この再帰関数を延々コールするとオーバーフローしますね。

スタックがオーバーフローしてるっぽいよ、と教えてくれました。

ハードウェアがある場合と同じですね。
https://note.com/yn_2022/n/ne8a0329d2fb1#87c24647-2aa4-49f3-bd7a-af21ec65cdbb

2.6 カバレジ

コードカバレジを取ってみましょう。
こちらで書いた内容をそっくりそのまま試してみます。
https://note.com/yn_2022/n/na660efb50d37

取れました。

その他、関数トレース、ローダー機能、アドレスサニタイザ機能などなど、ハードウェアがある場合と同じように使用することができます。

3.ハードウェア構成

ハードウェアがある場合と同じにならない可能性が一番高いのは、周辺I/Oですよね。

これについても、想定のハードウェア構成に近づけることは可能です。
(どこまでやるか、ですが)

どこで定義されているのかについて、以下のURLで解説されています。
https://solid.kmckk.com/SOLID/doc/latest/qemu/virtualboard.html

3.1 標準構成

以下の部品が標準で搭載されています。

CPU: ARM Cortex-A53(シングルコア or マルチコア)
割り込みコントローラ:  GIC-400
タイマ: Generic Timer
UART: PL011
ROMなし、RAM 2GB

3.2 カスタマイズ

ハードウェア構成を知るためにQEMUが参照するのは、.dtb (device tree blob)ファイルです。dtsファイルはそのソースファイルです。

これらはプロジェクトのqemuフォルダ内にあります。

このファイルは、コアの数によって形式が違います。
(CPUの数以外のハードウェア構成は同じです。)

今回使用した2-CPUコアの場合、dual-aarch64.dtsで定義されています。

例えば、RAMのサイズについては以下のように定義されています。

この値を変更すれば、標準構成の2GBから変更することができます。

では、周辺I/Oについてはどうでしょうか。
UARTを見てみます。

ここで、UARTチャンネル名を変更したり、UART本数を増やしたりができます。
UARTの出力先についても、標準ではQEMUのコンソールとなっていますが、TCPポートに変更することもできます。
詳細はこちら。
https://solid.kmckk.com/SOLID/doc/latest/qemu/virtualboard.html#uart

DTSファイルの変更を反映されるためには、SOLID付属のdtcコマンドでdtbファイルを再生成します。
手順については以下のURLで紹介されています。
https://solid.kmckk.com/SOLID/doc/latest/qemu/virtualboard.html#id5

その他、I2C等の別の周辺I/Oを追加するには、別途SDKを購入するか有償サポートが必要です。

4.まとめ

手軽にこういったシミュレータが使えるのは嬉しいですね。
QEMUというと、ちょっと使うのにハードルがあるイメージがあったのですが、SOLIDでは既に開発ツールの一つとして組み込まれているので、サクッと使えました。

それに各周辺I/Oがないからといって、何もできないわけではありませんよね。
ソフトウェアの構造、大枠を作ることはできるわけです。
タスクの個数や役割を決めたり、ローダブルモジュールとして切り分けるところを作成したり、いろいろとできます。
それに例えばI2C経由でセンサをアクセスするところは空関数にしておいて、後でハードウェアが入手できたら実装する、という手順で開発するなどできそうです。

また、冒頭で書いた通り、SOLIDではQEMUのFull-system emulation版を組み込んでいるため、リセット解除からのCPU動作をエミュレートしています。
ハードウェアはなくとも本物のCPUの動きを見ることができるので、ARMコアの学習にももってこいですね。
CPUの学習をしたいだけなのにハードウェアのトラブルに悩まされる、、、という事もありませんしね。

次回は、引き続きSOLID for QEMUの機能についてご紹介をする予定です。


この記事が気に入ったらサポートをしてみませんか?