Skip to content

Commit d9c79bd

Browse files
harukasanclaude
andcommitted
Add master plan and research documents for Harucom OS completion
- Research reusable PicoRuby components (Editor::Buffer, Sandbox) - Research IRB implementation requirements (try-compile multi-line detection) - Research DVI text VRAM API needs (scroll, clear, cursor) - Research USB keyboard input layer (HID keycode conversion in Ruby) - Research picorabbit migration requirements (resolution, draw primitives) - Research build size and memory budget (6.9MB firmware headroom) - Define 7 milestones with dependency graph Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f8727a2 commit d9c79bd

7 files changed

Lines changed: 918 additions & 0 deletions

doc/masterplan/masterplan.md

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
# Harucom OS マスタープラン
2+
3+
## ゴール
4+
5+
残り約2週間で以下の3機能を完成させ、Harucom OS を作品として仕上げる:
6+
7+
1. **Ruby Shell (IRB)**: DVI テキストモード上で動作するインタラクティブ Ruby
8+
2. **テキストエディタ**: Ruby スクリプトを編集・保存できるエディタ
9+
3. **picorabbit**: プレゼンテーションツールを Harucom 上で動作させる
10+
11+
## アーキテクチャ概要
12+
13+
I/O 経路は完全に分離する:
14+
15+
- **デバッグ経路**: `printf()` -> `hal_write()` -> UART TX / `hal_getchar()` <- UART RX
16+
- **ユーザー経路**: IRB/Editor (Ruby) -> DVI::Text VRAM -> DVI 画面 / USB::Host.keyboard_* (Ruby) <- USB キーボード
17+
18+
HAL は UART デバッグ I/O 専用として維持し、変更しない。
19+
20+
```
21+
┌─────────────────────────────────────────────────────────┐
22+
│ Ruby アプリケーション層 │
23+
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
24+
│ │ IRB │ │ Editor │ │ picorabbit │ │
25+
│ │ (Ruby) │ │ (Ruby) │ │ (Ruby) │ │
26+
│ └────┬─────┘ └────┬─────┘ └────┬─────────────┘ │
27+
│ │ │ │ │
28+
│ ┌────┴──────────────┴──┐ ┌─────┴───────────────┐ │
29+
│ │ Console (Ruby) │ │ DVI::Graphics (C) │ │
30+
│ │ テキストモード UI │ │ グラフィックスモード │ │
31+
│ └──┬──────────┬────────┘ └─────────────────────┘ │
32+
│ │ │ │
33+
│ │ 出力 │ 入力 │
34+
│ v v │
35+
├─────────────────────────────────────────────────────────┤
36+
│ C 基盤層 │
37+
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
38+
│ │ DVI::Text │ │ USB::Host │ │ Sandbox │ │
39+
│ │ VRAM API (C) │ │ keyboard (C) │ │ eval 隔離 │ │
40+
│ └──────────────┘ └──────────────┘ └──────────────┘ │
41+
│ ┌──────────────┐ ┌──────────────┐ │
42+
│ │ Editor:: │ │ picoruby- │ │
43+
│ │ Buffer │ │ require │ │
44+
│ │ (PicoRuby) │ │ (PicoRuby) │ │
45+
│ └──────────────┘ └──────────────┘ │
46+
├─────────────────────────────────────────────────────────┤
47+
│ HAL (UART デバッグ専用、変更なし) │
48+
│ hal_write() -> UART TX hal_getchar() <- UART RX │
49+
└─────────────────────────────────────────────────────────┘
50+
```
51+
52+
## コンポーネント一覧 (Ruby/C の実装境界)
53+
54+
### C で実装するもの
55+
56+
| コンポーネント | 概要 | 新規/既存 |
57+
|---|---|---|
58+
| DVI::Text 追加 API | scroll_up, clear_range, get_attr, set_attr | 既存に追加 |
59+
| DVI::Graphics 描画追加 | draw_text (8x8), draw_line, draw_image | 既存に追加 |
60+
| Machine ポート | signal_self_manage, check_signal | 新規 |
61+
62+
### Ruby で実装するもの
63+
64+
| コンポーネント | 概要 | 新規/既存 |
65+
|---|---|---|
66+
| Keyboard | USB::Host API をラップした keycode->文字変換、キーリピート、修飾キー処理 | 新規 |
67+
| Console | DVI::Text を使ったテキスト UI 基盤 (カーソル管理、スクロール、行描画) | 新規 |
68+
| IRB | Console + Editor::Buffer + Sandbox による REPL | 新規 |
69+
| Editor | Console + Editor::Buffer による全画面エディタ | 新規 |
70+
| picorabbit | スライドロジック (DVI::Graphics API で再実装) | 移植 |
71+
72+
### PicoRuby から再利用する部品
73+
74+
| 部品 | パス | 用途 |
75+
|---|---|---|
76+
| Editor::Buffer | `lib/picoruby/mrbgems/picoruby-editor/mrblib/buffer.rb` | テキストバッファ管理 (完全再利用、修正不要) |
77+
| Sandbox | `lib/picoruby/mrbgems/picoruby-sandbox/` | IRB の eval 隔離実行 (Machine ポート必要) |
78+
| picoruby-require | 既にビルド済み | ファイルベースの require/load |
79+
| mruby-task | 既にビルド済み | 協調マルチタスク |
80+
81+
## マイルストーン
82+
83+
### Milestone 1: キーボード入力 (Days 1-3)
84+
85+
USB キーボードから文字入力を受け取れるようにする。全機能の入力基盤。Ruby で実装する。
86+
87+
**新規ファイル**: Ruby スクリプト (ファームウェア埋め込みまたは /flash 配置)
88+
89+
**Keyboard クラス (Ruby)**:
90+
- `USB::Host.keyboard_keycodes` / `keyboard_modifier` をポーリング
91+
- HID keycode -> 文字変換ルックアップテーブル (初期実装は US レイアウト、テーブル差し替えで JIS 等に対応可能)
92+
- 前回レポートとの差分で新規キー押下を検出
93+
- Shift: shifted テーブル使用
94+
- Ctrl + 文字: ASCII 制御コード (Integer 1-26) として返す (Ctrl-C=3, Ctrl-D=4, Ctrl-S=19, Ctrl-Q=17)
95+
- 特殊キー: Editor::Buffer.put が受け付けるシンボルで返す (`:UP`, `:DOWN`, `:LEFT`, `:RIGHT`, `:HOME`, `:BSPACE`, `:TAB`, `:DELETE`)
96+
- ソフトウェアキーリピート (初期ディレイ 400ms, リピート 50ms)
97+
- `Keyboard#read_char` -> String (通常文字) / Symbol (特殊キー) / Integer (制御コード) / nil (入力なし)
98+
99+
**戻り値の設計**: Editor::Buffer.put にそのまま渡せる形で統一する。
100+
IRB/Editor のループは制御コード (Integer) を先にチェックし、残りを Buffer.put に渡す。
101+
102+
**HAL は変更しない**: hal_write / hal_getchar は UART デバッグ専用のまま維持。
103+
104+
**検証**: Ruby スクリプトで `Keyboard#read_char` を呼び出し、DVI::Text.put_string で文字が画面に表示されることを確認。
105+
106+
### Milestone 2: DVI テキスト API 拡張 (Days 2-4)
107+
108+
IRB とエディタに必要なテキスト VRAM 操作を追加する。Milestone 1 と並行作業可能。
109+
110+
**実装内容**:
111+
112+
C API 追加 (`mrbgems/picoruby-dvi/`):
113+
- `dvi_text_scroll_up(int lines, uint8_t fill_attr)` -- VRAM memmove + 末尾行クリア
114+
- `dvi_text_clear_range(int col, int row, int width, uint8_t attr)` -- 部分行クリア
115+
- `dvi_text_get_attr(int col, int row)` -- セル属性読み取り
116+
- `dvi_text_set_attr(int col, int row, uint8_t attr)` -- セル属性設定
117+
118+
Ruby バインディング追加:
119+
- `DVI::Text.scroll_up(lines, attr)`
120+
- `DVI::Text.clear_range(col, row, width, attr)`
121+
- `DVI::Text.clear_line(row, attr)` (既存 C API の Ruby 公開)
122+
- `DVI::Text.get_attr(col, row)`
123+
- `DVI::Text.set_attr(col, row, attr)`
124+
125+
**変更ファイル**:
126+
- `mrbgems/picoruby-dvi/include/dvi.h`
127+
- `mrbgems/picoruby-dvi/ports/rp2350/dvi_output.c`
128+
- `mrbgems/picoruby-dvi/src/mruby/dvi.c`
129+
130+
**検証**: Ruby スクリプトから scroll_up, clear_range 等を呼び出し、DVI 画面で正しく描画されることを確認。
131+
132+
### Milestone 3: ビルド統合 + Machine ポート (Days 4-5)
133+
134+
Sandbox と Editor::Buffer をビルドに追加し、Machine モジュールのポートを実装する。
135+
136+
**ビルド設定変更** (`build_config/harucom-os-pico2.rb`):
137+
```ruby
138+
conf.gem core: 'picoruby-editor' # Editor::Buffer
139+
conf.gem core: 'picoruby-sandbox' # eval 隔離
140+
conf.gem core: 'picoruby-machine' # シグナル管理
141+
conf.gem core: 'picoruby-env' # Sandbox 依存
142+
```
143+
144+
**Machine ポート実装**:
145+
- `Machine.signal_self_manage` / `Machine.check_signal` / `Machine.pop_signal_self_manage`: hal.c の sigint_status と統合
146+
- `Machine.reboot`: `watchdog_reboot()` で実装
147+
148+
**picoruby-io-console は追加しない**: Keyboard は USB::Host API を直接使い、Sandbox は io-console に依存しないため不要。hal.c の `io_raw_q()` / `io_echo_q()` スタブはそのまま維持。
149+
150+
**変更ファイル**:
151+
- `build_config/harucom-os-pico2.rb`
152+
- `CMakeLists.txt` (ソース・インクルードパス追加)
153+
154+
**検証**: `rake` がエラーなくビルド完了。
155+
156+
### Milestone 4-7: Console + IRB, エディタ, picorabbit, ポリッシュ (Days 5-14)
157+
158+
Milestone 3 までが完了すれば基盤 (キーボード入力、DVI テキスト API、ビルド統合) が揃う。
159+
Milestone 4 以降は直列に依存しており、実装しながら詳細を詰める。以下は現時点の方針。
160+
161+
---
162+
163+
#### Milestone 4: Console + IRB (Days 5-8)
164+
165+
DVI テキストモード上で動作する IRB を実装する。プロジェクトのコア機能。
166+
167+
**Console クラス (Ruby, 新規)**:
168+
- DVI::Text API を直接使ったテキスト UI 基盤
169+
- カーソル位置管理 (col, row)
170+
- 文字出力: put_char でカーソル位置に配置、カーソル前進、行末折り返し、画面末スクロール
171+
- 行クリア、画面クリア
172+
- カーソル描画 (属性反転トグル)
173+
- UTF-8 文字列出力 (DVI::Text.put_string に委譲)
174+
175+
**IRB (Ruby, 新規)**:
176+
- Console + Editor::Buffer + Sandbox の組み合わせ
177+
- プロンプト表示 (`irb> `)
178+
- キー入力ループ: Keyboard#read_char -> Editor::Buffer.put
179+
- Enter 時: try-compile による複数行判定 (`begin; _ = (...); rescue => _; end; _`)
180+
- 実行: Sandbox.execute -> result.inspect で結果表示
181+
- ヒストリ: 配列に保存、上下キーで切り替え
182+
- Ctrl-C: 実行中断
183+
184+
**ブートシーケンス変更** (`src/main.c`):
185+
```ruby
186+
# ファイルシステムマウント + USB host タスク (既存)
187+
# ...
188+
# IRB 起動
189+
if VFS.exist?("/flash/main.rb")
190+
load "/flash/main.rb"
191+
else
192+
require 'irb' # /flash/irb.rb を load
193+
end
194+
```
195+
196+
IRB の Ruby コードは `/flash/irb.rb` として配置するか、ファームウェアに埋め込む。
197+
198+
**検証**: 起動後 IRB プロンプトが表示され、`1 + 1` -> `=> 2` が動作すること。
199+
200+
### Milestone 5: テキストエディタ (Days 8-11)
201+
202+
IRB から呼び出せるテキストエディタを実装する。
203+
204+
**Editor (Ruby, 新規)**:
205+
- Console + Editor::Buffer による全画面エディタ
206+
- Editor::Buffer のダーティフラグで効率的な差分描画
207+
- 基本操作: カーソル移動 (矢印、Home、End)、文字入力、バックスペース、デリート
208+
- 行操作: 行挿入 (Enter)、行削除
209+
- ファイル操作: 保存 (Ctrl-S)、終了 (Ctrl-Q)
210+
- ステータスバー: ファイル名、行番号、変更フラグ
211+
212+
**IRB からの起動**:
213+
```ruby
214+
irb> require 'editor'
215+
irb> Editor.new.open("/flash/hello.rb")
216+
```
217+
218+
**画面構成**:
219+
```
220+
行 0: ステータスバー (ファイル名、行番号)
221+
行 1-35: テキスト編集領域 (35行)
222+
行 36: コマンドバー (Ctrl-S:Save Ctrl-Q:Quit)
223+
```
224+
225+
**検証**: エディタでファイルを開き、編集、保存、終了してIRBに戻れること。
226+
227+
### Milestone 6: picorabbit 移植 (Days 11-13)
228+
229+
プレゼンテーションツールを Harucom 上で動作させる。
230+
231+
**DVI::Graphics 描画追加 (C)**:
232+
- `DVI::Graphics.draw_text(x, y, text, color)` -- 8x8 フォント (font8x8_basic)
233+
- `DVI::Graphics.draw_line(x0, y0, x1, y1, color)` -- Bresenham
234+
- `DVI::Graphics.draw_image(data, x, y, w, h)` -- 画像ブリット
235+
- `DVI::Graphics.draw_image_masked(data, mask, x, y, w, h)` -- 透過画像
236+
237+
**画像アセット**: picorabbit の `scripts/convert_image.rb` で変換、C ヘッダーとしてファームウェアに埋め込み
238+
239+
**スライドロジック (Ruby)**: picorabbit の main_task.rb を 320x240 座標系に移植
240+
241+
**入力**: GPIO ボタンを USB キーボードに変更 (l=次, h=前, q=終了)
242+
243+
**モード切り替え**: IRB -> `DVI.set_mode(DVI::GRAPHICS_MODE)` -> picorabbit -> `DVI.set_mode(DVI::TEXT_MODE)` -> IRB
244+
245+
**検証**: IRB から picorabbit を起動し、スライド表示・切り替え・IRB 復帰が動作すること。
246+
247+
### Milestone 7: ポリッシュ (Days 13-14)
248+
249+
- ブート画面 (Harucom OS バナー)
250+
- DVI 診断出力を UART のみに制限
251+
- キーリピートのチューニング
252+
- 安定性テスト (長時間動作、メモリリーク確認)
253+
- flash 書き込み中の DVI ブランキング確認 (エディタ保存時)
254+
255+
## 依存関係
256+
257+
```
258+
Milestone 1 (Keyboard) ──┐
259+
├──> Milestone 3 (Build) ──> Milestone 4 (IRB)
260+
Milestone 2 (DVI API) ───┘ │
261+
v
262+
Milestone 5 (Editor)
263+
264+
v
265+
Milestone 6 (picorabbit)
266+
267+
v
268+
Milestone 7 (Polish)
269+
```
270+
271+
## リスクと対策
272+
273+
| リスク | 影響 | 対策 |
274+
|---|---|---|
275+
| Machine ポートの複雑さ | 中: Sandbox が動かない | 最小実装から開始 (signal_self_manage のみ) |
276+
| picorabbit 解像度差 (640 vs 320) | 中: 表示品質 | 320x240 で再設計 (最も現実的) |
277+
| Editor::Buffer のビルド統合 | 低: 依存 gem の連鎖 | 最小限の gem セットで開始 |
278+
| SRAM 不足 (mrbgem 追加後) | 低: 現在 334KB 余裕 | サイズ監視、不要機能は除外 |
279+
280+
## 設計方針メモ
281+
282+
### Editor::Buffer を共通基盤とする設計
283+
284+
Editor::Buffer は I/O に依存しない純粋なデータモデル。
285+
Harucom OS の IRB/Editor は Editor::Buffer の上に独自の I/O 層 (Console + Keyboard) を構築する。
286+
287+
```
288+
Harucom: Console (DVI::Text) + Keyboard (USB::Host) -> Editor::Buffer
289+
R2P2: Editor::Line/Screen (ANSI + STDIN) -> Editor::Buffer
290+
```
291+
292+
この構造により、picoruby-vim のモード管理ロジック等を将来 Harucom に持ってくる際も、
293+
Editor::Buffer への操作部分は再利用し、I/O 層だけ差し替えればよい。
294+
295+
### HAL の I/O 分離
296+
297+
HAL (hal_write / hal_getchar) は UART デバッグ専用として維持し、変更しない。
298+
ユーザー向け I/O (画面表示、キーボード入力) は Ruby レイヤーで DVI::Text と USB::Host を直接使う。
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# ビルドサイズとメモリ予算
2+
3+
## 調査結果サマリー
4+
5+
現在のファームウェアは 1.1MB で、8MB の firmware 領域に 6.9MB の余裕がある。
6+
DVI::Graphics フレームバッファは SRAM に 76.8KB 確保。
7+
mrbgem 追加によるサイズ増加は管理可能な範囲。
8+
9+
## 詳細
10+
11+
### 現在のビルドサイズ
12+
13+
| 項目 | サイズ |
14+
|---|---|
15+
| harucom_os.elf | 2.3 MB |
16+
| harucom_os.bin | 1.1 MB (1,108,648 bytes text) |
17+
| harucom_os.uf2 | 2.2 MB |
18+
| bss (SRAM 使用) | 190,532 bytes |
19+
| data | 2,048 bytes |
20+
21+
### Flash レイアウト
22+
23+
```
24+
0x00000000 - 0x007FFFFF (8 MB): ファームウェア領域
25+
0x00800000 - 0x00FFFFFF (8 MB): FAT ファイルシステム
26+
```
27+
28+
firmware 領域の残り: 8 MB - 1.1 MB = **6.9 MB**
29+
30+
### SRAM 使用量
31+
32+
RP2350 メイン SRAM: 520 KB
33+
34+
主要な使用先:
35+
- テキスト VRAM: ~15.7 KB (106x37x4 bytes)
36+
- グリフキャッシュ (narrow + wide): ~32.6 KB
37+
- ラインバッファ: ~5.2 KB
38+
- グラフィックスフレームバッファ: 76.8 KB (320x240)
39+
- Core 0 スタック (BSS): 32 KB
40+
- Core 1 スタック: 4 KB
41+
- Core 1 ベクタテーブル: 272 bytes
42+
- stdin ringbuffer: ~260 bytes
43+
- BSS その他: ~24 KB (概算)
44+
45+
合計 BSS: 190,532 bytes (~186 KB)
46+
SRAM 残り: ~334 KB
47+
48+
### PSRAM 使用量
49+
50+
APS6404L 8 MB 全体を mruby ヒープとして使用。
51+
XIP マッピング (キャッシュ経由): 0x11000000 - 0x117FFFFF
52+
53+
### mrbgem 追加による影響の見積もり
54+
55+
追加予定の mrbgem:
56+
- picoruby-sandbox: C + Ruby コード、タスク管理ロジック (~10-20 KB text)
57+
- picoruby-machine: ハードウェア制御ポート (~5-10 KB text)
58+
- picoruby-env: 環境変数管理 (~2-5 KB text)
59+
60+
概算サイズ増加: 20-40 KB (firmware text)
61+
62+
picorabbit 画像アセット追加時: ~200 KB (RGB332 画像データ、flash に配置)
63+
64+
合計でも firmware 領域の余裕 (6.9 MB) に対して十分に小さい。
65+
66+
### DVI::Graphics フレームバッファ
67+
68+
ファイル: `mrbgems/picoruby-dvi/ports/rp2350/dvi_output.c` (191行)
69+
70+
```c
71+
static uint8_t framebuf[DVI_GRAPHICS_WIDTH * DVI_GRAPHICS_HEIGHT]; // 76,800 bytes
72+
```
73+
74+
メイン SRAM に静的確保。PSRAM ではない。
75+
ダブルバッファリング未実装 (シングルバッファ)。
76+
77+
もし 640x240 に拡大する場合: 追加 76.8 KB で合計 153.6 KB。SRAM 残量 (~334 KB) から確保可能だが、他の用途を圧迫する。
78+
79+
## マスタープランへの示唆
80+
81+
- ファームウェアサイズの制約は問題なし (6.9 MB の余裕)
82+
- SRAM はやや tight だが現状の 320x240 フレームバッファなら問題なし
83+
- picorabbit の画像アセット (~200 KB) は flash 直接配置で対応
84+
- mrbgem 追加のサイズ影響は軽微

0 commit comments

Comments
 (0)