documents
、源码文件夹source
以及许可协议文件LICENSE.txt
00history.txt
介绍了FatFs 的版本更新情况00readme.txt
说明了当前目录下各文件的功能diskio.c
包含底层存储介质的操作函数diskio.h
定义了FatFs 用到的宏,以及diskio.c 文件内与底层硬件接口相关的函数声明ff.c
FatFs 核心文件,文件管理的实现方法ff.h
FatFs 核心文件,文件管理的实现方法的函数声明ffconf.h
FatFs 配置文件ffsystem.c
可选的操作系统示例代码ffunicode.c
可选的Unicode程序函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/*---------------------------------------------------------------------------/
/ FatFs Functional Configurations
/---------------------------------------------------------------------------*/
#define FFCONF_DEF 86606 /* Revision ID *///版本ID
/*---------------------------------------------------------------------------/
/ Function Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_READONLY 0 //只读
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define FF_FS_MINIMIZE 0 //最小化级别
/* This option defines minimization level to remove some basic API functions.
/
/ 0: Basic functions are fully enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define FF_USE_STRFUNC 0 //字符串函数
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define FF_USE_FIND 0 //查找功能
/* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define FF_USE_MKFS 0 //创建FAT/exFAT卷函数
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define FF_USE_FASTSEEK 0 //快速寻道功能
/* This option switches fast seek function. (0:Disable or 1:Enable) */
#define FF_USE_EXPAND 0 //分配连续块函数
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#define FF_USE_CHMOD 0 //属性操作功能
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
#define FF_USE_LABEL 0 //卷标操作功能
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define FF_USE_FORWARD 0 //数据转发到流设备函数
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
#define FF_CODE_PAGE 932 //指定要在目标上使用的OEM代码页系统
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect code page setting can cause a file open failure.
/
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
/ 0 - Include all code pages above and configured by f_setcp()
*/
#define FF_USE_LFN 0 //切换对长文件名的支持
#define FF_MAX_LFN 255 //长文件名最大长度
/* The FF_USE_LFN switches the support for LFN (long file name).
/
/ 0: Disable LFN. FF_MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
/ be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN
/ specification.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree() exemplified in ffsystem.c, need to be added to the project. */
#define FF_LFN_UNICODE 0 //长文件名编码
/* This option switches the character encoding on the API when LFN is enabled.
/
/ 0: ANSI/OEM in current CP (TCHAR = char)
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
/ 2: Unicode in UTF-8 (TCHAR = char)
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
/
/ Also behavior of string I/O functions will be affected by this option.
/ When LFN is not enabled, this option has no effect. */
#define FF_LFN_BUF 255 //长文件名缓冲区大小
#define FF_SFN_BUF 12 //备选文件名缓冲区大小
/* This set of options defines size of file name members in the FILINFO structure
/ which is used to read out directory items. These values should be suffcient for
/ the file names to read. The maximum possible length of the read file name depends
/ on character encoding. When LFN is not enabled, these options have no effect. */
#define FF_STRF_ENCODE 3 //要读取/写入的文件字符编码
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
/ This option selects assumption of character encoding ON THE FILE to be
/ read/written via those functions.
/
/ 0: ANSI/OEM in current CP
/ 1: Unicode in UTF-16LE
/ 2: Unicode in UTF-16BE
/ 3: Unicode in UTF-8
*/
#define FF_FS_RPATH 0 //配置相对路径功能
/* This option configures support for relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
*/
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define FF_VOLUMES 1 //配置要使用的卷数
/* Number of volumes (logical drives) to be used. (1-10) */
#define FF_STR_VOLUME_ID 0 //切换对字符串卷ID的支持
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" //定义每个逻辑驱动器的卷ID字符串
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
/ not defined, a user defined volume string table needs to be defined as:
/
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
*/
#define FF_MULTI_PARTITION 0 //切换多分区功能
/* This option switches support for multiple volumes on the physical drive.
/ By default (0), each logical drive number is bound to the same physical drive
/ number and only an FAT volume found on the physical drive will be mounted.
/ When this function is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
#define FF_MIN_SS 512 //最小扇区大小
#define FF_MAX_SS 512 //最大扇区大小
/* This set of options configures the range of sector size to be supported. (512,
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
/ for variable sector size mode and disk_ioctl() function needs to implement
/ GET_SECTOR_SIZE command. */
#define FF_LBA64 0 //媒体访问接口切换到64位LBA
/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable)
/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
#define FF_MIN_GPT 0x100000000 //创建分区时确定分区格式的阈值
/* Minimum number of sectors to switch GPT format to create partition in f_mkfs and
/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */
#define FF_USE_TRIM 0 //切换ATA-TRIM功能
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
/*---------------------------------------------------------------------------/
/ System Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_TINY 0 //切换微型缓冲区配置
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
/ Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
#define FF_FS_EXFAT 0 //exFAT文件系统
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
#define FF_FS_NORTC 0 //使用RTC
#define FF_NORTC_MON 1 //没有RTC系统使用的月
#define FF_NORTC_MDAY 1 //没有RTC系统使用的日
#define FF_NORTC_YEAR 2019 //没有RTC系统使用的年
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
/ These options have no effect in read-only configuration (FF_FS_READONLY = 1). */
#define FF_FS_NOFSINFO 0 //文件信息
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
#define FF_FS_LOCK 0 //切换文件锁定功能
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
/* #include <somertos.h> // O/S definitions */
#define FF_FS_REENTRANT 0 //切换FatFs模块本身的重新进入(线程安全)
#define FF_FS_TIMEOUT 1000 //等待时间
#define FF_SYNC_t HANDLE //与O / S相关的同步对象类型
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/*--- End of configuration options ---*/
文件 | 函数 | 条件(ffconf.h) | 备注 |
---|---|---|---|
diskio.c | 设备状态获取 disk_status |
总是需要 | 底层设备驱动函数 |
设备初始化 disk_initialize |
|||
扇区读取 disk_read |
|||
扇区数量 disk_ioctl(GET_SECTOR_COUNT) |
FF_USE_MKFS == 1 | ||
同时擦除扇区个数 disk_ioctl(GET_BLOCK_SIZE) |
|||
扇区大小 disk_ioctl(GET_SECTOR_SIZE) |
FF_MAX_SS!= FF_MIN_SS | ||
通知设备扇区块上的数据不再使用 disk_ioctl(CTRL_TRIM) |
FF_USE_TRIM == 1 | ||
确保设备已完成挂起的写入过程 disk_ioctl(CTRL_SYNC) |
FF_FS_READONLY == 0 | ||
扇区写入 disk_write |
|||
时间戳获取 get_fattime |
FF_FS_READONLY == 0 FF_FS_NORTC == 0 |
||
ffunicode.c | Unicode->OEM转换 ff_uni2oem |
_USE_LFN != 0 | Unicode 支持 将可选模块ffunicode.c添加到项目中 |
OEM->Unicode转换 ff_oem2uni |
|||
Unicode大小写转换 ff_wtoupper |
|||
ffsystem.c | 创建同步对象 ff_cre_syncobj |
_FS_REENTRANT == 1 | 取决于O / S的功能 ffsystem.c中提供了示例代码 |
删除同步对象 ff_del_syncobj |
|||
请求访问权限 ff_req_grant |
|||
释放访问权限 /ff_rel_grant |
|||
分配内存块 ff_mem_alloc |
_USE_LFN == 2 | ||
释放内存块 ff_mem_free |
source
复制到工程source
文件夹下的文件添加到工程diskio.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
switch (pdrv) {
case DEV_RAM :
stat = (sFLASH_ID == W25Q_ReadID())?0:STA_NOINIT;
// translate the reslut code here
return stat;
}
return STA_NOINIT;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
switch (pdrv) {
case DEV_RAM :
// translate the reslut code here
/* 初始化SPI Flash */
SPI_FLASH_Init();
/* 延时一小段时间 */
uint16_t i=500;
while(--i);
/* 唤醒SPI Flash */
W25Q_WAKEUP();
/* 获取SPI Flash芯片状态 */
stat=disk_status(DEV_RAM);
return stat;
}
return STA_NOINIT;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
DRESULT res;
switch (pdrv) {
case DEV_RAM :
/* 扇区偏移约2MB,外部Flash 文件系统空间放在SPI Flash 后面约6MB 空间 */
sector+=514;
W25Q_BufferRead(buff,sector <<12, count<<12);
res = RES_OK;
return res;
}
return RES_PARERR;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT res;
switch (pdrv) {
case DEV_RAM :
/* 扇区偏移2MB,外部Flash文件系统空间放在SPI Flash后面6MB空间 */
sector+=514;
W25Q_SectorErase(sector<<12);
W25Q_BufferWrite((u8 *)buff,sector<<12,count<<12);
res = RES_OK;
return res;
}
return RES_PARERR;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
switch (pdrv) {
case DEV_RAM :
switch (cmd) {
/* 扇区数量:1536*4096/1024/1024=6(MB) */
case GET_SECTOR_COUNT:
*(DWORD * )buff = 1534;
break;
/* 扇区大小 */
case GET_SECTOR_SIZE :
*(WORD * )buff = 4096;
break;
/* 同时擦除扇区个数 */
case GET_BLOCK_SIZE :
*(DWORD * )buff = 1;
break;
}
res= RES_OK;
return res;
}
return RES_PARERR;
}
1
2
3
4
5
6
7
8
9
DWORD get_fattime(void) {
/* 返回当前时间戳 */
return ((DWORD)(2020 - 1980) << 25) /* Year 2020 */
| ((DWORD)9 << 21) /* Month 9 */
| ((DWORD)11 << 16) /* Mday 11 */
| ((DWORD)0 << 11) /* Hour 0 */
| ((DWORD)0 << 5) /* Min 0 */
| ((DWORD)0 >> 1); /* Sec 0 */
}
ffconf.h
1
2
3
4
5
6
#define FF_USE_STRFUNC 1//字符串
#define FF_USE_MKFS 1 //创建文件系统
#define FF_CODE_PAGE 936//简体中文
#define FF_USE_LFN 2 //支持长文件名,并指定使用栈空间为缓冲区
#define FF_MAX_SS 4096//SPI Flash 芯片扇区大小一般设置为4096 字节
#define FF_VOLUMES 2 //修改为2,以便后续SD卡使用
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include "my_gpio.h"
#include "my_usart.h"
#include "my_spi.h"
#include "my_W25Qx.h"
#include "ff.h"
FATFS fs; /* FatFs文件系统对象 */
FIL fnew; /* 文件对象 */
FRESULT res_flash; /* 文件操作结果 */
UINT fnum; /* 文件成功读写数量 */
char fpath[100]; /* 保存当前扫描路径 */
char readbuffer[512];
/**
* @brief 板级外设初始化,所有板子上的初始化均可放在这个函数里面
* @param 无
* @retval 无
*/
static void BSP_Init(void)
{
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
/* LED 初始化 */
LED_GPIO_Config();
/* 串口初始化 */
USART_Config();
/*SPI初始化 */
SPI_FLASH_Init();
}
/* FatFs多项功能测试 */
static FRESULT miscellaneous(void)
{
DIR dir;
FATFS *pfs;
DWORD fre_clust, fre_sect, tot_sect;
printf("\n*************** device info ***************\r\n");
/* 获取设备信息和空簇大小 */
res_flash = f_getfree("0:", &fre_clust, &pfs);
/* 计算得到总的扇区个数和空扇区个数 */
tot_sect = (pfs->n_fatent - 2) * pfs->csize;
fre_sect = fre_clust * pfs->csize;
/* 打印信息(4096 字节/扇区) */
printf("device total:%10u KB.\nfree:%10u KB.\n", tot_sect *4, fre_sect *4);
printf("\n******** file ********\r\n");
res_flash = f_open(&fnew, "0:FatFstest.txt",
FA_OPEN_ALWAYS|FA_WRITE|FA_READ );
if ( res_flash == FR_OK )
{
/* 文件定位 */
res_flash = f_lseek(&fnew,f_size(&fnew));
if (res_flash == FR_OK)
{
/* 格式化写入,参数格式类似printf函数 */
f_printf(&fnew,"\nnew line\n");
f_printf(&fnew,"total:%10lu KB.\nfree: %10lu KB.\n", tot_sect *4, fre_sect *4);
/* 文件定位到文件起始位置 */
res_flash = f_lseek(&fnew,0);
/* 读取文件所有内容到缓存区 */
res_flash = f_read(&fnew,readbuffer,f_size(&fnew),&fnum);
if(res_flash == FR_OK)
{
printf("file: \n%s\n",readbuffer);
}
}
f_close(&fnew);
printf("\n********** dir **********\r\n");
/* 尝试打开目录 */
res_flash=f_opendir(&dir,"0:TestDir");
if(res_flash!=FR_OK)
{
/* 打开目录失败,就创建目录 */
res_flash=f_mkdir("0:TestDir");
}
else
{
/* 如果目录已经存在,关闭它 */
res_flash=f_closedir(&dir);
/* 删除文件 */
f_unlink("0:TestDir/testdir.txt");
}
if(res_flash==FR_OK)
{
/* 重命名并移动文件 */
res_flash=f_rename("0:FatFstest.txt","0:TestDir/testdir.txt");
}
}
else
{
printf("file fail:%d\n",res_flash);
printf("reset\n");
}
return res_flash;
}
FILINFO fno;
/**
* 文件信息获取
*/
static FRESULT file_check(void)
{
/* 获取文件信息 */
res_flash=f_stat("0:TestDir/testdir.txt",&fno);
if(res_flash==FR_OK)
{
printf("'testdir.txt':\n");
printf("size: %d(byte)\n", fno.fsize);
printf("time: %u/%02u/%02u, %02u:%02u\n",
(fno.fdate >> 9) + 1980, fno.fdate >> 5 & 15, fno.fdate & 31,fno.ftime >> 11, fno.ftime >> 5 & 63);
printf("attrib: %c%c%c%c%c\n\n",
(fno.fattrib & AM_DIR) ? 'D' : '-', // 是一个目录
(fno.fattrib & AM_RDO) ? 'R' : '-', // 只读文件
(fno.fattrib & AM_HID) ? 'H' : '-', // 隐藏文件
(fno.fattrib & AM_SYS) ? 'S' : '-', // 系统文件
(fno.fattrib & AM_ARC) ? 'A' : '-'); // 档案文件
}
return res_flash;
}
/**
* @brief scan_files 递归扫描FatFs内的文件
* @param path:初始扫描路径
* @retval result:文件系统的返回值
*/
static FRESULT scan_files (char* path)
{
FRESULT res; //部分在递归过程被修改的变量,不用全局变量
FILINFO fno;
DIR dir;
int i;
char *fn; // 文件名
#if _USE_LFN
/* 长文件名支持 */
/* 简体中文需要2个字节保存一个“字”*/
static char lfn[_MAX_LFN*2 + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
#endif
//打开目录
res = f_opendir(&dir, path);
if (res == FR_OK)
{
i = strlen(path);
for (;;)
{
//读取目录下的内容,再读会自动读下一个文件
res = f_readdir(&dir, &fno);
//为空时表示所有项目读取完毕,跳出
if (res != FR_OK || fno.fname[0] == 0) break;
#if _USE_LFN
fn = *fno.lfname ? fno.lfname : fno.fname;
#else
fn = fno.fname;
#endif
//点表示当前目录,跳过
if (*fn == '.') continue;
//目录,递归读取
if (fno.fattrib & AM_DIR)
{
//合成完整目录名
sprintf(&path[i], "/%s", fn);
//递归遍历
res = scan_files(path);
path[i] = 0;
//打开失败,跳出循环
if (res != FR_OK)
break;
}
else
{
printf("%s/%s\r\n", path, fn); //输出文件名
/* 可以在这里提取特定格式的文件路径 */
}//else
} //for
}
return res;
}
int main(void)
{
BSP_Init();
res_flash = f_mount(&fs,"0:",1);
if(res_flash!=FR_OK)
{
printf("fail(%d)\r\n",res_flash);
printf("may beSPI Flash init fail\r\n");
while(1);
}
else
{
printf("success\r\n");
}
/* FatFs多项功能测试 */
res_flash = miscellaneous();
printf("\n*************** file check **************\r\n");
res_flash = file_check();
printf("***************** file scan ****************\r\n");
strcpy(fpath,"0:");
scan_files(fpath);
/* 不再使用文件系统,取消挂载文件系统 */
f_mount(NULL,"0:",1);
while(1);
}