Baochip のご紹介



bunnie | masto: @bunnie@treehouse.systems | bluesky: @bunnie.org

baochip | bluesky: @baochip.com

English (original)|この日本語版は Claude (AI) による機械翻訳です

Baochip のご紹介

  • オープンソースの CPU を5つ搭載
    • VexRiscv RV32IMAC+MMU @ 350MHz
    • PicoRV I/O エンジン(「BIO」)×4 @ 700MHz
  • オンチップ ROM 4MiB(「RRAM」)
  • オンチップ SRAM 2MiB
  • 暗号アクセラレータ、TRNG
  • USB HS、カメラ、I2C、SPI、UART など

マイコン比較表:Dabao vs Raspberry Pi Pico 2、ESP32、Teensy 4.1、Adafruit Feather M4、BBC micro:bit v2

項目 Dabao Raspberry Pi Pico 2 ESP32-DevKitC Teensy 4.1 Adafruit Feather M4 BBC micro:bit v2
メーカーBaochipRaspberry Pi LtdEspressif SystemsPJRCAdafruitMicro:bit Educational Foundation
MCU / SoCBaochip-1x(シングルコア Vexriscv)RP2350(デュアルコア Cortex-M33)ESP32(デュアルコア Xtensa LX6)NXP iMXRT1062(Cortex-M7)SAMD51(Cortex-M4F)nRF52833(Cortex-M4F)
クロック周波数350 MHz150 MHz240 MHz600 MHz120 MHz64 MHz
I/O コプロセッサBIO(PicoRV ×4 @ 700 MHz)PIO ブロック ×2(ステートマシン 8基)ULP コア ×2(RISC-V / FSM)FlexIOSERCOMなし
ハードウェアセキュリティ署名付きブート、TRNG、鍵ストア、ワンウェイカウンタ、RSA、ECC、ECDSA、X25519、SHA-256/512、SHA3、Blake2/3、AES;セキュアメッシュ、グリッチセンサ、ECC 保護 RAMTrustZone、署名付きブート、OTP 鍵ストア、HW SHA-256、TRNGeFuse セキュアブート + AES フラッシュ暗号化、HW RNGHAB セキュアブート、AES-256 暗号化 XIP(ロック可能)NVM の読み出し保護のみ読み出し保護のみ;HW 暗号なし
IRIS で検査可能対応非対応非対応非対応非対応非対応
ブートローダがオープンオープンオープン非公開非公開非公開非公開
RTL がオープンほぼオープン非公開非公開非公開非公開非公開
メモリ保護MMUMPU + TrustZoneMPU 相当MPUMPUMPU
スワップメモリ対応(Xous + 外部 PSRAM)非対応非対応非対応非対応非対応
Rust ネイティブ対応非対応非対応非対応非対応非対応
RAM2048 KB + I/O バッファ 256 KB520 KB520 KB1 MB192 KB128 KB
Flash4 MB(内蔵 RRAM)4 MB4 MB8 MB + SD スロット内蔵 512 KB + 外付け 2 MB内蔵 512 KB
Flash インターフェース内蔵 XIP(最大 1200 MB/s)QSPI(XIP 約 56 MB/s)QSPI(約 40 MB/s)FlexSPI octal/quad(XIP 約 100 MB/s)内蔵 NVM(XIP 推定約 400 MB/s)内蔵 NVM(推定 20–40 MB/s)
GPIO ピン2026345520大ピン5 / 全19
無線なしなし(W 版は Wi-Fi/BT 搭載)Wi-Fi + Bluetooth 4.2なし(アドオンあり)なし(Wing エコシステム)Bluetooth 5.0 + 2.4 GHz
USBUSB-C(USB 2.0 HS デバイス)Micro-USB(ネイティブ)Micro-USB(CP2102 経由)USB-C(ネイティブ、デバイス + ホスト)Micro-USBMicro-USB
価格(目安)$12$5–$7$8–$12$30–$35$20–$24$15–$18
向いている用途セキュリティ、高信頼性、汎用汎用、MicroPython/C++IoT、無線接続オーディオ DSP、高速データ、USB MIDI/HIDCircuitPython、モジュール式 Wing 拡張教育、子ども向け、授業でのコーディング

IRIS で検査できる

IRIS でチップの偽造が難しくなる

BIO で柔軟な I/O を実現


  • BIO:Bao-I/O プロトコルエミュレータ
    • トグルレート 25MHz 未満ならどんなプロトコルでも
    • CAN
    • LED テープ
    • USB フルスピード
    • I2C、UART、SPI など…
    • あの謎なエアコンの赤外線プロトコルも…
  • オープンソースで特許フリー!
    • Raspberry Pi の PIO に似てるけど、こっちはオープンソース

