OpenEdv-开源电子网

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

了解Fatfs文件系统的请进。

[复制链接]

2

主题

13

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2018-4-3
在线时间
5 小时
发表于 2018-4-8 15:54:22 | 显示全部楼层 |阅读模式
1金钱
看了一篇文章,觉得这个问题很值得分享出来探讨一下。文章写得是批量写入数据到txt文件。

第一步、建立文件系统和文件结构变量,相当于为文件系统以及文件开辟一个实体,如下图


第二步、加载文件系统(Mount or Unmount),这里需要调用f_mount函数,函数格式如下

FRESULT f_mount (
FATFS* fs,  /* Pointer to the file system object (NULL:unmount)*/
const TCHAR* path,/* Logical drive number to be mounted/unmounted */
BYTE opt  /* 0o not mount (delayed mount), 1:Mount immediately */
)

fs为所要加载的文件系统结构指针,在第一步已经定义过了。

path相当于你加载的磁盘符,这里默认为"0:/",也就是磁盘符为0.

opt是加载选项,这里设置为1,立即加载。

当其返回FR_OK时,说明加载成功,其他一些返回状态见ff.h,这里不再列举了

然后调用f_mount函数即可,如下图


第三步、加载好文件系统后,下面就可以操作文件系统了,在创建文件之前,我先创建个路径(其实路径也可以不用创建,那样的话就在跟目录下了)

创建目录需要调用f_mkdir函数,函数格式如下

FRESULT f_mkdir (
const TCHAR* path/* Pointer to the directory path */
)

其只有一个参数path,为指向所创建目录的指针。

同样,其返回FR_OK说明创建成功

调用f_mkdir函数,如下图



其中,文件夹格式为年_月,文件名格式日_时。


第四步、文件夹路径创建好后,就可以创建文件了,文件系统通过f_open函数来创建文件,函数其格式如下

FRESULT f_open (
FIL* fp,  /* Pointer to the blank file object */
const TCHAR* path,/* Pointer to the file name */
BYTE mode  /* Access mode and file open mode flags */
)

其中fp为文件结构指针,在第一步中已经建立

path为文件路径,这里需要注意,这里的文件路径必须要包含之前文件夹名以及文件名,例如我想在16_12文件夹中创建15_13文件,需要将路径赋值为

"0:/16_12/15_13.txt",如果该路径只加文件名的话,还是会将文件创建在根目录下的。

参数mode为操作选项,我们这里赋值为FA_WRITE | FA_OPEN_ALWAYS表示以写的方式打开或创建文件,如果文件存在,则打开,如果文件不存在则创建。

调用该函数如果返回FR_OK,则说明文件打开成功。


第五步、向文件中写入数据,直接调用f_write函数即可,函数格式如下

FRESULT f_write (
FIL* fp,  /* Pointer to the file object */
const void *buff,/* Pointer to the data to be written */
UINT btw,  /* Number of bytes to write */
UINT* bw  /* Pointer to number of bytes written */
)

其中fp为文件结构指针

buff为写入数据缓冲区

btw为写入数据长度

bw为btw的指针

调用过程如下

f_lseek(fil,fil->fsize);
Sd_Fat_Data.File_Wt_Flg = f_write(fil, Sd_Fat_Data.BMS_Str_Buffer, index, &bw);

我这里的数据比较长,就不截图了。有一点注意的是,在多次重复写入一个文件前,需要调用一下f_lseek(fil,fil->fsize); 其作用就是定位到你要写入的文件的末端,这样写入的数据才不会覆盖文件原有的数据。


第六步、文件写好后,如果不想继续操作,就可以关闭文件并卸载文件系统工作区间了

f_close(&Fil);
f_mount(NULL,"0:/",1);



注:在测试过程中遇到的问题现象

