ハードディスクを使ったMP3プレイヤーの製作


ハードディスクを使って、音楽がやたらたくさん入るMP3プレイヤーの製作をしようと考えた
きっかけは、
・音楽は聴きたいときに聴きたい音楽が聴けるべきだ
 仕事と育児に追われる生活では、音楽をゆっくりきけるのは通勤電車の中ぐらいしか時間が取れない。このとき、「今日は天気が良いから○○を聴きながら行こう」などと、その場で選曲できたら、素敵かもしれない
で、MP3デコーダチップを若松通商から入手し、HDDアクセスのテストでもしようかと思っているうちに、「iPod」が発売されてしまった。ここでかなりひるんだが、HDD容量が最大10GB(約、160時間分に相当、CD135枚分)に限定されていることなど、少々不満が残るので、この際、容量最重視のものを作ってしまうことにする(いまいち説得力がない...)
当面、AKI-H8でテストを行い、目処がたったら基板を起して携帯化しようと思う

'02/5/5、22:00〜4:30
 とりあえずHDDをAKI-H8のバスにつなぎ、アクセスを試みた。
実験機
HDDとAKIのバス(16ビット)の上位下位を反転することも考えたが、あまりメリットもないので、直結することにした。AKIはMODE5で使う。
AKI-H8には、シリアルで応答するモニタを載せ、ハイパーターミナルでコマンドを打ってチェックプログラムゐ操作するようにした
PIO-MODE0だと、アクセスタイム600nsecなので、Waitが要りそうだが、とりあえず何もしないバスにで直結し、一応コマンドのやりとりはできるようになり、スタンバイにするとモータが停まり、IDLEにすると復帰することは確認できた。また、IDENTIFY DEVICEコマンドで、HDDの情報が取り込めるようになった
'02/5/6、22:00〜24:00
コマンドが実行できるようになったので、セクタリード、セクタライトコマンドはすぐに実装できた。一応、ちゃんと読書きできているようだ。
実は、カンニングペーパとして使っている、「インターフェース」のIDE/ATAPI特集の、PIO-DATA-INコマンドのフローチャートに1箇所ミスがある。ディスクにコマンド(セクタリードなど)を送った後、データが準備できたらDRQ=1になるので、これを待って読み出しを開始するが、フローチャートでは、「DRQ=0を待つ」となっていて、これではデータが準備できる前にゴミを読み出して終わってしまうので、ここは常識に照らし合わせて修正(なぜか、PIO-DATA-OUTコマンドのフローチャートは正しい
AKI-H8はRAMが4Kしかない。本当は、1分(1MB)ぐらいのバッファを設け、いちどきにHDDからデータを読み出して、しばらくはRAMでデータを供給、HDDは止めておくのがバッテリ寿命を長くできるが、当面、この4KのRAMでどこまでできるかやってみることにする。というわけで、BIOSとしてはディスクバッファを持たず、アプリ側で必要に応じて確保する実装とする(アプリの用意したバッファに直接読みこむ

ファイルシステムの検討
曲のダウンロードや削除を考えると、HDDべた書きにするより、なんらかのファイルシステムを入れる必要がある。UFSが効率がよさそうだが、RAM上に大きなテーブルを持つ必要がありそう。というわけで、独自のFAT16システムを開発することにした。これで、10GBのときのクラスタサイズは150KB程度と、音楽専用なら悪くない。

02/5/8,24:00〜26:00
前回、セクタライト・リードが完成したと思っていたが真っ赤なうそだった。実は、non-data-commandを実装し、それをコピーしてpio-data-inコマンドとpio-data-outコマンドの骨格を作り、リードだけ作った状態で力尽きて、できたと勘違いしていた。そこでライトもちゃんと作る。
昨日は残業で、さすがに6:00起きで午前様はちょっと辛い。寝そうになりながら実装した。
簡単なチェックで一応正しく書きこんでいることがわかったので、全セクタに値を書いてべリファイする簡単なコマンドを作った。1セクタづつ内容をちょっとずつずらし、上書きしたらある程度わかるようにした。これを使って、ライト・ベリファイを行いOK.
ついでにデータ転送時間を測定したところ、約400KByte/secと、予想していたより良好なパフォーマンスだった。なお、HDDは古いLibretto30についていた500MBのもの。AKI-H8は16MHzで動作させ、ディスクリード、ライトの部分は、
for(i = 0;i < 512/2;i++) {
HDD = *ptr++;
}
こんなコード。ここをアセンブラで書き直すかDMAにすると、さらに高速になるだろう(MP3プレイヤーに必要な速度は数十KByte/secなのでそこまでしなくてもいいが、その分CPUのクロックを落として消費電力を下げたら有効)

02/5/9 22:00-24:00
セクタ読書きの確認の仕上げに、少しHDDをいじめてみることにした。これまでのテストはセクタを順にスキャンするものだったが、ランダムな順でライトリードベリファイを行ったらどうなるか。
セクタを表す数値(ここでは500mBのHDDなので20bit)のビット順を上位下位反転して(FFTのビットリバースと同じ)与えてみたところ、これまで音もなく読書きしていたものが、とたんに「カラカラカラカラ」と忙しい音がするようになった。この状態でライトべりファイを確認しOKであった。
この状態でデータ転送速度を測定したところ、セクタあたりの書き込み時間が平均約25msec、以前のセクタを順番に書いたときの、約1msec/セクタと比べると20倍以上になり、平均シークタイムのオーダになった。データ転送速度としては20KByte/sec程度と、MP3プレイヤーとしてもぎりぎりの速度となった(1MB/分の場合で計算すると16KByte/sec必要)。ま、フラグメンテーション対策までしなくともなんとかなるでしょう。

02/5/10
ハードディスクの不良セクタについて急に不安になったので、IDEのコマンドをいろいろ調べたが、不良セクタ情報を取得するコマンドは見当たらないので、先輩に相談。どうも最近のHDDはドライブが勝手に不良セクタを検出して予備セクタと入れ替えるみたいで、外から不良セクタは見えないようですね。予備がなくなったらセクタ書き込みができなくなるかなんか、外から見えるようになるが、そこまで壊れたら老い先長くないかもしれない、ということで今回は不良セクタは考えないことにする

02/5/19
しばらく日付が飛んでいるが、BIOSができてしまったので、いよいよファイルシステムの設計を行った。簡易実装にしたいのでFAT方式。音楽専用なんでクラスタサイズが大きくても平気ということで、FAT16に決定。適当にディレクトリフォーマットやセクタサイズ計算方法なんかを決めたので、いよいよ実装。とはいっても、いきなりAKI-H8の上で作るのも大変だし、セクタリードライトをメモリリードライトに置き換えたら別にハードウェアはなくても作れるので、通勤途中にC1でC++Builderの上で少しづつ書いている。

■参考文献
・インターフェース
・H8-3048Fハードウェアマニュアル、日立製作所
ホームページに戻る