仕組み:BIO のアーキテクチャ

  • RISC-V の CPU を想像してみてください…
    • 下位16個のレジスタは「普通」
    • 上位16個のレジスタは「ハードウェア機能」
      • GPIO の設定/取得、ピンの方向
      • イベント管理
      • CPU 間の通信と同期

例:LED を「Blink(点滅)」させる


#include <stdint.h>

#include "bio.h" // これは必ず一番最初に書くこと

#define GPIO_PIN 21

void main(void) {
    uint32_t output_mask = 1 << GPIO_PIN;

    set_gpio_mask(output_mask);
    set_output_pins(output_mask);

    clear_gpio_pins_n(!output_mask); // Low に駆動
    while (1) {
        for(int i = 0; i < 10; i++) {
            set_gpio_pins(output_mask);
        }
        for(int i = 0; i < 10; i++) {
            clear_gpio_pins_n(!output_mask); // ピンを Low に駆動
        }
    }
}
					

LED を「Blink」:GPIO を設定する

マルチコア動作


// コア0 で動く
void main(void) {
    uint32_t tx = 0;
    uint32_t rx;
    while(1) {
        push_fifo1(tx);
        rx = pop_fifo0();
        tx = rx + 1;
    }
}

// コア1 で動く
void main(void) {
    uint32_t rx;
    while(1) {
        rx = pop_fifo1();
        push_fifo0(rx + 1);
    }
}
					

詳しく:CPU0 と CPU1 の間でデータを送る

BIO を試してみよう

Baochip が生まれた経緯

オープンソース・シリコンの全体像

  • PDK vs RTL
    • PDK(process design kit)
      • 実際のトランジスタや配線を記述する
      • ファウンドリの企業秘密のため、オープンソース化が難しい
      • オープンな PDK は古いノード(130nm、180nm)だけ。それ以外は(今のところ)クローズド
    • RTL(Register Transfer Level)
      • ハードウェアをコードで記述したもの
      • Verilog、VHDL など

      • 自分たちが設計する RTL は、オープンソースにできる
      • CPU にオープンなアーキテクチャを選ぶこともできる
      • 完全にオープンなハードウェアスタックでいずれ動くソフトを、から作り始めることもできる
    RTL の例

問題:チップは高い

コードを作るツール vs チップを作るツールのコスト

戦略:
オープンソースのコアを
商用テープアウトに「ヒッチハイク」させる

おさらい:微細ノードチップのロジック密度

  • チップのサイズを主に決めるのは:
    • メモリ
    • I/O の外周
  • ロジックは「気体」みたいなもので、
    空いている空間を埋めるように広がる
    • 細かく見ると、けっこうスカスカ

おさらい:典型的な SoC のブロック図

じゃあ…RISC-V コアを足すだけじゃダメ?

できます、しかも「タダ」!


  • ダイ面積 2% 未満
    • VexRiscv ×1 (MMU 付き)
    • PicoRV ×4
  • テープアウトの追加コストなし
    • ロジックはスカスカ
    • もっとロジックを詰め込める!
    • ロイヤリティなし

さて…ヒッチハイクは理論上は可能、でも…

でも、こんな奴を誰が乗せてくれる?

図1.「ヤバそうな奴」

幸い、Crossbar はちょうど同じ方向に向かっていて、
止まって私に道を尋ねてきた…

結果:高信頼用途向けの
部分オープン RTL SoC「Baochip-1x」

Dabao のご紹介

Dabao:Baochip-1x 評価ボード

  • 「いちばんシンプルなボード」
    • 2層基板
    • JLCPCB で製造可能
  • 全 I/O がピンに出ているわけではない
    • Baochip-1x の CSP パッケージが高密度すぎる
    • 配線できる I/O の一部だけ利用可能
  • オンボードの電圧レギュレータ内蔵
  • ソース:https://github.com/baochip/dabao

Dabao のピンアウト

Dabao の入手時期

  • 最初の出荷は2026年6月、CrowdSupply の「アーリーアクセス」支援者向け
  • 一般販売は2026年12月を予定
  • 待ち時間が長い理由:ファウンドリが AI 関連の注文で「予約で満杯」

Baochip の OS「Xous」をざっくり紹介