1、我在实际应用中是每500ms向文件中写2000字节左右的数据,刚开始操作是每写一次文件前打开文件,写好后再关闭文件。

      后来经测试发现,在连续几十小时写入文件没有出现任何错误的情况下(打开或写入文件出错的情况下向上位机发送标识),SD卡文件夹中出现了很多莫名其妙的文件,在电脑端打不开也删不了。出现这种问题实在是找不出原因,所以究其根本,既然是出现了很多乱七八糟的文件,那应该是在打开文件的时候,文件路径指针指飞的原因。

后来改进了自己的方法,因为我的系统是按小时来更新文件,如下图


于是我在每次建立一个新文件后,只打开该文件一次,并且只在达到需要建立下一个文件的条件时才关闭该文件,至于存储过程中文件如何更新,则改成调用f_sync(&Fil);

也就是避免了最初的频繁调用open及close函数。后来经几天几夜的测试,之前乱七八糟文件出现的现象没有了,文件的写入也很正常。下图是我写的文件



至此,我的批量存储功能已经完成,文中如有不合理的地方,也请大家指正。



最佳答案

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

已经解决,通过f_sync(&Fil)函数解决了。说到底,还是对fatfs文件系统的每个函数了解不够,通过三天的研究和逐句调试观察,把ff.c里用到的函数都研究了一下,最后调整了下代码,问题解决了。 谢谢热心回复的原子哥,我每个帖子都能看到你的回复,是你给了我解决问题的力量。
学无止境
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2018-4-3
在线时间
5 小时
 楼主| 发表于 2018-4-8 15:54:23 | 显示全部楼层
已经解决,通过f_sync(&Fil)函数解决了。说到底,还是对fatfs文件系统的每个函数了解不够,通过三天的研究和逐句调试观察,把ff.c里用到的函数都研究了一下,最后调整了下代码,问题解决了。

谢谢热心回复的原子哥,我每个帖子都能看到你的回复,是你给了我解决问题的力量。
学无止境
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2018-4-3
在线时间
5 小时
 楼主| 发表于 2018-4-8 15:57:28 | 显示全部楼层
在测试过程中遇到的问题现象
1、我在实际应用中是每500ms向文件中写2000字节左右的数据,刚开始操作是每写一次文件前打开文件,写好后再关闭文件。
      后来经测试发现,在连续几十小时写入文件没有出现任何错误的情况下(打开或写入文件出错的情况下向上位机发送标识),SD卡文件夹中出现了很多莫名其妙的文件,在电脑端打不开也删不了。出现这种问题实在是找不出原因,所以究其根本,既然是出现了很多乱七八糟的文件,那应该是在打开文件的时候,文件路径指针指飞的原因。
后来改进了自己的方法,因为我的系统是按小时来更新文件
于是我在每次建立一个新文件后,只打开该文件一次,并且只在达到需要建立下一个文件的条件时才关闭该文件,至于存储过程中文件如何更新,则改成调用f_sync(&Fil);
也就是避免了最初的频繁调用open及close函数。后来经几天几夜的测试,之前乱七八糟文件出现的现象没有了,文件的写入也很正常。



我也遇到了同样的问题,作者说他于是我在每次建立一个新文件后,只打开该文件一次,并且只在达到需要建立下一个文件的条件时才关闭该文件,至于存储过程中文件如何更新,则改成调用f_sync(&Fil);  


谁能给我详解一下作者这里是如果修改的,如何修改成调用f_sync(&Fil);
学无止境
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-4-9 02:13:22 | 显示全部楼层
图片都看不到
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2018-4-3
在线时间
5 小时
 楼主| 发表于 2018-4-9 08:47:51 | 显示全部楼层

原文地址://blog.csdn.net/xinjitmzy/article/details/53692051
学无止境
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-4-11 01:45:22 | 显示全部楼层
david2018 发表于 2018-4-8 15:54
已经解决,通过f_sync(&Fil)函数解决了。说到底,还是对fatfs文件系统的每个函数了解不够,通过三天的研究 ...

谢谢分享
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 08:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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