ライン

PIC32MX150F用SDカードブートローダの製作

ライン

2014年3月9日

Rev.2公開 2015年11月21日

 これまでカラービデオ信号出力の実験でいくつかのゲームやデモアプリケーションを製作してきましたが、アプリケーションの数だけハードを作るか、切り替えるためにいちいちPICkitなどでPCにつないでプログラムの書き換えをする必要がありました。
 そこで1つのハードウェアで簡単にアプリケーションが切り替えられるよう、SDカードブートローダを製作しました。これにより、複数のHEXファイルをSDカードに入れておき、テレビ画面を見ながら選択してプログラムの書き換えができるようになりました。1つのハードでパックマンもテトリスも簡単に切り替えて実行できるようになるので、まるで汎用ゲーム機のような感覚で遊べるようになりました。
(2014.4.29)おまけを追加しました。
(2015.4.29)KM-BASICについてを追加しました。
(2015.5.9)アプリ・ゲーム集を追加しました。
(2015.11.21)仕様変更を伴うバージョンアップを行いました。旧バージョンはこちらになります。

回路

 これまで製作したPIC32MX1xxシリーズのカラービデオ出力実験回路に、空きピンを使って、SDカードスロットを接続しました。また、リセットを行う機会が増えるので、リセットボタンも追加しました。
 使用したPICマイコンはPIC32MX150F128Bです。PIC32MX250F128Bでも使用可能です。それ以下のPIC32MX1xx/2xxではフラッシュメモリの容量が小さいため、使用することができません。
 空きポートを増やしたかったので、SDカードスロットのCD(Card Detect)のチェックは行わないように変更しました。(RA1ポートの開放)(Rev.2より)
 また、WE(Write Enable)のチェックも行わないので、接続不要です。
 ICSP端子は一度ブートローダプログラムさえ書き込んでしまえば使うことがないので、省略してもよいでしょう。その場合は、別の方法でブートローダ自体の書き込みを行ってください。

回路図

ハードウェア製作

 以前ユニバーサル基板で製作したハードに、無理やりSDカードスロットを追加しました。SDカードスロットと言っても、実際にはマイクロSDからSDへの変換アダプターを直付けして流用しました。
 電源は元々がACアダプタと乾電池の両対応だったのでそのままですが、乾電池2本ではSDカードの電源としては厳しいものがあります。使用しているうちにSDカードを認識しなくなることがあるので、なるべく安定した電源を用意してください。
 

製作写真

ブートローダプログラム

 PIC32用のブートローダはマイクロチップのアプリケーションノートAN1388で公開されています。USB版やUART版等と共にSDカード版も公開されているので、これを改造しました。SDカードへのアクセスやHEXファイルのデコード、フラッシュ書き込みなどはそのまま使い、HEXファイルの一覧をテレビ画面上に表示し、ボタンで選択する機能を追加しました。画面への出力は以前作成したカラーテキストビデオ出力実験を応用しました。
 今回のシステムのメモリーマップは右図のようになります。PIC32MX1xx/2xxシリーズのブートフラッシュ領域はわずか3Kバイトしかありません。これではブートローダ本体はとても入らないので、ブート領域にはリセット後の初期化コードだけとし、通常のプログラム領域の最初の部分にブートローダを格納することにしました。
 実際に作成してみると、SDカードへのアクセスやビデオ出力機能があるため、割り込みベクタテーブルも含め実に22Kバイトもの大きなブートローダとなってしまいましたが、PIC32MX150F128Bのプログラムフラッシュは128Kバイトもあり、まだユーザアプリケーション領域として100Kバイトも使えるので、これでよしとしました。
 前回のバージョンではロードファイル名とハイスコア記録領域がプログラムフラッシュの最後尾(1D00 F800〜)にありましたが、ユーザアプリケーション領域の前に移動しました。ブートローダの割り込みベクタとプログラムの圧縮を図ったので、ユーザアプリケーション領域の先頭アドレス変更はありません。そのため、従来のHEXファイルもそのまま利用可能ですが、従来のハイスコア領域は消されるのでハイスコアが残りません。(Rev.2)

メモリーマップ
メモリーマップ(Rev.2)

ユーザプログラムの作成方法

 ブートローダ対応のプログラムを作成する場合、通常とは異なる点がいくつかありますので、以下にご注意ください。

