OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 13631|回复: 13

Fatfs删除SD卡文件导致文件系统损坏

[复制链接]

3

主题

347

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
2082
金钱
2082
注册时间
2014-12-19
在线时间
711 小时
发表于 2014-12-19 16:30:27 | 显示全部楼层 |阅读模式
5金钱
Fatfs的版本是最新的R0.10c。
我目前用SPI的方式和SD卡通讯,在不断的摸索之后,读写终于正常了,虽然写卡的速度非常慢。
于是我继续添加其他功能,比如删除文件或文件夹。用的是fatfs官网的代码。
但每次删除完后,我把SD卡插到电脑上,检查磁盘都会显示检测到问题,然后自动修复了,并在SD卡里写入FOUNDxx文件夹。
有趣的是,我用以下函数删除文件或文件夹并不会返回错误。但为什么SD的文件系统却损坏了呢?
经查f_unlink函数在文件打开时可能导致卷损坏,但我的函数都会在打开文件之后关闭文件。
那么问题是, f_readdir和f_opendir会不会打开文件呢?从而导致删除文件时损坏文件系统。

检查磁盘的方法见链接:http://jingyan.baidu.com/article/a3a3f8118f24498da3eb8a48.html
FRESULT empty_directory(char *path)
{
    UINT i, j;
    FRESULT fr;
    DIR dir;
    FILINFO fno;
// path:Working buffer filled with start directory

#if _USE_LFN
    fno.lfname = 0; // Disable LFN output
#endif
//f_chdir
    fr = f_opendir(&dir, path);
    if (fr == FR_OK)
    {
        for (i = 0; path; i++);
        path[i++] = '/';
        for (;;)
        {
            fr = f_readdir(&dir, &fno);
            if (fr != FR_OK || !fno.fname[0]) break;
            if (_FS_RPATH && fno.fname[0] == '.') continue;
            j = 0;
            do
            {
                path[i+j] = fno.fname[j];
            }while (fno.fname[j++]);
            if (fno.fattrib & AM_DIR)
            {
               fr = empty_directory(path);
                if (fr != FR_OK) break;
            }
//The file/sub-directory must not be opened, Fatfs官方资料
//or the FAT volume can be collapsed.
//It can be rejected with FR_LOCKED when file lock feature is enabled.
            fr = f_unlink(path);
            if (fr != FR_OK) break;
        }
        path[--i] = '\0';
        f_closedir(&dir);
    }
    f_closedir(&dir);
    return fr;
}

最佳答案

查看完整内容[请看2#楼]

f_readdir,f_opendir不是文件操作,是文件夹操作。不会打开文件的。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-12-19 16:30:28 | 显示全部楼层
f_readdir,f_opendir不是文件操作,是文件夹操作。不会打开文件的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

347

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
2082
金钱
2082
注册时间
2014-12-19
在线时间
711 小时
 楼主| 发表于 2014-12-19 16:30:28 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
今天偶然在 FATFS的官网看到,原来是之前的f_unlink函数有问题,详见下面的网址
http://elm-chan.org/fsw/ff/patches.html
R0.10c版和R0.10b版均有此问题,各位要注意了,注意修改,否则使用删除功能时会导致文件系统损坏。

f_unlink function does not remove cluster chain of the file. It reads to a lost cluster of
the FAT volume. This is added at a bugfix of R0.10c.
f_unlink函数不会删除文件的簇链,它会一直读到FAT卷的一个丢失簇。

修改后的完整 f_unlink函数如下:
FRESULT f_unlink (
const TCHAR* path /* ointer to the file or directory path */
)
{
FRESULT res;
DIR dj, sdj;
BYTE *dir;
DWORD dclst = 0;
DEF_NAMEBUF;


/* Get logical drive number */
res = find_volume(&dj.fs, &path, 1);
if (res == FR_OK) {
INIT_BUF(dj);
res = follow_path(&dj, path); /* Follow the file path */
if (_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))
res = FR_INVALID_NAME; /* Cannot remove dot entry */
#if _FS_LOCK
if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open object */
#endif
if (res == FR_OK) { /* The object is accessible */
dir = dj.dir;
if (!dir) {
res = FR_INVALID_NAME; /* Cannot remove the origin directory */
} else {
if (dir[DIR_Attr] & AM_RDO)
res = FR_DENIED; /* Cannot remove R/O object */
}
if (res == FR_OK) {
dclst = ld_clust(dj.fs, dir);
if (dir[DIR_Attr] & AM_DIR) { /* Is it a sub-dir? */
if (!dclst) {
res = FR_INT_ERR;
} else { /* Make sure the sub-directory is empty */
mem_cpy(&sdj, &dj, sizeof (DIR));
sdj.sclust = dclst;
res = dir_sdi(&sdj, 2); /* Exclude dot entries */
if (res == FR_OK) {
res = dir_read(&sdj, 0); /* Read an item */
if (res == FR_OK /* Not empty directory */
#if _FS_RPATH
|| dclst == dj.fs->cdir /* or current directory */
#endif
) res = FR_DENIED;
if (res == FR_NO_FILE) res = FR_OK; /* It is empty */
}
}
}
}
if (res == FR_OK) {
res = dir_remove(&dj); /* Remove the directory entry */
if (res == FR_OK && dclst) /* Remove the cluster chain if exist */
res = remove_chain(dj.fs, dclst);
if (res == FR_OK) res = sync_fs(dj.fs);
}
}
FREE_BUF();
}

LEAVE_FF(dj.fs, res);
}
回复

