SD カード上の既存の大きなファイル test.dat で始まるテスト コードがあり、テストは次のことを行います。
f_open(&fp, "test.dat", FA_OPEN_ALWAYS|FA_READ|FA_WRITE);
f_write(&fp, bufferOfZeros, 4096, &ioBytes);
まっすぐに見えます。
f_write の結果は、SD カードの破損です。
組み込みデバイスの EDMA をトレースして、FatFの読み取り/書き込み要求を監視しました。f_open 読み取り要求はすべて正常で、ファイルと FAT テーブルを適切に検出します。
f_write は、最初のセクターをスクラッチ バッファーに読み込むことから始まります。次に、ゼロをスクラッチ バッファに memcpy します。すばらしいです。512 個のゼロの memcpy の後、セクターをコミットして次のセクターに移動する必要があります。
コードが混乱するのはこの時点です。そのゼロのスクラッチ バッファを FAT テーブルに書き込みます!!
ff.c/f_write() の問題のあるコードは次のとおりです。
if (fp->flag & FA__DIRTY) { /* Write-back sector cache */
if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
ABORT(fp->fs, FR_DISK_ERR);
fp->flag &= ~FA__DIRTY;
ここで、fp->buf はゼロのセクター バッファーですが、fp->dsect は FAT セクター (8318) であり、ファイル データ セクター (10240) ではありません! おっとっと。disk_write() で、fp->buf は fp->sect に一致します。
ここでは基本的な使用例のように思えますが、これを見てショックを受けました。
世界中の誰かが、以前に FatFs でこのような問題を掘り下げたことがあることを願っていますか?