1.メモリ配置の設定

 何も指定せずにPIC32MX150F128B用のプログラムをMPLABやMPLAB Xでビルドすると、ブート領域に初期化コード、プログラム領域のトップから割り込みベクタとプログラム本体が配置されます。これではブートローダと重なってしまい正常にロードできません。そのため、全て上述のユーザアプリケーション領域に配置されるように指定する必要があります。指定にはリンカスクリプトを使用します。専用のリンカスクリプト用意しましたので、単純にプロジェクトに追加してビルドしてください。(ファイル名App_32MX250F128B.ld)
 なお、以前のC32コンパイラを使用する場合、69行目と70行目にあるOPTIONALの行の先頭を「// 」でコメントアウトしてください。

2.コンフィグレーション設定について

 ブートローダを使用する場合、デバイスのコンフィグレーションはブートローダ側で設定されているため、ユーザプログラムではコンフィグレーションを記述する必要がありません。記述されていても無視されます。ただし、私のビデオ出力システムでは種類によって、システムクロックのPLL設定が外部発振子の15倍だったり16倍だったりと異なるため、コンフィグレーションではなくプログラム内で動的に設定変更する必要があります。具体的には、ブートローダ自体は16倍設定で動作しているので、16倍の場合は変更不要ですが、グラフィック版のシステムは15倍で作成しているので、設定変更が必要です。動的なシステムクロック変更は面倒なので、マイクロチップが提供しているライブラリを使いました。15倍にするにはmain関数の最初に以下のように記述します。

 OSCConfig(OSC_POSC_PLL, OSC_PLL_MULT_15, OSC_PLL_POST_1, 0);

サンプルプログラムに入れたパックマンも15倍で動作させているので、参考にしてください。

3.ハイスコアの記録

Rev.2で仕様変更あり

 PIC32シリーズには8ビットPICのようなEEPROMがないため、ゲームのハイスコアの記録には、これまでプログラムフラッシュ領域の最後のほうに書き込みを行っていました。ブートローダで複数のゲームを切り替えて使う場合、他のゲームを実行してもハイスコアが消去されないようにする必要があります。そこで、ブートローダ対応アプリケーション用に、ハイスコア等のデータを保存する共通の仕組みを提供しました。
 1つのアプリケーションに16バイトのレコードが割り当てられ、HEXファイルのファイル名(8文字分)で管理を行います。利用可能なレコード数は63個となります。
 プロジェクトにrecscore.cとrecscore.hを追加しておくと、以下の関数が使用できるようになります。

ハイスコアテーブル

 void init_recscore(void)
  アプリケーションの最初に利用のための初期化を行います。この関数を呼び出すと、テーブル内のレコードを検索し、ロードしたHEXファイル名のレコードが存在しない場合は新規でレコードを作成します。

 void write_recscore(unsigned int s1,unsigned int s2)
  初期化で設定されたレコードに2つの32ビットデータを書き込みます。実際にフラッシュの消去と書き込みを行うため、呼び出す前にstop_composite()関数で映像出力を停止して割り込みが発生しないようにします。また、書き込み終了後は、start_composite()で映像出力を再開します。

 unsigned int read_recscore(int n)
  レコードに書き込まれたn番目の32ビットデータを読み出します。nは0〜1で指定します。

 PIC32MX1xx/2xxシリーズのフラッシュメモリは、1Kバイトのページ単位で消去を行ってから書き込む必要があります(ちなみにPIC32MX3xx以上は4Kバイト単位)。そこで記録場所としてブートローダプログラム直後の1Kバイトを割り当てました。またページ消去したときに他のゲームのハイスコアが消えてしまうと困るので、ワーク用に1Kバイトを使用します。(RAM容量が小さいのでフラッシュで代用。)


