我的测试代码以 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 首先将第一个扇区读入暂存缓冲区,非常棒。然后它 memcpy 的零进入暂存缓冲区,太好了。在 memcpy 512 个零之后,它需要提交扇区并移动到下一个扇区。
正是在这一点上,代码被混淆了。它将零的暂存缓冲区写入 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 解决过这样的问题吗?