我有一个测试代码,它从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,以观察FatFs的读/写请求。f_open读取请求都是健康的,它们正确地找到了文件和FAT表。
f_write从将第一个扇区读取到暂存缓冲区开始,非常好。然后它将零存储到暂存缓冲区中,非常好。在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上发现过这样的问题吗?
Clifford是正确的-这是我的一个问题,我知道这样一个简单的用例必须工作。
我把测试切换到
f_open(&fp, "test.dat", FA_OPEN_ALWAYS|FA_READ|FA_WRITE);
f_write(&fp, pattern, 512, &ioBytes);
f_lseek(&fp, 0);
f_read(&fp, zeroedBuffer, 512, &ioBytes);
这揭示了一个缓存问题。f_read操作成功,DMA完成得很好,但由于L0未刷新,所以zerodeBuffer保持不变。因此,FatFs看到了正确价值观和陈旧价值观的混合。我修复了EDMA缓存,现在一切正常。
另一个学习,TI Starterware附带R0.4b。我从它开始,它返回了令人困惑的FR_RW_ERROR。我升级到R0.11a,得到了更好的错误反馈。
有人知道FatFs的单元测试吗?