ブートローダの使い方

 最初にブートローダプログラムをPICに書き込みます。この時はPICkit3などの書き込み器が必要です。次にSDカードに上述の方法で作成したアプリケーションのHEXファイルをコピーします。HEXファイルのファイル名は、半角8文字以内+「.hex」です。ロングファイル名や日本語文字は使用できません。また大文字小文字の区別はありません。SDカードはFATまたはFAT32フォーマットのものが使用できます。
 MPLAB XではHEXファイルはプロジェクトフォルダ配下の「dist\default\production」に生成されます。ファイル名が「プロジェクト名.X.production.hex」となりますので、コピーした後にファイル名変更してください。
 HEXファイルを保存したSDカードをSDカードスロットに挿入してボードの電源を入れると、ファイル選択画面が表示されます。もし、既に何らかのアプリケーションがロードされていれば、無条件にそのアプリケーションを実行します。他のアプリケーションをロードしたい場合は、どれかのボタンを押しながら、電源オンまたはリセットを行うことで、ファイル選択画面が表示されます。
 ファイル選択画面では、上下左右ボタンでファイルを選び、FIREボタンを押すと選択されたファイルをフラッシュに書き込んだ後、実行します。書き込み中は割り込み禁止のため、画面表示を停止します。そのため一瞬真っ黒になりますが、数秒で完了し、ユーザプログラムが始まります。
 なお画面表示の関係上、利用できるHEXファイルの最大数は75個となります。

選択画面


ダウンロード

 下記リンクから関連ファイル一式をダウンロードしてください。ブートローダのHEXファイルとソースファイル、ブートローダ対応アプリのサンプルとして、パックマン(グラフィック版)とテトリスのHEXファイルとソースファイルをそれぞれフォルダに分けてアーカイブしておきます。

関連ファイル一式のダウンロード (2015.11.21 Rev.2対応版に変更)

 いずれもHEXファイル以外の全ファイルをプロジェクトに追加してビルドすることで、HEXファイルが生成されるようになっていますが、最適化は適宜行う必要があります。特にブートローダは22Kバイトに収めるために、最適化や16ビットコードの生成など設定の工夫が必要ですので、特に理由がなければダウンロードしたHEXファイルをそのまま書き込んで使用してください。
 なお、ブートローダはCのソースファイルが6個とヘッダファイルが12個、リンカスクリプトが1個の計19個ものファイルに分かれてしまっています。また、マイクロチップ社作成のプログラムを改造したものなので、コメントが英語と日本語入り乱れていて、大変読みにくくなっていますし、英語のコメントに合っていない部分もありますが、気にしないでください。
 テトリスは元々PIC32MX120F032B用に作成したものですが、ブートローダ対応させる場合はデバイスとしてPIC32MX150F128B(またはPIC32MX250F128B)を指定して、ビルドしてください。
 対応コンパイラはC32またはXC32のv1.32以前です。XC32 v1.33以降には対応していません。また、C32コンパイラを使用する場合、リンカスクリプトの69行目と70行目にあるOPTIONALの行の先頭を「// 」でコメントアウトしてください。


最後に

 SDカードを利用したゲームプログラムの切り替えは、カラービデオ出力システムの開発当初から考えていましたが、ブート用フラッシュメモリが小さく、実現できずにいました。しかし、PIC32MX150F128Bでは128Kバイトものプログラム用フラッシュがあるので、この一部を利用すればよいことに気付きました。
 実際に完成して使ってみると、使い勝手もよく、満足いくものとなりました。あとはゲームに限らず、アプリケーションを増やしていくといろいろ楽しめそうです。せっかくSDカードもつながったので、アプリケーション側からSDカードを使うというのもいいですね。
 何かご不明点やご意見などありましたら、お気軽にこちらの掲示板に書き込んでください。


おまけ 「SDカードアクセスライブラリ」

(2014.4.29追加)
(2015.11.21更新)
 上述したアプリケーション側からSDカードを使うためのライブラリを作成しました。ご自由にご利用ください。こちらもマイクロチップ社製のファイルシステムとSDカードライブラリを利用しています。FAT32対応で、書き込み機能も使えます。関数やマクロの一覧が掲載されたヘルプファイルも添付しておきます(英文)。ただし、全ての機能が使えるわけではありません。
 また、デモプログラムも作成しました。ご利用の参考にしてください。

関連ファイル一式のダウンロード

各ファイルの説明

<SDカードアクセス関連>
 libsdfsio.a SDカードアクセスのライブラリファイル本体
 SDFSIO.h  ライブラリ利用のためのヘッダーファイル
 MDDFS Library Help.chm マイクロチップ社製ファイルシステムのヘルプファイル

