2025/09/15 15:04 Creating a VGA Signal in Hubris

ロボ子、今日は組み込みOSのHubrisをST Nucleo-H753ZI評価ボードで試した話をするのじゃ。

面白そうですね、博士。Hubrisですか。組み込みOSは初めて聞きます。

そうじゃろ。今回はVGAモニタを繋いで画像を表示させるのが目標じゃ。

VGAモニタですか?最近は見かけませんね。

Raspberry Piのアクセサリから古い4x3のVGAモニタを見つけてきたのじゃ。GPIOに接続して信号を生成するぞ!

GPIOピンを直接制御するんですか?

そう!最初はGPIOピンを高速で切り替えるために、通常のコードからGPIOピンを変更することを考えたのじゃ。Hubrisでは、`stm32xx-sys`タスクがGPIOピンを制御しているから、これを削除して、全部自分のタスクでやることにしたぞ。

`sys`タスクを削除するとは大胆ですね。

最初は画面に単色を表示させることを目標にしたのじゃ。緑色のピンをHighにして、緑色の画像を表示させようとしたんじゃが…うまくいかんかった。

なるほど。それで、どうしたんですか?

チップのペリフェラルはレジスタで制御されていて、それがメモリアドレスにマッピングされているのじゃ。3000ページの参照マニュアルとにらめっこしながら、Peripheral Access Crate (PAC) を使ってレジスタを読み書きしたぞ。

3000ページですか!それは大変でしたね。

メモリ保護下で動作させるために、`app.toml`でレジスタへの書き込み権限を設定する必要があるのじゃ。Hubrisのビルドシステムが認識していないメモリ領域を使うから、`chip.toml`で定義されている領域を使うことにしたぞ。

なるほど、色々と設定が必要なんですね。

PWM(パルス幅変調)機能を使ってVGA同期信号を生成することも試したぞ。最初はPWMを使ってLEDを点滅させることから始めたんじゃ。

PWMでLEDの点滅ですか。基本的なところから試されたんですね。

H-SyncとV-Syncのピンを使って、タイミング情報をtinyvga.comで調べて、タイマーのプリスケーラーとかARR、CCRを設定したのじゃ。

H-SyncとV-Syncですね。懐かしい響きです。

最初は640x480を試したけど、800x600に切り替えたぞ。でも、緑色のピンをGPIOピンに繋いでHighにしても、期待通りに緑色の画像が表示されなかったんじゃ…

うまくいかなかったんですね。原因は何だったんでしょう?

そこで、DAC(デジタル-アナログ変換器)を使うことにしたのじゃ!DACを使って単一のラインを連続的に繰り返すことを計画したぞ。

DACですか。アナログ信号を扱うんですね。

そう!CPUの負荷を減らすために、DMA(ダイレクトメモリアクセス)も使うぞ。でも、DAC制御レジスタをタスクにマッピングする時に、メモリ保護ユニットの制限に引っかかって、タイマーをグループ化して解決したんじゃ。

色々な問題が発生するんですね。

DMAユニットがCPUキャッシュを通過しないから、ランダムなデータが表示される問題も発生したぞ。`chips/stm32h7/memory-large.toml`で`dma`フラグを設定して、`link_section`属性を使ってバッファを配置することで解決したぞ。

キャッシュの問題ですか。組み込みならではですね。

2次元画像を生成するために、MDMA(マスターダイレクトメモリアクセスコントローラ)を使うことを計画したんじゃ。でも、タスクにマッピングできる領域が足りなくなって、`sys`タスクを再導入することにしたぞ。

結局`sys`タスクを復活させたんですね。

MDMAをDMAバッファにコピーすることには成功したけど、フレームバッファはまだ動作していないんじゃ。まだまだ道のりは遠いぞ!

なるほど。でも、着実に進んでいますね。

今回の教訓は、VGAモニタを繋ぐのは思ったより大変じゃった!

お疲れ様でした。博士、今日はありがとうございました。

どういたしまして。最後に一つ、VGAモニタを繋ぐのは大変じゃが、繋がると達成感がすごいぞ!…でも、目がチカチカするからほどほどにするのじゃ。
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。