実質的にSDカードからブードが出来ることが分かったので、今度はブートするプログラムを
選択できるランチャーメニューを実装しました。
ランチャープログラムはEEPROM上に書きこみます。
ハードウエア的にリセットがかかるとEEPROM上のランチャーメニューが起動します。
ランチャープログラムは、選択されたプログラムをSDカードからロードしてメインRAM
に書きこみます。その後ソフトウェアリセットにより、ロードしたプログラムが実行されます。

操作としては、
ジョイスティック操作でメニューをスクロールさせて起動したいプログラムを選択します。
選択中のプログラムの説明を下段に表示します。
リセットボタンを押すことランチャープログラムがロードされて、メニュー画面に戻ります。
実際の操作の様子
(デジカメでの動画撮影なのでちょっと映像が劣化しています)
メニューに表示されるプログラム一覧は、SDカード内のテキストファイルに定義して
います。ランチャープログラムがその内容を読んで表示します。
ランチャーさえあれば、簡単にプログラムの入れ替えが出来ます。
SDカードだとプログラマやシリアル接続不要ですね。
こほ方式は色々と使えそうです。
ランチャープログラムのソースはこんな感じです。
{{
LameStation SDカードローダー
}}
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
'SDカード PIN接続
sdDO = 16 'EX0(P16)
sdCLK = 17 'EX1(P17)
sdDI = 18 'EX2(P18)
sdCS = 19 'EX3(P19)
VAR
'メニュー情報
byte text[2048] 'メニューファイルバッファ
long index[32] 'インデックス
long count '登録数
long pos 'メニューファイルバッファ用ポインタ
'メニュー表示用
long mnTop 'タイトル表示開始先頭番号
long mnSelect 'メニュー上の選択位置(0~3)
OBJ
cm : "LameSerial"
sd : "SD-MMC_FATEngine"
lcd : "LameLCD"
gfx : "LameGFX"
txt : "LameText"
fn : "LameFunctions"
ctrl : "LameControl"
font_6x8 : "gfx_font6x8_normal_w"
font_6x8b : "gfx_font6x8"
font_4x6 : "gfx_font4x6"
PUB Main | ctrlChange,prevCtrl,ctrlCode,fname,p
mnTop := 0 'ランチャーメニューリスト先頭
mnSelect := 0 '選択カーソル先頭
prevCtrl := 0
ctrlCode := 0
cm.Start
lcd.Start(gfx.Start)
gfx.ClearScreen(0)
count:= LoadMEnu 'メニューデータをSDカードからロード
DrawMenu 'ランチャーメニュー表示
'ランチャーメニュー 操作
repeat
'操作状態取得
ctrl.Update
prevCtrl := ctrlCode
if ctrl.B 'タイトルを選択決定した
p:= index[mnTop+mnSelect]
repeat while text[p++] <> 0
fname := @text[p]
quit
if ctrl.Down
ctrlCode := ctrl.Down
elseif ctrl.Up
ctrlCode := ctrl.Up
else
ctrlCode := 0
if prevCtrl <> ctrlCode
'操作に変化があった場合は表示の更新を行う
if ctrl.Down
if mnSelect < 3
mnSelect++
else
if mnTop < count-4
mnTop++
else
mnTop := 0
mnSelect := 0
if ctrl.Up
if mnSelect > 0
mnSelect--
else
if mnTop > 0
mnTop--
else
mnTop := count-4
mnSelect := 3
if ctrlCode <> 0
DrawMenu
Run(fname)
'メニュー画面表示
PUB DrawMenu |title,fname,info,i,p
'メニュー部
gfx.ClearScreen(0)
txt.Load(font_6x8b.Addr, " ", 6, 8)
txt.Str(string("[Menu]"),0,0)
'タイトルリスト部
txt.Load(font_6x8.Addr, " ", 6, 8)
repeat i from mnTop to (mnTop+4 <# count)-1
title := @text[index[i]]
if (i<10)
txt.Dec(i,12, 8 + (i-mnTop)<<3)
else
txt.Dec(i, 6, 8 + (i-mnTop)<<3)
txt.Str(String(":"), 17, 8 + (i-mnTop)<<3)
txt.Str(title, 23, 8 + (i-mnTop)<<3)
txt.Str(String("*"), 0, 8 + (mnSelect)<<3)
'選択したタイトルの説明表示
p:= index[mnSelect+mnTop]
repeat while text[p++] <> 0
repeat while text[p++] <> 0
txt.Load(font_4x6.Addr, " ", 4, 6)
txt.box(@text[p],0,40,128,18)
lcd.DrawScreen
'指定イメージファイルによるブート
PUB Run(filePathName) : statusVal | statusStr
ifnot sd.partitionMounted
Mount(0)
statusStr := \ sd.bootPartition(filePathName)
statusVal := sd.partitionError
PRI Mount(partition) : statusVal | statusStr
ifnot sd.CogStatus
Start
statusStr := \ sd.mountPartition(partition)
statusVal := sd.partitionError
PRI Start : okay | statusStr
ifnot sd.CogStatus
okay := sd.FATEngineStart(sdDO, sdCLK, sdDI, sdCS, -1, -1, -1, -1, -1)
'SDカードからメニュー情報を取得する
PUB LoadMenu | d,i
pos := 0
i := 0
'SDカードのマウント
sd.fatEngineStart(sdDO, sdCLK, sdDI, sdCS, -1,-1,-1,-1,-1)
sd.mountPartition(0)
if strcomp( sd.listEntry(@myfname), @myfname )
abort
'メニューファイルのオープン
sd.openFile( @myfname, "R" )
if sd.partitionError
cm.Str( string("File I/O Error.",13) )
abort
'データの読み込み
index[i]:=0
repeat while d := sd.readByte
if d == "|" 'カラム区切り
text[pos++] := 0
elseif d == $0a 'LFは行終端
text[pos++] := 0
index[++i]:= pos
elseif d => 32 'CRはスキップ '通常の文字
text[pos++] := d
'ファイルのクローズ
sd.closeFile
'パーティションのアンマウント
sd.unmountPartition
'エンジン解放
sd.FATEngineStop
result := i+1
DAT
'ファイル名
myfname byte "menu.txt",0
最近のコメント