<デモプログラム>
 sdlibdemo.c     デモ用メインプログラム
 lib_colortext32.a  キャラクター版カラービデオ出力ライブラリ
 colortext32.h    キャラクター版カラービデオ出力ライブラリ用ヘッダー
 App_32MX250F128B.ld ブートローダ対応用リンカースクリプト

 上記全てのファイル(ヘルプファイル以外)をプロジェクトに追加し、ビルドして出来上がったHEXファイルをSDカードにコピーし、ブートローダから起動すると、SDカード内のテキストファイル一覧が表示されます。方向ボタンでファイル選択して、FIREボタンを押すと画面にテキストファイルの内容が表示されます。

注意事項/制限事項

・ロングファイル名は使用できません。8.3形式のファイル名のみ使用可です。
・同時にオープン可能なファイル数は2つまでです。
・メディアのフォーマット機能は搭載していません。
・FSfprintf関数は搭載していません。
・使用方法によっては、ファイルの消滅などの恐れがあります。重要なファイルは必ずバックアップをとってください。
 実際、私もプログラムミスでSDカード内のファイルが全滅する事故を経験しました。
 当方およびマイクロチップ社は、生じた損害に対していかなる責任も負いません。


KM-BASICについて

(2015.4.29追加)
 MZ-80Kエミュレータの作者であるKatsumi氏が、本システム用にBASICプログラミング環境を作成してくれました。下記サイトから実行環境やソースファイル等がダウンロード可能です。

KM-BASIC for MIPSの紹介(電子ブロック工房)

 (2015.12.24) SDカードブートローダ Rev.2対応になりました。
 また、こちらの回路のPS/2キーボードにも対応してくれました。

 使い方は簡単で、まず実行したいBASICのソースプログラムをPC等で作成します。そのソースファイルを例えば「hogehoge.txt」としてSDカードに保存しておき、ダウンロードした「basic.hex」を「hogehoge.hex」にファイル名変更し、同じSDカードに保存してブートローダを立ち上げます。ブートローダで「hogehoge」を選択すると、hexファイルをフラッシュに書き込んでブートし、自動でソースファイルを読み込みコンパイルが完了し、実行されます。
 複数のBASICプログラムを保存したい場合は、その数だけ「basic.hex」のコピーおよび同名の.txtファイルを用意しておくことで可能となります。
 KM-BASICはインタープリタ方式と違い、実行前にコンパイルする方式のため、パフォーマンスが非常によく、また本システムの特徴であるカラー表示やサウンド出力にも対応しています。文法やその他の詳細は作者のページをご参照ください。

KM-BASIC画面1

サンプルプログラム ダウンロード

CLS
M=15:N=13
FOR C=1 TO 7
R=C*2-1
COLOR C
GOSUB CIRCLE
NEXT
LABEL ENDL
GOTO ENDL

LABEL CIRCLE
X=R:Y=0:F=-2*R+3
D$=CHR$($EC)
LABEL CIRLP
IF X<Y THEN RETURN
CURSOR M-X,N-Y:PRINT D$;
CURSOR M-X,N+Y:PRINT D$;
CURSOR M+X,N-Y:PRINT D$;
CURSOR M+X,N+Y:PRINT D$;
CURSOR M-Y,N-X:PRINT D$;
CURSOR M-Y,N+X:PRINT D$;
CURSOR M+Y,N-X:PRINT D$;
CURSOR M+Y,N+X:PRINT D$;
IF F>=0 THEN X=X-1:F=F-X*4
Y=Y+1:F=F+Y*4+2
GOTO CIRLP


アプリ・ゲーム集

(2015.5.9) 公開開始
(2015.11.21) Rev.2対応版にHEXファイルを更新
 本システムで利用できるゲーム、アプリケーションのHEXファイルをまとめてダウンロードできるようにしました。
 SDカードのルートフォルダに全てコピーするだけで利用可能です。
 今後、機会があればどんどん充実させていきたいと思います。

トップ画像

アプリ・ゲーム集のダウンロード
HEXファイル名アプリ名
TETRISテトリス
PACMANパックマン(キャラクター版)
PACMAN-Gパックマン(グラフィック版)
HAKOMUSU箱入り娘パズル
BREAKOUTブロック崩し

Copyright (C) KenKen All Rights Reserved.