Open2

2コアマイコン向け簡易OS設計のための下調べ編

okuokuokuoku

Maix AmigoのK210とRaspberry Pi PicoのRP2040には意外な共通点があって、

  • チップは2コアを提供している
  • SDKはOSを提供していない

というポイントがある。というわけでこれら向けには他の環境と同様のコーディングはできず、まず適当なOSを用意してやる必要がある。

基本戦略

ESP32と同様の戦略、つまり:

  • Core0: プロトコル処理等の通常のシステムにおけるOSカーネルに相当する処理
  • Core1: ユーザアプリケーションを動作させる

という分割を前提とする。Core0側、つまりカーネルはチップベンダが提供するSDKで記述し、Core1側のアプリケーションは専用のSDKやlibcを別途用意する。Core1側のアプリケーションは将来的にWebAssemblyでの供給とチップを超えた共通化を目指す。

... もっとも、RP2040はメモリが少すぎるので一般的なアプリケーションを実現するのはほぼ不可能で、専用に構築したゲームが限界なのではないかと考えている。

調べること

簡易といっても、マルチプロセッサ対応のOSを作るにはそれなりのプリミティブが必要になる。

  1. プロセッサ間割り込みの方法 。Core0 → Core1 は最低でも必要になる。Core1 → Core0 は存在しなくてもポーリングで何とかできなくはないが、パフォーマンスのためには合った方が良い。
  2. キャッシュをフラッシュする方法 。 Core0 と Core1 でメモリを共有する可能性がある場合、例えば、Core0で行った変更がキャッシュだけに反映されていてCore1から見えないといった事故が発生する可能性がある。
  3. アトミックなメモリ更新方法 。Core0でカメラ画像を取り込んでCore1で使用するといったケースでは、Core1が画像を使用している間はCore0は更新しないように配慮する必要がある。このとき、 "カメラ画像使用中フラグ" はCore0とCore1で共有されるため、両者で矛盾なくフラグを更新できる仕組みが必要になる。
  4. プロセッサをスリープ/復帰させる方法 。流石に単純に消費電力倍は受け入れられないのでsleepさせる方法論が必要になる。
okuokuokuoku

諸元、情報源

とりあえずどこを見れば良いのかを先に調べておく。

K210

K210のデータシートにリソース類は列挙されている。

https://github.com/kendryte/kendryte-doc-datasheet/blob/822026850598e05c1d6fd7e3c60462f8ea3219cd/en/003.md

関連するのは、

SDKは割り込みハンドラを抽象化しているので、それに乗るのが妥当な気がする。例えば、core1の起動コードは、

というような実装になっている。一度Core1側でユーザコードの実行を始めたら、割り込みハンドラをオーバライドしてやらなければならない。

キャッシュ制御命令の類は提供されない 。つまり、DMAによってプロセッサ外部に出ていくデータは非キャッシュ領域に一旦手でコピーする必要がある。

Coreは独立したキャッシュを持つが、これらは(gccの)atomic拡張でカバーされる。 https://github.com/kendryte/kendryte-standalone-sdk/blob/06a2ea71f250e91d66fa156ff82ae1f5b9fc6e56/lib/bsp/include/atomic.h#L35-L51

RaspberryPi Pico

データシートにリソース類は列挙されている。

https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf

K210は割と素直なRISC-V SoCになっているが、RP2040の方は割と斬新な構成をしていて、例えば、"2.1.2. Atomic Register Access" で示されるようにバスレベルで周辺レジスタへのread-modify-writeをサポートしている。

また、(XIP -- 外部 NOR/NAND フラッシュからの直接実行用) を除いて 一切のCPUキャッシュが無い ので、K210と比べて気にするべきことは少ない。

ライブラリ pico_multicore https://raspberrypi.github.io/pico-sdk-doxygen/group__pico__multicore.html がCore 1側の起動をサポートしている。