使用道具 举报

3

主题

347

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
2082
金钱
2082
注册时间
2014-12-19
在线时间
711 小时
 楼主| 发表于 2014-12-22 08:21:05 | 显示全部楼层
但文件系统为什么会损坏呢?还是没答到点子上
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-12-22 19:47:34 | 显示全部楼层
回复【3楼】lvehe:
---------------------------------
这我也不晓得
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-12-25 23:17:06 | 显示全部楼层
回复【5楼】lvehe:
---------------------------------
谢谢分享
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

0

主题

25

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1664
金钱
1664
注册时间
2015-1-19
在线时间
330 小时
发表于 2015-2-11 10:06:14 | 显示全部楼层
我也是用Fatfs的版本是最新的R0.10c , 已经在电脑删上除文件(Delete / Cut),可是在STM32 的SD,还是存在的。无法删除!除非Fotmat。
回复

使用道具 举报

4

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
162
金钱
162
注册时间
2013-7-30
在线时间
31 小时
发表于 2015-8-21 14:49:49 | 显示全部楼层
我遇到的现象和6楼描述的一样!另外4楼提供的是官方修改的吗
回复

使用道具 举报

2

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2015-6-6
在线时间
3 小时
发表于 2016-4-6 10:41:37 | 显示全部楼层
yonhing 发表于 2015-2-11 10:06
我也是用Fatfs的版本是最新的R0.10c , 已经在电脑删上除文件(Delete / Cut),可是在STM32 的SD,还是存在的 ...

两个FAT表看看
这家伙明明可以靠才华吃饭,却偏偏要靠脸。
回复

使用道具 举报

2

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2015-6-6
在线时间
3 小时
发表于 2016-4-6 10:43:01 | 显示全部楼层
lvehe 发表于 2014-12-19 16:30
回复【4楼】正点原子:
---------------------------------
今天偶然在 FATFS的官网看到,原来是之前的 ...

谢谢楼主。。而且这个文件系统不能批量删除。可以加好友讨论
这家伙明明可以靠才华吃饭,却偏偏要靠脸。
回复

使用道具 举报

2

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2015-6-6
在线时间
3 小时
发表于 2016-4-6 10:47:28 | 显示全部楼层
lvehe 发表于 2014-12-22 08:21
但文件系统为什么会损坏呢?还是没答到点子上

簇链表没有删除干净。SD插到电脑,用windows的cmd输入chkdsk f:\f(盘符)可以检测磁盘错误。这种情况都是簇链表丢失。
这家伙明明可以靠才华吃饭,却偏偏要靠脸。
回复

使用道具 举报

0

主题

12

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
229
金钱
229
注册时间
2014-11-27
在线时间
44 小时
发表于 2017-2-20 14:59:25 | 显示全部楼层
这个更新日志里有FATFS各版本中存在的问题,http://elm-chan.org/fsw/ff/updates.txt ,R0.10c也出现楼主的问题。解决方法,复制R0.11里的f_unlink函数过来,然后修改函数里的DEFINE_NAMEBUF; 为DEF_NAMEBUF;即可。
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2016-11-23
在线时间
11 小时
发表于 2017-4-20 10:27:58 | 显示全部楼层
慢摇1991 发表于 2017-2-20 14:59
这个更新日志里有FATFS各版本中存在的问题,http://elm-chan.org/fsw/ff/updates.txt ,R0.10c也出现楼主的 ...

我也遇到这个问题 R0.10c 的f_ulink函数删除了文件但是存储空间没变化    按你的方法就解决了
回复

使用道具 举报

18

主题

66

帖子

0

精华

初级会员

Rank: 2

积分
161
金钱
161
注册时间
2017-9-20
在线时间
49 小时
发表于 2017-12-12 09:03:40 | 显示全部楼层
本帖最后由 1052130982 于 2017-12-12 09:39 编辑
慢摇1991 发表于 2017-2-20 14:59
这个更新日志里有FATFS各版本中存在的问题,http://elm-chan.org/fsw/ff/updates.txt ,R0.10c也出现楼主的 ...

赞赞赞赞赞赞。。。。。。。。。。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-19 15:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表