Xous:Baochip-1x 向けの純 Rust 製 OS

  • 一から Rust で書かれている
    • MMU のおかげで仮想メモリを使える(デスクトップ OS みたいに)
    • プロセス間はメッセージパッシング
  • ソース:https://github.com/betrusted-io/xous-core/
    
    									git clone --depth 1 https://github.com/betrusted-io/xous-core/
    									cd xous-core
    									git fetch --depth 1 origin tag v0.10.1
    								
  • Rust ツールチェーンが必要
    • すでに入っている場合は「rustup update」で最新化してください
  • 複数ターゲットに対応。dabao 向けは以下でビルド
  • 
    									cargo xtask dabao dabao-console
    								

Xous のコード構成

Xous はメッセージパッシング型 OS

  • 各プロセスは独立した仮想メモリ空間で動作する
  • メッセージは一度カーネルを「経由」して宛先へルーティングされる
  • この例では:
    • 「console」プロセスがカーネル経由で「log」にログメッセージを送る
    • log がそのメッセージを受け取る
    • log はそれを USB インターフェースへ流す
    • (図にはないけど、ハードウェアシリアルにも流している)

ありがとうございました!



bunnie | masto: @bunnie@treehouse.systems | bluesky: @bunnie.org

baochip | bluesky: @baochip.com


Discord に参加しよう:

予備スライド

開発者体験:LED を点滅させる

  • シェルに「blink」コマンドを追加
  • HAL の IO サービスに接続
  • ピンを設定
  • ピンの値を切り替えながらループ

シェルの概要

  • シェルは「dabao-console」にある
  • シェルには REPL(Read-Eval-Print-Loop)があり、コマンドを受け取って「コマンドモジュール」に振り分ける
  • これは「ver」コマンドモジュールの例

impl<'a> ShellCmdApi<'a> for Ver {
    cmd_api!(ver);

    fn process(&mut self, args: String, env: &mut CommonEnv) ->
		Result<Option<String>, xous::Error> {
        use core::fmt::Write;
        let mut ret = String::new();
        let helpstring = "ver [xous]";

        let mut tokens = args.split(' ');

        if let Some(sub_cmd) = tokens.next() {
            match sub_cmd {
                "xous" => {
                    write!(ret, "Xous version: {}", env.ticktimer.get_version()).unwrap();
                    log::info!("VER.XOUS,{}", env.ticktimer.get_version());
                }
                _ => {
                    write!(ret, "{}", helpstring).unwrap();
                }
            }
        } else {
            write!(ret, "{}", helpstring).unwrap();
        }
        Ok(Some(ret))
    }
}
						

blink コマンド:サブコマンドを追加

  • 「test.rs」モジュールに「blink」コマンドを追加
  • blink のコードを apps-dabao/dabao-console/src/cmds/test.rs の 24 行目あたりに挿入

    fn process(&mut self, args: String, _env: &mut CommonEnv) -> Result<Option<String>, xous::Error> {
        use core::fmt::Write;
        let mut ret = String::new();

        #[allow(unused_variables)]
        let helpstring = "test [proc] [freemem] [interrupts] [panic] [env]";

        let mut tokens = args.split(' ');

        if let Some(sub_cmd) = tokens.next() {
            match sub_cmd {
                "blink" => {
                    log::info!("Add blinky code here");
                }

						

コマンド拡張をテスト

vscode 拡張を使って:

  • 「Build-flash-monitor」をクリック
  • 初回は、指示に従って Dabao のディスクとシリアルポートの場所を指定
    • baochip の場所を設定
    • ブートローダモードのシリアルポートを設定
    • build-flash-monitor を押す
    • 実行モードのシリアルポートを設定
    • もう一度「monitor」を選ぶ必要があるかも
  • 「[console]」プロンプトで「test blink」と入力

[console]

[console] test blink
INFO:dabao_console::cmds::test: Add blinky code here (apps-dabao\dabao-console\src\cmds\test.rs:25)
						

blink コマンド:点滅処理を追加

  • 「IoxHal」オブジェクトを作る
  • ポートと方向を設定
    • PB4 なら、PB4 と隣のグランドピンの間に LED を1個挿せる
  • ループを作る:
    • ピンを High に
    • 1秒待つ
    • ピンを Low に
    • 1秒待つ
  • Build-flash-monitor

                "blink" => {
                    use std::time::Duration;

                    use bao1x_api::{IoGpio, IoxDir, IoxHal, IoxPort, IoxValue};
                    let iox = IoxHal::new();
                    iox.set_gpio_pin_dir(IoxPort::PB, 4, IoxDir::Output);
                    loop {
                        iox.set_gpio_pin_value(IoxPort::PB, 4, IoxValue::High);
                        std::thread::sleep(Duration::from_secs(1));
                        iox.set_gpio_pin_value(IoxPort::PB, 4, IoxValue::Low);
                        std::thread::sleep(Duration::from_secs(1));
                    }
                }