FatFs 应用接口函数

FS的配置选项

针对每个项目的不同需求,有许多选项可以配置FatFs的功能。配置选项在ffconf.h中定义。

功能设置

FF_FS_READONLY

Read/Write(0)或Read-only (1). Read-only配置删除了写API函数,f_write、f_sync、f_unlink、f_mkdir、f_chmod、f_rename、f_truncate、f_getfree以及可选的写函数。

FF_FS_MINIMIZE

该选项定义了最小化级别以删除一些基本API函数,如下所示:

描述
0所有基本API函数都可用。
1删除F_stat、f_getfree、f_unlink、f_mkdir、f_chmod、f_utime、f_truncate和f_rename函数
2除1外,F_opendir, f_readdir和f_closedir函数被删除。
3除2外,F_lseek函数被删除。

FF_USE_FIND

禁用(0)或启用(1) 过滤目录读取函数,f_findfirst和f_findnext。此外,ff_fs_minimal需要为0或1。

FF_USE_MKFS

Disable (0) or Enable (1) f_mkfs函数。

FF_USE_FASTSEEK

Disable(0)或Enable (1) fast seek function用于开启f_lseek, f_read和f_write函数的加速模式。欲了解更多信息,请阅读f_lseek函数

FF_USE_EXPAND

Disable(0)或Enable (1) f_expand函数。

FF_USE_CHMOD

禁用(0)或启用(1)元数据控制功能f_chmod和f_utime。另外,FF_FS_READONLY需要为0。

FF_USE_LABEL

禁用 (0) 或启用 (1) 卷标、f_getlabel 和 f_setlabel 的 API 函数。

FF_USE_FORWARD

禁用 (0) 或启用 (1) f_forward 功能。

FF_USE_STRFUNC

此选项切换字符串函数、f_gets、f_putc、f_puts 和 f_printf。 这些函数等同于 POSIX 中的常规字符串流 I/O 函数。 如果 sprintf 可用且不需要代码转换,则使用 sprintf 的 f_write 在代码大小和性能方面比 f_printf 更高效。 启用此功能时,stdarg.h 包含在 ff.c 中。

描述
0禁用字符串函数
1启用无需 LF-CRLF 转换的字符串函数
2使用 LF-CRLF 转换启用字符串函数

FF_PRINT_LLI

此选项切换对 f_printf 中 long long integer 参数的支持。

禁用 (0) 或启用 (1)。 启用此功能时,C 标准需要为 C99 或更高版本。

FF_PRINT_FLOAT

此选项切换对 f_printf 中浮点参数的支持。 启用此功能时,C 标准需要为 C99 或更高版本,并且 math.h 包含在 ff.c 中。

描述
0禁用浮点参数
1在类型“f”、“e”和“E”中启用浮点参数
2使用小数分隔符“,”而不是“.”

FF_STRF_ENCODE

当 API 上的字符编码为 Unicode (FF_LFN_UNICODE >= 1) 时,FF_USE_STRFUNC 启用的字符串 I/O 函数会转换其中的字符编码。 此选项定义要通过这些函数读取/写入的文件的字符编码假设。 当 LFN 未启用或 FF_LFN_UNICODE == 0 时,字符串函数无需任何代码转换即可工作,并且此选项无效。

文件上的字符编码
0当前代码页中 A使用 ANSI/OEM
1UTF-16LE 中的 Unicode
2UTF-16BE 中的 Unicode
3UTF-8 中的 Unicode

名称空间和区域配置

FF_CODE_PAGE

此选项指定目标系统上使用的 OEM 代码页。 代码页设置不正确会导致文件打开失败。 如果任何非 ASCII 字符未用于路径名或 FF_LFN_UNICODE != 0,则任何代码页设置之间没有区别。 无论如何设置它437。

代码页
0包括以下所有代码页并由 f_setcp() 设置
437美国
720阿拉伯
737希腊
771KBL
775波罗的海
850拉丁语 1
852拉丁语 2
855西里尔
857土耳其
860葡萄牙
861冰岛
862希伯来
863加拿大法语
864阿拉伯
865北欧
868俄罗斯
869希腊语 2
932日语 (DBCS)
936简体中文 (DBCS)
949韩语 (DBCS)
950繁体中文 (DBCS)

FF_USE_LFN

此选项切换对长文件名 (LFN) 的支持。 启用 LFN 时,需要将 Unicode 支持模块 ffunicode.c 添加到项目中。 当使用堆栈作为工作缓冲区时,请注意堆栈溢出。 当工作缓冲区使用堆内存时,需要在项目中添加内存管理函数(ff_memalloc和ff_memfree)。

描述
0禁用 LFN。 只能使用 8.3 格式的路径名
1在 BSS 上使用静态工作缓冲区启用 LFN。 始终不是线程安全的
2在 STACK 上使用动态工作缓冲区启用 LFN
3在 HEAP 上使用动态工作缓冲区启用 LFN

FF_MAX_LFN

LFN 函数需要一定的内部工作缓冲区来存储文件名。 此选项定义缓冲区的大小,值可以在 LFN 的 12 到 255 个字符(实际上是 UTF-16 代码单元)的范围内。 当启用 exFAT 时,缓冲区占用 (FF_MAX_LFN + 1) * 2 个字节和额外的 (FF_MAX_LFN + 44) / 15 * 32 个字节。 建议设置为 255 以完全支持 LFN 规范。 当未启用 LFN 时,此选项无效。

FF_LFN_UNICODE

此选项切换 API 上文件名的字符编码。 FatFs 最多支持 U+10FFFF 的代码点。 该选项还影响字符串 I/O 函数的行为(参见 FF_STRF_ENCODE)。

字符编码TCHAR
0当前 CP 中的 ANSI/OEMchar
1UTF-16 中的 UnicodeWCHAR
2UTF-8 中的 Unicodechar
3UTF-32 中的 UnicodeDWORD
选择Unicode时,FF_CODE_PAGE除了兼容遗留系统,如MS-DOS和任何不支持LFN的系统,实际上没有任何意义。

未启用 LFN 时,此选项无效,FatFs 在 API 上以 ANSI/OEM 代码运行。 有关更多信息,请阅读FatFs Module Application Note中的Unicode API

FF_LFN_BUF, FF_SFN_BUF

这组选项在用于读出目录项的 FILINFO 结构中定义了文件名成员 fname[] 和 altname[] 的大小。 这些值应该足以让文件名读取。 读取文件名的最大可能长度取决于 API 上的字符编码方案,如下所示:

编码长文件名长度SFN长度
SBCS 中的 ANSI/OEM255项12项
DBCS 中的 ANSI/OEM510项12项
UTF-16/32 中的 Unicode255项12项
UTF-8 中的 Unicode765项34项

如果名称成员的大小对于 LFN 来说不足,则该项目被视为没有 LFN。 未启用 LFN 时,这些选项无效。

FF_FS_RPATH

该选项配置相对路径功能。 有关更多信息,请阅读FatFs Module Application Note中的Format of the Path Names

描述
0禁用相对路径并删除相关功能。
1启用相对路径。 f_chdir 和 f_chdrive 函数可用。
2f_getcwd 函数除 1 外还可用

容器卷/驱动配置

FF_VOLUMES

此选项配置要使用的卷数(最多 10 个逻辑驱动器)。

FF_STR_VOLUME_ID

此选项切换对字符串卷 ID 的支持。 当为驱动器前缀启用卷 ID 的任意字符串时,FF_VOLUME_STRS 预定义的字符串或用户定义的字符串也可以用作路径名中的驱动器前缀。 无论此选项如何,数字驱动器编号始终有效,并且可以通过此选项启用驱动器前缀的任一格式。

描述示例
0只能使用数字 ID 中的 DOS/Windows 风格驱动器前缀。1:/filename
1也可以使用字符串 ID 中的 DOS/Windows 风格驱动器前缀。flash:/filename
2也可以使用字符串 ID 中的 Unix 风格驱动器前缀。/flash/filename

FF_VOLUME_STRS

此选项定义每个逻辑驱动器的卷 ID 字符串。 项目数不得少于 FF_VOLUMES。 卷 ID 字符串的有效字符是 A-Z、a-z 和 0-9,但是,它们在比较时不区分大小写。 如果 FF_STR_VOLUME_ID == 0,则此选项无效。 如果 FF_STR_VOLUME_ID >= 1 且未定义此选项,则需要定义用户定义的卷字符串表,如下所示。 该表不应即时修改。

/* 用户定义的卷 ID 字符串 0: 到 3: */
const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb"};

FF_MULTI_PARTITION

禁用 (0) 或启用 (1)。 该选项切换多分区功能。 默认情况下 (0),每个逻辑驱动器号都绑定到相同的物理驱动器号,并且只装载物理驱动器中的一个卷。 启用后,每个逻辑驱动器都绑定到用户定义的分区解析表 VolToPart[] 中列出的物理驱动器上的分区。 f_fdisk 功能也将可用。 有关更多信息,请阅读FatFs Module Application Note中的Volume Management

FF_MIN_SS, FF_MAX_SS

这组选项定义了用于低级磁盘 I/O 接口、disk_read 和 disk_write 函数的扇区大小范围。 有效值为 512、1024、2048 和 4096。FF_MIN_SS 定义最小扇区大小,FF_MAX_SS 定义最大扇区大小。 始终为存储卡和硬盘设置 512。 但板载闪存和某些类型的光学介质可能需要更大的值。 当 FF_MAX_SS > FF_MIN_SS 时,启用可变扇区大小的支持,需要对 disk_ioctl 函数执行 GET_SECTOR_SIZE 命令。

FF_LBA64

此选项将媒体访问接口切换到 64 位 LBA,并启用用于分区管理的 GUID 分区表 (GPT),启用 (1) 或禁用 (0)。 需要启用 exFAT 文件系统才能启用此功能。

FF_GPT_MIN(FF_MIN_GPT)

此选项指定在 f_mkfs 和 f_fdisk 函数中在驱动器上创建分区时确定分区格式的阈值。 当可用扇区数等于或大于此值时,驱动器将按 GPT 分区。 当 FF_LBA64 == 0 时,此选项无效。

FF_USE_TRIM

禁用 (0) 或启用 (1)。 此选项切换 ATA-TRIM 功能。 要启用 Trim 功能,还应该对 disk_ioctl 功能执行 CTRL_TRIM 命令。

系统设置

FF_FS_TINY

正常 (0) 或微型 (1)。 微型配置减少了 FIL 结构、文件对象、FF_MAX_SS 字节的大小。 FATFS 结构中的公共扇区缓冲区、文件系统对象用于文件数据传输,而不是从文件对象中消除私有扇区缓冲区。

FF_FS_EXFAT

除了 FAT/FAT32 文件系统之外,此选项还会切换对 exFAT 文件系统的支持,启用 (1) 或禁用 (0)。 要启用 exFAT,还必须启用 LFN,建议配置 FF_LFN_UNICODE >= 1 和 FF_MAX_LFN == 255 以获得全功能的 exFAT 功能。 请注意,启用 exFAT 会放弃 ANSI C (C89) 兼容性并需要 C99,因为需要 64 位整数类型。

FF_FS_NORTC

使用 RTC (0) 或不使用 RTC (1)。 此选项控制时间戳特征。 如果系统没有 RTC 或不需要有效的时间戳,将 FF_FS_NORTC 设置为 1 以禁用时间戳功能。 FatFs 修改的每个对象都将有一个由 FF_NORTC_MON、FF_NORTC_MDAY 和 FF_NORTC_YEAR 定义的常量时间戳。 要使用时间戳功能,请设置 FF_FS_NORTC == 0 并将 get_fattime 函数添加到项目以从 RTC 获取当前时间。 此选项对只读配置没有影响。

FF_NORTC_MON, FF_NORTC_MDAY, FF_NORTC_YEAR

这组选项定义了在无 RTC 系统中使用的时间。 此选项对只读配置或 FF_FS_NORTC == 0 没有影响。

FF_FS_NOFSINFO

0 到 3。如果您需要知道 FAT32 卷上的正确可用空间,请设置此选项的位 0,并且在卷安装后的第一次 f_getfree 函数将强制进行完整的 FAT 扫描。 位 1 控制使用最后分配的簇号进行新分配。

描述
bit0=0如果可用,请使用 FSINFO 中的空闲簇计数。
bit0=1不要相信 FSINFO 中的空闲簇计数。
bit1=0使用 FSINFO 中最后分配的簇号来查找空闲簇(如果可用)
bit1=0不要相信 FSINFO 中最后分配的簇号。

FF_FS_LOCK

该选项切换文件锁定功能以控制重复文件打开和对打开对象的非法操作。 请注意,此功能与重新进入无关。 此选项在只读配置中必须为 0。

描述
0禁用文件锁定功能。 为避免错误的文件操作导致文件崩溃,应用程序需要避免非法打开、删除和重命名打开的对象
>0启用文件锁定功能。 该值定义了在文件锁定功能下可以同时打开多少个文件/子目录。 对打开对象的非法操作将被 FR_LOCKED 拒绝

FF_FS_REENTRANT

禁用 (0) 或启用 (1)。 此选项切换 FatFs 模块本身的重入(线程安全)。 请注意,对不同卷的文件/目录访问始终是可重入的,并且无论此选项如何,它都可以同时工作,但是,卷管理功能 f_mount、f_mkfs 和 f_fdisk 始终不可重入。 此功能仅控制对同一卷的文件/目录访问,换句话说,对每个文件系统对象的独占使用。 要启用此功能,还需要将用户提供的同步处理程序 ff_mutex_take、ff_mutex_give、ff_mutex_create 和 ff_mutex_delete 添加到项目中。 ffsystem.c 中提供了示例代码。

FF_FS_TIMEOUT

当等待时间超过此时间段时,使用 FR_TIMEOUT 中止文件功能的 O/S 时间滴答数。 当 FF_FS_REENTRANT == 0 时,此选项无效。

FF_SYNC_t

FS的返回码

大多数API函数以枚举类型FRESULT返回常见的结果代码。当API函数成功时,它返回零(FR_OK),否则返回非零值表示错误类型。

FR_OK(成功),
FR_DISK_ERR(下层disk_read、disk_write或disk_ioctl函数报告发生了不可恢复的硬盘错误。),
FR_INT_ERR(断言失败,在内部流程中检测到异常),
FR_NOT_READY(下层disk_initialize函数报告存储设备无法做好工作准备。),
FR_NO_FILE(目录中没找到文件),
FR_NO_PATH(在路径名中找不到目录。),
FR_INVALID_NAME(给定的字符串作为路径名无效。),
FR_DENIED(由于某些原因,所需的访问被拒绝),
FR_EXIST(目录中已存在具有相同名称的对象。),
FR_INVALID_OBJECT(文件/目录对象无效或给定了空指针。),
FR_WRITE_PROTECTED(针对写保护介质的写模式操作。),
FR_INVALID_DRIVE(在路径名称中指定了无效的驱动器号,或者将空指针作为路径名称),
FR_NOT_ENABLED(f_mount函数尚未注册逻辑驱动器的工作区域。没挂载),
FR_NO_FILESYSTEM,(在驱动器中找不到有效的FAT卷。)
FR_MKFS_ABORTED(f_mkfs函数在格式化启动前中止),
FR_TIMEOUT(由于线程安全控制超时,该函数被取消。(),
FR_LOCKED(对对象的操作被文件共享控制拒绝),
FR_NOT_ENOUGH_CORE(内存不足,无法进行操作。)
FR_TOO_MANY_OPEN_FILES(打开的对象数已达到最大值,无法再打开任何对象。)
FR_INVALID_PARAMETER(给定的参数无效,或者卷存在不一致的参数。)

文件访问类

f_open() – 打开或者创建一个文件

描述:
f_open函数的作用是打开一个文件并创建一个文件对象。它是文件后续读/写操作的标识符。函数成功后,文件对象有效。如果函数失败,则文件对象设置无效。

打开文件后应使用f_close函数关闭该文件的会话访问。如果对文件进行了任何更改,并且在断电、删除介质或重新挂载之前未关闭,则可以将文件折叠。

如果需要打开复制文件,请仔细阅读此处。然而,使用任何写模式标记的文件的重复打开总是被禁止的。

总是可用的。当FF_FS_READONLY == 1(文件权限为只读)时,模式标志只有FA_READ和FA_OPEN_EXISTING可用。

FRESULT f_open (
  FIL* fp,           /* [OUT] 指向空白文件对象结构的指针 */
  const TCHAR* path, /* [IN] 文件名 指向以空结束的字符串的指针,该字符串指定要打开或创建的文件名。*/
  BYTE mode          /* [IN] 模式标志,用于指定文件的访问类型和打开方法。 */
);

fr = f_open(&fil, "message.txt", FA_READ);
if (fr) return (int)fr;
Flags(参数mode)meaning
FA_READ指定对文件的读访问权。可以从文件中读取数据。
FA_WRITE指定对文件的写访问。可向该文件写入数据。结合FA_READ进行读写访问。
FA_OPEN_EXISTING打开文件。如果文件不存在,该函数将失败。(默认)
FA_CREATE_NEW创建一个新文件。如果文件存在,函数使用FR_EXIST失败。
FA_CREATE_ALWAYS创建一个新文件。如果文件存在,它将被截断和覆盖。
FA_OPEN_ALWAYS如果文件存在,则打开该文件。如果没有,将创建一个新文件。
FA_OPEN_APPEND与FA_OPEN_ALWAYS相同,只是读写指针设置在文件末尾。

f_open的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH, FR_INVALID_NAME, FR_DENIED, FR_EXIST, FR_INVALID_OBJECT, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_LOCKED, FR_NOT_ENOUGH_CORE, FR_TOO_MANY_OPEN_FILES

f_close() - 关闭一个打开的文件对象

描述:
f_close函数的作用是关闭一个打开的文件对象。如果文件已被更改,则该文件的缓存信息将被写回卷。函数成功后,文件对象不再有效,可以丢弃。

注意:如果文件对象处于只读模式,且没有启用FF_FS_LOCK,该文件对象也可以被丢弃,不需要执行此步骤。但是,为了将来的兼容性,不建议这样做。

FRESULT f_close (
  FIL* fp     /* [IN] 指向要关闭的打开文件对象结构的指针。 */
);
f_close(&fil);

f_close的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_INVALID_OBJECT, FR_TIMEOUT

f_read() – 从文件中读数据

描述:
该函数从文件对象的读写指针所指向的文件偏移量处开始读取数据。读/写指针随着读取字节数的增加而增加。函数成功后,应该检查*br以检测文件的结束。
如果*br < btr,则表示读操作期间读/写指针命中文件的末尾。

FRESULT f_read (
  FIL* fp,     /* [IN] Pointer to the open file object. */
  void* buff,  /* [OUT] 指向存储读取数据的缓冲区的指针。 */
  UINT btr,    /* [IN] 在UINT类型范围内要读取的字节数。如果需要快速读取文件,则应尽可能以大块进行读取。 */
 UINT* br     /* [OUT] 指向UINT变量的指针,该变量接收读取的字节数。不管函数的返回码是什么,这个值在函数调用之后总是有效的。如果返回值等于btr,函数返回码应该是FR_OK。 */
);
/* Example */ 
fr = f_read(&fsrc, buffer, sizeof buffer, &br);
if (br == 0) break; /* error or eof 出错*/

/* br文件读写次数 */

f_read的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_DENIED, FR_INVALID_OBJECT, FR_TIMEOUT

f_write() – 在文件里写数据

描述:
该函数从文件对象的读/写指针所指向的文件偏移量开始向文件写入数据。读/写指针随着写入字节数的增加而增加。该功能成功后,应检查*bw以检测磁盘已满。

如果*bw < btw,则表示写入操作期间卷已满。当卷已满或接近满时,该函数需要一段时间。

FRESULT f_write (
  FIL* fp,          /* [IN] 指向打开文件对象结构的指针。 */
  const void* buff, /* [IN] 指向要写入数据的指针 */
  UINT btw,         /* [IN] 指定在UINT类型范围内要写入的字节数。如果需要快速写入数据,则应尽可能将其写入大块。 */
  UINT* bw          /* [OUT] 指向UINT变量的指针,该变量接收写入的字节数。不管函数的返回码是什么,这个值在函数调用之后总是有效的。如果返回值等于btw,函数返回码应该是FR_OK。 */
);
/* Example */ 
fr = f_write(&fdst, buffer, br, &bw);           /* 将其写入目标文件 */
if (bw < br) break; /* error or disk full */

f_write的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_DENIED, FR_INVALID_OBJECT, FR_TIMEOUT

f_lseek() - 移动读写指针,扩展大小

描述:
打开文件对象中的文件读/写指针指向下一次读/写操作时要读/写的数据字节。它随着读取/写入的字节数而增加。f_lseek函数在没有对文件进行任何读/写操作的情况下移动文件读/写指针。f_freback函数是作为一个宏来执行的。

当ff_fs_minimum <= 2时可用。使用快速查找功能时,FF_USE_FASTSEEK需要设置为1才能启用该功能。

#define f_rewind(fp) f_lseek((fp), 0)
FRESULT f_lseek (
  FIL*    fp,  /* [IN] 指向打开文件对象的指针。 */
  FSIZE_t ofs  /* [IN] 用于设置读/写指针的文件顶部的字节偏移量。数据类型FSIZE_t是DWORD(32位)的别名还是QWORD(64位)的别名取决于配置选项FF_FS_EXFAT。 */
);
FRESULT f_rewind (
  FIL*    fp   /* [IN] 文件对象 */
);
res = f_lseek(fp, 5000); /* 设置读/写指针为5000 */

f_lseek的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_INVALID_OBJECT, FR_TIMEOUT

f_truncate() - 截断文件大小

描述:
f_truncate函数的作用是:将文件大小截断为当前文件读写指针。如果文件读/写指针已经指向文件的末尾,则此函数没有作用。

RESULT f_truncate (
  FIL* fp     /* [IN] 指向要截断的打开文件对象的指针。 */
);
res = f_truncate(fp);                    /* 截断未使用区域*/

f_truncate的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_DENIED, FR_INVALID_OBJECT, FR_TIMEOUT

f_sync() - 刷新写入文件的缓存信息。

描述:
f_sync函数执行的过程与f_close函数相同,但文件保持打开状态,可以继续对文件进行读/写/查找操作。适用于长时间以写方式打开文件的应用,如数据记录器等。在一定的时间间隔内执行f_sync功能,可以最大限度地降低由于突然停电、错误的介质移除或不可恢复的磁盘错误而导致的数据丢失风险。
在这里插入图片描述

FRESULT f_sync (
  FIL* fp     /* [IN] 指向要刷新的打开文件对象的指针 */
);

f_sync的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_INVALID_OBJECT, FR_TIMEOUT

f_forward() - 读取文件数据并将其转发到数据流设备。

描述:
f_forward函数从文件中读取数据并将其转发到传出流。此功能适用于内存较小的系统,因为它在应用模块中不需要任何数据缓冲区。文件对象的文件指针转发的字节数增加。如果*bf小于btf而不出错,则表示在数据传输过程中由于文件结束或流繁忙而无法传输所请求的数据大小。

FRESULT f_forward (
  FIL* fp,                        /* [IN] File object */
  UINT (*func)(const BYTE*,UINT), /* [IN] Data streaming function */
  UINT btf,                       /* [IN] 在UINT范围内要转发的字节数。 */
  UINT* bf                        /* [OUT] 指向UINT变量的指针,返回转发的字节数。 */
);
/* 定期或按需填充输出流 */
rc = f_forward(&fil, out_stream, 1000, &dmy);

f_forward的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_INVALID_OBJECT, FR_DENIED, FR_TIMEOUT

f_expand - 为文件准备或分配一个连续的数据区域。

描述:
f_expand函数为文件准备或分配一个连续的数据区域。

当opt为1时,数据区域将分配给此函数中的文件。与f_lseek函数扩展文件大小不同,在使用此函数之前必须截断文件,并且在函数调用后文件的读/写指针保持在偏移量0处。使用此函数分配的文件内容是未定义的,因为在此过程中没有数据写入文件。

当opt为0时,函数会找到一个连续的数据区域,并将其设置为下一次分配的建议点。随后的集群分配从该函数找到的连续区域的顶部开始。因此,除非对卷执行任何其他更改,否则保证文件分配是连续的,并且在文件大小达到该大小之前没有分配延迟。

连续文件对于时间关键的读/写操作具有优势。它消除了由于随机访问碎片文件而导致的文件系统和存储设备的一些开销。

此外,可以通过低级磁盘功能轻松地直接访问连续文件。但是,考虑到可移植性和未来兼容性,不建议这样做。如果尚未确认文件是否连续,请使用此函数检查文件是否连续。

FRESULT f_expand (
  FIL*    fp,  /* [IN] File object */
  FSIZE_t fsz, /* [IN] 为文件准备或分配的字节数。数据类型FSIZE_t是DWORD(32位)的别名还是QWORD(64位)的别名取决于配置选项FF_FS_EXFAT。 */
  BYTE    opt  /* [IN] 分配模式。准备分配(0)或立即分配(1)。 */
);
/* 为文件分配 100 MiB 的连续区域 */
    res = f_expand(fp, 104857600, 1);

** f_expand的返回码:** FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_INVALID_OBJECT, FR_DENIED, FR_TIMEOUT

f_gets - 从文件中读取一个字符串

描述
读取操作将继续,直到存储“\n”、到达文件末尾或缓冲区充满 len - 1 个字符。 读取的字符串以“\0”结尾。 当没有字符可读取或读取操作发生任何错误时,它返回一个空指针。 可以使用 f_eof 和 f_error 函数检查 EOF 和错误的状态。

当 FatFs 配置为 Unicode API (FF_LFN_UNICODE >= 1) 时,srting 函数 f_putc、f_puts、f_printf 和 f_gets 上的数据类型也切换为 Unicode。 要通过此函数读取的文件的字符编码假定为 FF_STRF_ENCODE。 如果文件上的字符编码与API上的不同,则在此函数中进行转换。 在这种情况下,编码错误的输入字符将丢失。

TCHAR* f_gets (
  TCHAR* buff, /* [OUT] 指向读取缓冲区的指针,用于存储读取的字符串。 */
  int len,     /* [IN] 以项目为单位的读取缓冲区的大小。 */
  FIL* fp      /* [IN] 指向打开文件对象结构的指针。 */
);

 /* 读取每一行并显示出来 */
    while (f_gets(line, sizeof line, &fil)) {
        printf(line);
    }

** f_gets的返回码:** f_open, f_read, f_putc, f_puts, f_printf, f_close, FIL

f_putc - 将一个字符放入文件

描述:
当 FatFs 配置为 Unicode API (FF_LFN_UNICODE >= 1) 时,字符串函数、f_putc、f_puts、f_printf 和 f_gets 函数的字符编码也切换为 Unicode。 通过这些函数读取/写入的文件的字符编码由 FF_STRF_ENCODE 选择。 多编码单元的Unicode字符,如代理对、多字节序列等,不能用该函数写入。

这是 f_write 函数的包装函数。 当 FF_FS_READONLY == 0 且 FF_USE_STRFUNC >= 1 时可用。当 FF_USE_STRFUNC == 2 时,‘\n’ 输出为 ‘\r’+‘\n’。

int f_putc (
  TCHAR chr,  /* [IN] 要写的字符 */
  FIL* fp     /* [IN] 指向打开文件对象结构的指针 */
);
暂时未发现具体应用

f_gets的返回:当字符写入成功时,它返回写入文件的字符编码单元数。 当函数因磁盘已满或任何错误而失败时,将返回一个负值。

f_puts - 将字符串写入文件。

描述
当 FatFs 配置为 Unicode API (FF_LFN_UNICODE >= 1) 时,字符串函数、f_putc、f_puts、f_printf 和 f_gets 函数的字符编码也切换为 Unicode。 输入的多编码单元的Unicode字符,如代理对、多字节序列等,不能分成两个函数调用,否则会丢失字符。 通过此函数写入的文件的字符编码由 FF_STRF_ENCODE 选择。 编码错误或对输出编码无效的字符将丢失。

int f_puts (
  const TCHAR* str, /* [IN] 指向要写入的空终止字符串的指针。 不会写入终止符 */
  FIL* fp           /* [IN] 指向打开文件对象结构的指针 */
);
暂时未发现具体应用

f_puts的返回:当字符串写入成功时,它返回写入文件的字符编码单元数。 当函数因磁盘已满或任何错误而失败时,将返回一个负值。

f_printf - 将格式化字符串写入文件

描述
格式控制指令是标准库的一个子集,如下所示:

%[flag][width][precision][size]type

flag

填充选项。 A - 指定左对齐。 0 指定零填充。 默认设置是右对齐和空格填充。

width

字段的最小宽度,1-99 或 *。 如果生成的字符串的宽度小于最小宽度,则剩余字段用空格或零填充。 * 指定值来自 int 类型的参数。 默认设置为零。

precision

指定小数位数或字符串的最大宽度,.0-.99 或 .*。 如果省略数字,则与 .0 相同。 默认设置为数字 6,字符串无限制。

size

指定整数参数 l(long) 和 ll(long long) 的大小。 如果 sizeof (long) == sizeof (int) 为真(这是典型的 32 位系统),则可以省略长整型参数的前缀 l。 整数参数的默认大小为 int,浮点参数始终假定为 double 作为默认参数提升。

type

指定输出格式的类型和参数,如下所示。 生成字符串的长度假设 int 为 32 位。
在这里插入图片描述

当 FatFs 配置为 Unicode API (FF_LFN_UNICODE >= 1) 时,字符串函数、f_putc、f_puts、f_printf 和 f_gets 函数的字符编码也切换为 Unicode。 多个编码单元中的Unicode字符,如代理对、多字节序列等,不能分成两个函数调用,否则会丢失字符。 通过此函数写入的文件的字符编码由 FF_STRF_ENCODE 选择。 编码错误或对输出编码无效的字符将丢失。

如果项目中使用了 sprintf,并且不需要代码转换,f_write 和 sprintf 在代码大小和性能方面比 f_printf 更高效。

int f_printf (
  FIL* fp,          /* [IN] 指向打开文件对象结构的指针 */
  const TCHAR* fmt, /* [IN] 指向空的 '\0' 终止格式字符串的指针。 不会输出终止符。*/
  ...               /*Optional arguments...*/
);
f_printf(fp, "%d", 1234);             /* "1234" */

f_printf的返回: 当字符串写入成功时,它返回写入文件的字符编码单元数。 当函数因磁盘已满或错误而失败时,将返回一个负值。

f_tell - 获取文件的当前读/写指针

描述
在此版本中,f_tell 函数作为宏实现。 它没有任何验证和互斥。

#define f_tell(fp) ((fp)->fptr)
FSIZE_t f_tell (
  FIL* fp   /* [IN] 指向打开文件对象结构的指针 */
);
	/* 高级读写指针3000字节 */
    res = f_lseek(fp, f_tell(fp) + 3000);

f_tell的返回:返回文件的当前读/写指针。

f_eof - 测试文件的文件结尾

描述
在此版本中,此功能作为宏实现。 它没有任何验证和互斥。

#define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
int f_eof (
  FIL* fp   /* [IN] 指向打开文件对象结构的指针 */
);
/* 重复该操作,直到文件指针到达文件末尾 */
    while (rc == FR_OK && !f_eof(&fil)) {
    ...
}

f_eof的返回: 如果读/写指针已到达文件末尾,f_eof 函数将返回一个非零值; 否则返回零。

f_size - 获取文件的大小

描述
在此版本中,f_size 函数作为宏实现。 它没有任何验证和互斥。

#define f_size(fp) ((fp)->obj.objsize)
FSIZE_t f_size (
  FIL* fp   /* 指向打开文件对象结构的指针。 */
);
 /* 将读/写指针设置为文件末尾以追加数据 */
    res = f_lseek(fp, f_size(fp));

f_size的返回:以字节为单位,返回文件的大小。

f_error - 测试文件上的错误

描述
在此版本中,此功能作为宏实现。 它没有任何验证和互斥。

#define f_error(fp) ((fp)->err)
int f_error (
  FIL* fp   /* 指向打开文件对象结构的指针。 */
);

f_error的返回:如果发生硬错误,则返回一个非零值; 否则返回零。

目录访问类

f_opendir - 打开一个目录

描述
f_opendir 函数打开一个现有目录并为后续的 f_readdir 函数创建一个目录对象。

FRESULT f_opendir (
  DIR* dp,           /* 指向空白目录对象的指针,以创建一个新目录对象。 */
  const TCHAR* path  /* 指向指定要打开的目录名称的空终止字符串的指针。 */
);
res = f_opendir(&dir, path);                       /* 打开目录 */

f_opendir的返回值: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_PATH, FR_INVALID_NAME, FR_INVALID_OBJECT, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE, FR_TOO_MANY_OPEN_FILES

f_closedir - 关闭打开的目录

描述
f_closedir 函数关闭一个打开的目录对象。 函数执行成功后,目录对象不再有效,可以丢弃。

请注意,当未启用选项 FF_FS_LOCK 时,目录对象也可以在没有此过程的情况下被丢弃。 但是,为了将来的兼容性,不建议这样做。

FRESULT f_closedir (
  DIR* dp     /* 指向要关闭的打开目录对象结构的指针。 */
);
f_closedir(&dir);

** f_closedir的返回值:** FR_OK, FR_INT_ERR, FR_INVALID_OBJECT, FR_TIMEOUT

f_readdir - 读取目录的一项

描述
f_readdir 函数从打开的目录中读取目录项,有关对象的信息。 目录中的项目可以通过 f_readdir 函数调用按顺序读取。 当目录中的所有项都已读取且没有要读取的项时,空字符串将毫无错误地存储到 fno->fname[] 中。 当向 fno 提供空指针时,目录对象的读取索引将倒带。 f_rewinddir 函数作为宏实现。

#define f_rewinddir(dp) f_readdir((dp), 0)

当启用LFN(长文件名)时,在文件信息结构中定义一个成员altname[]来存储对象的短文件名。 如果由于下面列出的原因无法访问长文件名,则将短文件名存储到 fname[] 并且 altname[] 具有空字符串。

  • 该商品没有 LFN。 (exFAT 卷不是这种情况)
  • FF_MAX_LFN 不足以处理 LFN。 (FF_MAX_LFN == 255 不是这种情况)
  • FF_LFN_BUF 不足以存储 LFN。
  • LFN 包含一些当前 CP 中未定义的字符。 (FF_LFN_UNICODE
    不是这种情况!= 0)

exFAT 卷中的读取目录存在问题。 exFAT 不支持短文件名。 这意味着在上述条件下不能返回名称。 如果是这样,“?” 作为文件名返回以指示该对象不可访问。 为避免此问题,请配置 FatFs FF_LFN_UNICODE != 0 和 FF_MAX_LFN == 255 以支持 LFN 规范的全部功能。

FAT 卷子目录中的点条目(“.”和“…”)被过滤掉,它们将永远不会出现在读取项中,因为 exFAT 没有子目录中的点条目。

FRESULT f_readdir (
  DIR* dp,      /* 指向打开目录对象的指针*/
  FILINFO* fno  /* 指向文件信息结构的指针,用于存储有关读取项目的信息。 空指针倒带目录的读取索引。 */
);
res = f_readdir(&dir, &fno);                /* 读取目录项 */
FRESULT f_rewinddir (
  DIR* dp       /* 指向打开目录对象的指针 */
);

f_readdir的返回值: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_INVALID_OBJECT, FR_TIMEOUT, FR_NOT_ENOUGH_CORE

f_findfirst - 在目录中搜索项目

描述
path指定的目录可以打开后,开始在目录中搜索匹配pattern指定模式的项。 如果找到第一个项目,则将有关该项目的信息存储到文件信息结构 fno 中。 如果未找到,则 fno->fname[] 为空字符串。

匹配模式字符串可以包含通配符。 例如:

  • ? - 任何字符。
  • ??? - 长度为三个字符的任意字符串。
  • * - 长度为零或更长的任何字符串。
  • ? ? ? ?* - 长度为四个字符或更长的任意字符串。

由于匹配算法使用递归,匹配模式中的通配符数量限制为四个以限制堆栈使用。 任何具有太多通配符的模式都不匹配任何名称。 在LFN配置中,当FF_USE_FIND == 1时只测试fname[],当FF_USE_FIND == 2时也会测试altname[]。FatFs和标准系统在匹配条件上有一些区别如下。

  • “*.*” 不匹配任何不带扩展名的名称,而在标准系统中匹配任何带或不带扩展名的名称。
  • 以点结尾的任何模式不匹配任何名称,而在标准系统中它匹配没有扩展名的名称。
  • 当使用 !FF_LFN_UNICODE 启用 LFN 时,比较DBCS 扩展字符时区分大小写。
FRESULT f_findfirst (
  DIR* dp,              /* 指向空白目录对象的指针 */
  FILINFO* fno,         /* 指向文件信息结构的指针,用于存储有关找到的项目的信息 */
  const TCHAR* path,    /* 指向指定要打开的目录名称的空终止字符串的指针。 */
  const TCHAR* pattern  /* 指向以 nul 结尾的字符串的指针,该字符串指定要搜索的名称匹配模式。  */
   /*它也被后续的 f_findnext 函数引用,因此字符串在后续函数调用时必须有效。 */
);
fr = f_findfirst(&dj, &fno, "", "????????.JPG"); /* 开始搜索图片文件 */

f_findfirst的返回值: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_PATH, FR_INVALID_NAME, FR_INVALID_OBJECT, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE, FR_TOO_MANY_OPEN_FILES

f_findnext - 搜索下一个匹配的对象

描述
它继续从先前调用 f_findfirst 或 f_findnext 函数开始的搜索。 如果找到,则将有关对象的信息存储到文件信息结构中。 如果没有要读取的项目,将向 fno->fname[] 返回一个空字符串。

FRESULT f_findnext (
  DIR* dp,              /* 指向由 f_findfirst 函数创建的有效目录对象的指针 */
  FILINFO* fno          /* 指向文件信息结构的指针,用于存储有关找到的目录项的信息 */
);
fr = f_findnext(&dj, &fno);               /* 查找下一项目 */

f_findnext的返回值: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_OBJECT, FR_TIMEOUT, FR_NOT_ENOUGH_CORE

文件和目录管理类

f_stat - 检查文件或子目录是否存在

描述
f_stat 函数检查目录中是否存在文件或子目录。 如果不存在,函数返回 FR_NO_FILE。 如果存在,则函数返回 FR_OK,并将有关对象、大小、时间戳和属性的信息存储到文件信息结构中。 有关文件信息的详细信息,请参阅 FILINFO 结构和 f_readdir 函数。

请注意,文件信息来自目录中的元数据。 如果文件已被打开和修改,则需要同步或关闭文件以获取最新的文件信息。

FRESULT f_stat (
  const TCHAR* path,  /* 指向指定对象以获取其信息的空终止字符串的指针。 */
  /* 该对象不能是根目录。 */
  FILINFO* fno        /* 指向空白 FILINFO 结构的指针,用于存储对象的信息。 */
  /*如果不需要此信息,则设置空指针。 */
);
fr = f_stat(fname, &fno);

f_stat的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH, FR_INVALID_NAME, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE

f_unlink - 从卷中删除文件或子目录

描述
如果被删除对象的条件适用于以下条款,则该功能将被拒绝。

  • 文件/子目录不能有只读属性(AM_RDO),否则该函数将被拒绝并返回 FR_DENIED。
  • 子目录必须为空且不能是当前目录,否则该函数将被拒绝并返回 FR_DENIED。
  • 不能打开文件/子目录,或者 FAT 卷可能会折叠(collapse)。当启用文件锁定功能时,它将被安全地拒绝。
FRESULT f_unlink (
  const TCHAR* path  /* 指向指定要删除的文件或子目录的空终止字符串的指针 */
);

f_unlink的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH, FR_INVALID_NAME, FR_DENIED, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_LOCKED, FR_NOT_ENOUGH_CORE

f_rename - 重命名或 移动 文件或子目录。

描述
重命名文件或子目录,也可以将其移动到同一卷中的其他目录。 要重命名的对象不能是打开的对象,否则 FAT 卷会被折叠。 当启用文件锁定功能时,此类错误操作将被安全拒绝。

FRESULT f_rename (
  const TCHAR* old_name, /* 指向指定要重命名的现有文件或子目录的空终止字符串的指针。 */
  const TCHAR* new_name  /* 指向指定新对象名称的空终止字符串的指针。 */
  /*可以在此字符串中指定驱动器编号,但它会被忽略并假定为与 old_name 相同的驱动器。 */
 /* 除 old_name 外,具有此路径名的任何对象不得存在,否则该函数将因 FR_EXIST 而失败。 */
);
f_rename("2:oldname.txt", "newname.txt");
f_rename("oldname.txt", "newname.txt");
f_rename("log.txt", "old/log0001.txt");

f_rename的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH, FR_INVALID_NAME, FR_EXIST, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_LOCKED, FR_NOT_ENOUGH_CORE

f_chmod - 更改文件或子目录的属性

描述
更改文件或子目录的属性

FRESULT f_chmod (
  const TCHAR* path, /* 指向指定要更改的对象的空终止字符串的指针 */
  BYTE attr,         /* 要设置为以下标志的一个或多个组合的属性标志。 */
  /* 设置指定的标志并清除其他标志。 */
   /* Attribute		Description */
   /* AM_RDO	    只读*/
   /* AM_ARC		Archive档案 */
   /* AM_SYS		系统 */
   /* AM_HID		隐藏 */
  BYTE mask          /* 指定更改哪个属性的属性掩码。 */
  /* 设置或清除指定的属性,其他属性保持不变。 */
);

/* 设置Read-only,清除 Archive,其他不变。 */
    f_chmod("file.txt", AM_RDO, AM_RDO | AM_ARC);

f_chmod的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH, FR_INVALID_NAME, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE

f_utime - 更改文件或子目录的时间戳

描述
更改文件或子目录的时间戳

FRESULT f_utime (
  const TCHAR* path,  /* 指向指定要更改的对象的空终止字符串的指针。 */
  const FILINFO* fno  /* 指向文件信息结构的指针,该文件信息结构具有要在成员 */
  /* fdate 和 ftime 中设置的时间戳。 不关心任何其他成员。 */
);
 return f_utime(obj, &fno);

f_utime的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH, FR_INVALID_NAME, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE

f_mkdir - 创建一个新目录

描述
创建一个新目录。 要删除目录,请使用 f_unlink 函数。

FRESULT f_mkdir (
  const TCHAR* path /* 指向指定要创建的目录名称的空终止字符串的指针。 */
);
 res = f_mkdir("sub1");

f_mkdir的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_PATH, FR_INVALID_NAME, FR_DENIED, FR_EXIST, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE

f_chdir - 更改逻辑驱动器的当前目录

描述
f_chdir 函数更改逻辑驱动器的当前目录。 此外,在 Unix 风格的驱动器前缀 FF_STR_VOLUME_ID == 2 中,当前驱动器将被更改。每个逻辑驱动器的当前目录在挂载时被初始化为根目录。

请注意,当前目录保留在每个文件系统对象中,当前驱动器保留在静态变量中,因此它也会影响使用文件功能的其他任务。

FRESULT f_chdir (
  const TCHAR* path /* 指向指定要设置为当前目录的目录的空终止字符串的指针。 */
);
/* 更改当前驱动器的当前目录(根目录下的“dir 1”) */
    f_chdir("/dir1");

f_chdir的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_PATH, FR_INVALID_NAME, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE## f_chdrive - Change current drive

f_chdrive - 更改当前驱动器

描述
f_chdrive 函数仅更改当前驱动器。 当前驱动器编号的初始值为 0。在 Unix 风格的驱动器前缀配置中,不需要此函数,因为 f_chdir 函数也会更改当前驱动器。 请注意,当前驱动器保留在静态变量中,因此它也会影响使用文件功能的其他任务。

FRESULT f_chdrive (
  const TCHAR* path  /* 指定要设置为当前驱动器的逻辑驱动器号 */
);
f_chdrive("2:");  /* 将驱动器 2 设置为当前驱动器 */
f_chdrive("");   /* 无影响(设置当前驱动为当前驱动) */

f_chdrive的返回码: FR_OK, FR_INVALID_DRIVE

f_getcwd - 检索当前驱动器的当前目录

描述
f_getcwd 函数检索当前驱动器当前目录的完整路径名。 当 FF_VOLUMES >= 2 时,标题驱动器前缀添加到路径名。 驱动器前缀的样式取决于 FF_STR_VOLUME_ID。

注意:在此版本中,此功能无法检索 exFAT 卷上的当前目录路径。 它总是返回根目录路径。

FRESULT f_getcwd (
  TCHAR* buff, /* 指向接收当前目录字符串的缓冲区的指针。 */
  UINT len     /* 以 TCHAR 为单位的缓冲区大小。 */
);
fr = f_getcwd(str, SZ_STR);  /* 获得当前目录路径 */

f_getcwd的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_NOT_ENOUGH_CORE

卷管理和系统配置

f_mount - 注册/注销卷的工作区

描述
FatFs 需要每个逻辑驱动器(FAT 卷)的工作区(文件系统对象)。 在执行任何文件/目录操作之前,需要使用逻辑驱动器的 f_mount 函数注册文件系统对象。 文件/目录 API 函数在此过程后准备工作。 一些卷管理函数,f_mkfs、f_fdisk 和 f_setcp,不需要文件系统对象。

f_mount 函数向 FatFs 模块注册/取消注册文件系统对象,如下所示:

  1. 确定路径指定的逻辑驱动器。
  2. 清除并注销卷的已注册工作区(如果存在)。
  3. 如果 fs 不为 NULL,则清除新工作区并将其注册到卷。
  4. 如果指定了强制安装,则对卷执行卷安装过程。 如果逻辑驱动器上有任何打开的文件或目录对象,该对象将被该函数作废。

如果未指定强制安装 (opt = 0),则无论物理驱动器状态如何,此功能始终成功。 它仅清除(取消初始化)给定的工作区并将其地址注册到内部表,并且在此函数中没有物理驱动器的活动。 如果文件系统对象未初始化,则将在后续文件/directroy 函数上尝试卷安装过程。 (延迟挂载)卷挂载过程,初始化相应的物理驱动器,在其中找到FAT卷,然后初始化工作区,当以下任一条件为真时,在后续的文件/目录函数中执行。

  • 文件系统对象尚未初始化。 它由 f_mount 函数取消初始化。
  • 物理驱动器未初始化。 它通过系统重置或媒体移除来取消初始化。

如果强制挂载 (opt = 1) 的函数因 FR_NOT_READY 而失败,则意味着文件系统对象已成功注册,但该卷目前尚未准备好工作。 将在后续文件/目录功能上尝试卷安装过程。

如果磁盘 I/O 层的实现缺少异步介质变化检测,则应用程序需要在每次介质变化后执行 f_mount 函数以强制清除文件系统对象。

要注销工作区,给fs指定一个NULL,然后工作区就可以被丢弃。 f_unmount 函数以宏的形式实现。

#define f_unmount(path) f_mount(0, path, 0)
FRESULT f_mount (
  FATFS*       fs,    
  /* 指向要注册和清除的文件系统对象的指针。 */
  /*空指针取消注册已注册的文件系统对象。 */
  const TCHAR* path,  
  /* 指向指定逻辑驱动器的空终止字符串的指针。 */
  /* 没有驱动器号的字符串表示默认驱动器。 */
  BYTE         opt    
  /* 安装选项。 0:现在不挂载(在第一次访问该卷时挂载)*/
  /*1:强制挂载该卷以检查它是否准备好工作。n */
);
 f_mount(fs, "", 0);       /* 挂载默认驱动器 */
FRESULT f_unmount (
  const TCHAR* path   
  /* 指向指定逻辑驱动器的空终止字符串的指针。 */
  /* 没有驱动器号的字符串表示默认驱动器。 */
);

f_mount的返回值: FR_OK, FR_INVALID_DRIVE, FR_DISK_ERR, FR_NOT_READY, FR_NOT_ENABLED, FR_NO_FILESYSTEM

f_mkfs - 在逻辑驱动器上创建一个 FAT/exFAT 卷。

描述
根据 Microsoft 发布的 FAT 规范,除 exFAT 之外的 FAT 卷的 FAT 子类型 FAT12/FAT16/FAT32 仅由卷上的簇数决定,与其他无关。 因此,创建的卷的 FAT 子类型取决于卷大小和簇大小。 如果参数指定的 FAT 类型和簇大小的组合对于卷大小无效,则该函数将失败并返回 FR_MKFS_ABORTED。

分配单元,也称为,是为文件分配磁盘空间的单位。 当分配单元的大小为32768字节时,一个100字节大小的文件占用32768字节的磁盘空间。 随着分配单元大小的增加,磁盘使用的空间效率会变差,但另一方面,读/写性能会提高。 因此,分配单元的大小是空间效率和性能之间的权衡。 对于以 GB 为单位的大卷,大多数情况下建议默认自动选择 32768 字节或更大,除非在卷中创建了非常多的小文件。

当要格式化的逻辑驱动器与物理驱动器相关联(FF_MULTI_PARTITION == 0 或 VolToPart[].pt == 0)且未指定 FM_SFD 标志时,创建一个分区占用整个驱动器空间,然后创建 FAT 卷 在分区中。 当指定 FM_SFD 标志时,创建 FAT 卷时没有任何磁盘分区。

当要格式化的逻辑驱动器通过多分区特性关联到特定分区时(FF_MULTI_PARTITION == 1 和 VolToPart[].pt > 0),FAT 卷在卷映射表指定的物理驱动器的分区中创建,并且 忽略 FM_SFD 标志。 在使用此功能创建 FAT 卷之前,需要使用 f_fdisk 功能或任何分区工具对托管物理驱动器进行分区。 如果分区不存在,该函数将以 FR_MKFS_ABORTED 中止。

共有三种标准的磁盘分区格式,MBR、GPT 和 SFD。 MBR格式,又称FDISK格式,通常用于硬盘、存储卡和U盘。 它可以使用分区表将物理驱动器划分为一个或多个分区。 GPT,即 GUID 分区表,是一种为大型存储设备新定义的分区格式。 FatFs 仅在启用 64 位 LBA 时才支持 GPT。 SFD,即超级软盘,是一种非分区磁盘格式。 FAT 卷位于 LBA 0 并占据整个物理驱动器,没有任何磁盘分区。 它通常用于软盘、光盘和大多数超级软盘介质。 某些系统和媒体组合仅支持分区格式或非分区格式,不支持另一种。

一些系统以非标准格式管理板载存储中的分区。 分区被映射为由 disk_* 函数中的 pdrv 标识的物理驱动器。 对于此类系统,SFD 格式适合在分区中创建 FAT 卷。

FRESULT f_mkfs (
  const TCHAR* path,   
  /* 指向以 null 结尾的字符串的指针指定要格式化的逻辑驱动器。 
  如果其中没有驱动器号,则表示指定默认驱动器。 
  逻辑驱动器可能已安装也可能未安装用于格式化过程。 */
  const MKFS_PARM* opt,
  /* 指定格式选项结构 MKFS_PARM 持有格式选项。 
  如果给出空指针,它会以默认值为函数提供每个选项。 
  该结构有五个成员,顺序如下: */
  void* work,          
  /* 向用于格式化过程的工作缓冲区的指针。 
  如果 FF_USE_LFN == 3 给出空指针,
  则该函数在此函数中使用 len 字节的堆内存。 */
  UINT len             
  /* 以字节为单位的工作缓冲区的大小。 它至少需要是 FF_MAX_SS。 
  大量的工作缓冲区减少了写入驱动器的事务数量,因此格式化过程将很快完成。 */
);

/* 使用默认参数格式化默认驱动器 */
    res = f_mkfs("", 0, work, sizeof work);

opt:

  • BYTE fmt

指定 FAT 类型标志 FM_FAT、FM_FAT32、FM_EXFAT 和这三者的按位或 FM_ANY 的组合。 未启用 exFAT时忽略 FM_EXFAT。 这些标志指定要创建的 FAT 卷类型。 如果指定了两种或多种类型,将根据卷大小和 au_size 选择其中一种。标志 FM_SFD 指定以 SFD 格式在驱动器上创建卷。 默认值为 FM_ANY。

  • BYTE n_fat

指定 FAT/FAT32 卷上的 FAT 副本数。 此成员的有效值为 1 或 2。默认值 (0) 和任何无效值都为 1。如果 FAT 类型为exFAT,则此成员无效。

  • UINT n_align

以扇区为单位指定卷数据区(文件分配池,通常是闪存介质的擦除块边界)的对齐方式。 该成员的有效值介于 1 和 32768 之间(包括 2的幂)。如果给出零(默认值)或任何无效值,该函数将使用 disk_ioctl 函数从较低层获取块大小。

  • DWORD au_size

以字节为单位指定分配单元(簇)的大小。 对于 FAT/FAT32 卷,有效值为扇区大小和 128 * 扇区大小(包括在内)之间的 2的幂,或者对于 exFAT 卷,最大为 16 MB。 如果给出零(默认值)或任何无效值,则该函数使用默认分配单元大小,具体取决于卷大小。

  • UINT n_root

指定 FAT 卷上的根目录条目数。 此成员的有效值最大为 32768 并与扇区大小/32 对齐。默认值 (0) 和任何无效值都为512。如果 FAT 类型为 FAT32 或 exFAT,则此成员无效。

f_mkfs的返回值: FR_OK, FR_DISK_ERR, FR_NOT_READY, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_MKFS_ABORTED, FR_INVALID_PARAMETER, FR_NOT_ENOUGH_CORE

f_fdisk - 划分一个物理驱动器,在物理驱动器上创建分区

描述
f_fdisk 函数在物理驱动器上创建分区。 分区格式可以是通用的 MBR 或 GPT。 分区映射表指定了如何划分物理驱动器。 第一项指定第一个分区的大小,分区按从第一项开始的顺序位于驱动器上。 当 item 的值小于或等于 100 时,它以占整个驱动器空间的百分比指定分区大小。 当它大于 100 时,它指定扇区数。 分区映射表以零结尾,没有剩余空间可用于下一次分配或以 MBR 格式创建第 4 个分区。 如果指定的大小大于驱动器上的剩余空间,则分区将在驱动器末尾被截断。

默认情况下,分区以 MBR 格式创建。 它最多可以在一个驱动器上创建四个主分区。 GPT 格式用于在启用 64 位 LBA (FF_LBA64 = 1) 且驱动器大小等于或大于 FF_MIN_GPT 扇区时创建分区。 它可以在一个驱动器上创建十多个分区

FRESULT f_fdisk (
  BYTE  pdrv,         
  /* 指定要划分的物理驱动器。 这不是逻辑驱动器号,
  而是传递给低级磁盘函数的驱动器标识符。 */
  const LBA_t ptbl[], 
  /* 要在驱动器上创建的分区大小列表。 
  数据类型 LBA_t 是 DWORD 或 QWORD 的别名取决于配置选项 FF_LBA64。 */
  void* work         
   /* 指向函数工作区的指针。 大小必须至少为 FF_MAX_SS 字节。
   当 FF_USE_LFN = 3 给出空指针时,在此函数中为工作缓冲区获取一个内存块。a */
);

f_fdisk(0, plist, work);                    /* Divide physical drive 0 */

f_fdisk的返回码: FR_OK, FR_DISK_ERR, FR_NOT_READY, FR_WRITE_PROTECTED, FR_INVALID_PARAMETER, FR_NOT_ENOUGH_CORE

f_getfree -获取卷上空闲簇的数量。

描述
f_getfree 函数获取卷上的空闲簇数。 文件系统对象中的成员 csize 指示每个簇的扇区数,因此可以使用此信息计算以扇区为单位的可用空间。 如果 FAT32 卷上的 FSINFO 结构不同步,此函数可能会返回不正确的空闲簇计数。 为了避免这个问题,可以通过 FF_FS_NOFSINFO 选项强制 FatFs 进行完整的 FAT 扫描。

FRESULT f_getfree (
  const TCHAR* path,  
  /* 指向指定逻辑驱动器的空终止字符串的指针。 空字符串表示默认驱动器。 */
  DWORD* nclst,       /* 指向用于存储空闲簇数的 DWORD 变量的指针。 */
  FATFS** fatfs       /* 指针指向存储指向相应文件系统对象的指针。 */
);
 /* 获取驱动器 1 的卷信息和空闲簇 */
res = f_getfree("1:", &fre_clust, &fs);

f_getfree的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT

f_getlabel - 返回卷的卷标和卷序列号

FRESULT f_getlabel (
  const TCHAR* path, 
  /* 指向指定逻辑驱动器的空终止字符串的指针。 空字符串指定默认驱动器。*/
  TCHAR* label,       
  /* 指向用于存储卷标的缓冲区的指针。 如果卷没有标签,将返回空字符串。 
  如果不需要此信息,则设置空指针。 缓冲区大小至少应显示在下方以避免缓冲区溢出。 */
  DWORD* vsn          
  /* 指向用于存储卷序列号的 DWORD 变量的指针。 如果不需要此信息,则设置空指针。 */
);

	/* 获取默认驱动器的卷标 */
    f_getlabel("", str, 0);
    /* 获取驱动器 2 的卷标 */
    f_getlabel("2:", str, 0);

在这里插入图片描述
f_getlabel的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT

f_setlabel - 设置/删除卷的标签

描述
当字符串具有驱动器前缀时,卷标将设置为驱动器前缀指定的卷。 Unix 样式的卷 ID 不能用于指定卷。 如果未指定驱动器号,则卷标将设置为默认驱动器。 如果给定卷标的长度为零,则将删除卷上的卷标。 卷标的格式如下图所示:

  • 最多 11 个字节,与 FAT 卷中的 OEM 代码页转换一样长。
  • exFAT 卷最多 11 个字符。
  • FAT 卷允许的字符是:SFN允许的字符不包括点。 小写字符向上转换。
  • exFAT 卷允许的字符是:LFN 允许的字符包括点。 保留小写字符。
  • 空格可以嵌入卷标中的任何位置。 尾随空格在 FAT 卷中被截断。

备注:标准系统(Windows)在 FAT 卷上标题为 \xE5 的卷标处有问题。 为避免此问题,此功能拒绝此类卷标作为无效名称。

FRESULT f_setlabel (
  const TCHAR* label  /* 指向指定要设置的卷标的空终止字符串的指针。 */
);
	/* 将卷标设置为默认驱动器 */
    f_setlabel("DATA DISK");
    /* 为驱动器 2 设置卷标 */
    f_setlabel("2:DISK 3 OF 4");
    /* 删除驱动器 2 的卷标 */
    f_setlabel("2:");

f_setlabel的返回码: FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_INVALID_NAME, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT

f_setcp - 设置活动代码页

描述
f_setcp 函数设置路径名的活动代码页。 当FF_LFN_UNICODE >= 1 和FF_STRF_ENCODE == 0 时,字符串函数的代码转换会受到代码页设置的影响。由于代码页的初始设置为0,具有扩展字符的API 函数将无法正常工作,有效代码页面需要在系统启动时设置,不应即时更改。

FRESULT f_setcp (
  WORD cp     /* 用于路径名的 OEM 代码页。 有效值如下。 */
);

在这里插入图片描述
f_setcp的返回码: FR_OK, FR_INVALID_PARAMETER

Media Access Interface(MAI,媒体访问接口)——FatFs与存储介质之间的接口函数

由于FatFs模块是独立于平台和存储介质的文件系统层,它完全脱离了物理设备,如存储卡、硬盘和任何类型的存储设备。 存储设备控制模块不是FatFs模块的任何部分,需要由实现者提供。
FatFs 通过如下所示的简单媒体访问接口控制存储设备。 下载中还提供了某些平台的示例实现。 此处提供存储设备控制模块的功能检查器。
在这里插入图片描述

存储设备控制

disk_status - 查询当前驱动器状态

DSTATUS disk_status (
  BYTE pdrv     
  /* 用于标识目标设备的物理驱动器号。 
  在单驱动系统中始终为零。 */
);

disk_status的返回值: 当前驱动器状态结合下面描述的状态标志返回。 FatFs 仅指 STA_NOINIT 和 STA_PROTECT。

STA_NOINIT
指示设备尚未初始化且未准备好工作。 该标志在系统重置、介质移除或 disk_initialize 函数失败时设置。 它在 disk_initialize 函数成功时被清除。 必须捕获异步发生的任何媒体更改并将其反映到状态标志,否则自动安装功能将无法正常工作。 如果系统不支持媒体更改检测,应用程序需要在每次媒体更改后使用 f_mount 函数显式地重新挂载卷。

STA_NODISK
表示驱动器中没有介质。 当驱动器是不可移动类时,它总是被清除。 请注意,FatFs 不引用此标志。

STA_PROTECT
指示介质被写保护。 当驱动器没有写保护功能时,它总是被清除。 如果设置了 STA_NODISK,则无效。

disk_initialize - 初始化存储设备

描述
此函数初始化存储设备并使其准备好进行通用读/写。 当函数成功时,返回值中的 STA_NOINIT 标志被清除。

备注:该功能需要被FatFs模块控制。 在使用 FatFs 时,应用程序不得调用此函数,否则卷上的 FAT 结构可能会被破坏。 要重新初始化文件系统,请改用 f_mount 函数。

DSTATUS disk_initialize (
  BYTE pdrv           
  /* 用于标识目标设备的物理驱动器号。 
  单驱动系统始终为零。*/
);

disk_initialize 的返回值: 该函数返回当前驱动器状态标志作为结果。 有关驱动器状态的详细信息,请参阅 disk_status 函数。

disk_read - 从存储设备中读取数据

描述
对通用存储设备(如存储卡、硬盘和光盘)的读/写操作以称为扇区的数据字节块为单位进行。

FatFs 支持 512 到 4096 字节范围内的扇区大小。 当 FatFs 配置为固定扇区大小时(FF_MIN_SS == FF_MAX_SS,这是大多数情况),通用读/写功能必须仅在此扇区大小下工作。 当 FatFs 配置为可变扇区大小(FF_MIN_SS < FF_MAX_SS)时,在 disk_initialize 函数成功后使用 disk_ioctl 函数查询介质的扇区大小。

关于通过 buff 传递的内存地址有一些注意事项。 它并不总是与单词边界对齐,因为参数定义为 BYTE*。 未对齐的传输请求可以在直接传输时发生。 如果总线架构,尤其是DMA控制器,不允许未对齐的内存访问,应该在这个函数中解决。 如果是这种情况,下面描述了一些解决方法来避免此问题。

  • 使用此函数中的一些技巧将字传输转换为字节传输。 - 推荐
  • 在 f_read() 调用中,避免包含整个扇区的长读取请求。 - 永远不会发生任何直接转移。
  • 在 f_read(fp, data, btw, bw) 调用中,确保 (((UINT)data & 3) == (f_tell(fp) & 3)) 为真。 - 保证 buff 的字对齐。

此外,内存区域可能在 DMA 中无法访问。 如果它位于通常用于堆栈的紧耦合内存上,就会出现这种情况。 使用双缓冲传输,或避免将文件 I/O 缓冲区、FATFS 和 FIL 结构定义为堆栈上的局部变量。

通常,多扇区读取请求不得拆分为存储设备的单扇区事务,否则读取吞吐量会变差。

DRESULT disk_read (
  BYTE pdrv,     /* 标识目标设备的物理驱动器号。 */
  BYTE* buff,    
  /* 指向存储读取数据的字节数组第一项的指针。 
  读取数据的大小将是扇区大小 * 计数字节。 */
  LBA_t sector,  
  /* LBA 中的起始扇区号。 
  数据类型 LBA_t 是 DWORD 或 QWORD 的别名,
  具体取决于配置选项 */
  UINT count     /* 要读取的扇区数 */
);

disk_read的返回码:
RES_OK (0):函数成功
RES_ERROR:读取操作期间发生不可恢复的硬错误
RES_PARERR:无效的参数
RES_NOTRDY:设备尚未初始化

disk_write - 将数据写入存储设备

描述
指定的内存地址并不总是与字边界对齐,因为参数定义为 BYTE*。 有关详细信息,请参阅 disk_read 函数的说明。

通常,多扇区写入请求(计数> 1)不得拆分为存储设备的单扇区事务,否则文件写入吞吐量将急剧下降。

FatFs 期待磁盘控制层的延迟写入功能。 当写操作正在进行或数据仅存储到回写缓存中时,从该函数返回时不需要完成对介质的写操作。 但是从这个函数返回后,写入buff的数据是无效的。 写入完成请求由disk_ioctl函数的CTRL_SYNC命令完成。 因此,如果实现延迟写入功能,将提高文件系统的写入吞吐量。

备注:应用程序不得调用此函数,否则卷上的 FAT 结构可能会崩溃。

DRESULT disk_write (
  BYTE pdrv,        /* 标识目标设备的物理驱动器号 */
  const BYTE* buff, 
  /* 指向要写入的字节数组的第一项的指针。
   要写入的数据大小为扇区大小 * 计数字节。 */
  LBA_t sector,     /* LBA 中的起始扇区号。 
  数据类型 LBA_t 是 DWORD 或 QWORD 的别名,具体取决于配置选项。 */
  UINT count        /* 要写入的扇区数 */
);

disk_write返回值:
RES_OK (0):函数成功
RES_ERROR:写入操作期间发生不可恢复的硬错误
RES_WRPRT:介质被写保护
RES_PARERR:无效的参数
RES_NOTRDY:设备尚未初始化

disk_ioctl - 控制设备特定的功能和通用读/写以外的其他功能

描述
FatFs 模块只需要下面描述的五个设备独立命令

命令描述
CTRL_SYNC确保设备已完成挂起的写入过程。 如果磁盘 I/O 层或存储设备有回写缓存,脏缓存数据必须立即提交到介质。 如果对介质的每个写操作都在 disk_write 函数中完成,则此命令无关紧要。
GET_SECTOR_COUNT将驱动器上的可用扇区数(最大允许 LBA + 1)检索到 buff 指向的 LBA_t 变量中。 f_mkfs 和 f_fdisk 函数使用此命令来确定要创建的卷/分区的大小。
GET_SECTOR_SIZE将扇区大小、通用读/写的最小数据单元检索到 buff 指向的 WORD 变量中。 有效扇区大小为 512、1024、2048 和 4096。仅当 FF_MAX_SS > FF_MIN_SS 时才需要此命令。 当 FF_MAX_SS == FF_MIN_SS 时,将永远不会使用此命令并且 disk_read 和 disk_write 函数必须在 FF_MAX_SS 字节/扇区中工作。
GET_BLOCK_SIZE将闪存介质的以扇区为单位的擦除块大小检索到 buff 指向的 DWORD 变量中。 允许值为 1 到 32768 的 2 次幂。如果未知或在非闪存介质中,则返回 1。 此命令由未指定块大小的 f_mkfs 函数使用,它会尝试将数据区域对齐到建议的块边界上。 注意FatFs没有FTL(flash translation layer),所以无论是磁盘I/O层还是存储设备都必须有FTL在里面。
CTRL_TRIM通知磁盘 I/O 层或存储设备不再需要扇区块上的数据,可以将其擦除。 扇区块在 buff 指向的 LBA_t 数组 {<Start LBA>, <End LBA>} 中指定。 这是与 ATA 设备的 Trim 相同的命令。 如果不支持此功能或不是闪存设备,则此命令无事可做。 FatFs 不检查结果码,即使扇区块没有擦除好也不影响文件功能。 在删除集群链和 f_mkfs 函数中调用此命令。 当 FF_USE_TRIM == 1 时需要。

fatFs 永远不会使用任何依赖于设备的命令或用户定义的命令。 下表显示了可能对某些应用程序有用的非标准命令示例。

命令描述
CTRL_FORMAT在媒体上创建物理格式。 如果buff不为空,则为进度通知回调函数的指针。
CTRL_POWER_IDLE将设备置于空闲状态。 如果设备通过通用读/写功能进入活动状态,则可能不会设置当前状态标志中的 STA_NOINIT。
CTRL_POWER_OFF使设备处于关闭状态。 如果需要,关闭设备电源并取消初始化设备接口。 必须设置当前状态标志中的 STA_NOINIT。 设备通过 disk_initialize 函数进入活动状态。
CTRL_LOCK锁定介质弹出机制。
CTRL_UNLOCK解除锁定介质弹出机制。
CTRL_EJECT弹出介质盒。 状态标志中的 STA_NOINIT 和 STA_NODISK 在函数成功后设置。
CTRL_GET_SMART读取 SMART 信息。
MMC_GET_TYPE获取卡片类型。 类型标志 bit0:MMCv3、bit1:SDv1、bit2:SDv2+ 和 bit3:LBA 存储到 buff 指向的 BYTE 变量中。 (MMC/SDC 特定命令)
MMC_GET_CSD读取 CSD 寄存器并将其设置为 buff 指向的 16 字节缓冲区。 (MMC/SDC 特定命令)
MMC_GET_CID读取 CID 寄存器并将其设置到 buff 指向的 16 字节缓冲区中。 (MMC/SDC 特定命令)
MMC_GET_OCR读取 OCR 寄存器并将其设置为 buff 指向的 4 字节缓冲区。 (MMC/SDC 特定命令)
MMC_GET_SDSTAT读取 SDSTATUS 寄存器并将其设置为 buff 指向的 64 字节缓冲区。 (SDC 特定命令)
ATA_GET_REV读取修订字符串并将其设置到 buff 指向的 16 字节缓冲区中。 (ATA/CFC 特定命令)
ATA_GET_MODEL读取模型字符串并将其设置到 buff 指向的 40 字节缓冲区中。 (ATA/CFC 特定命令)
ATA_GET_SN读取序列号字符串并将其设置到 buff 指向的 20 字节缓冲区中。 (ATA/CFC 特定命令)
ISDIO_READ读取由 buff 指向的命令结构指定的 iSDIO 寄存器块。 (FlashAir 特定命令)
ISDIO_WRITE将数据块写入由 buff 指向的命令结构指定的 iSDIO 寄存器。 (FlashAir 特定命令)
ISDIO_MRITE更改由 buff 指向的命令结构指定的 iSDIO 寄存器中的位。 (FlashAir 特定命令)
DRESULT disk_ioctl (
  BYTE pdrv,     /* 用于标识目标设备的物理驱动器号 */
  BYTE cmd,      /* 命令代码 */
  void* buff     /* 指向参数的指针取决于命令代码。 
  不关心命令是否没有要传递的参数。 */
);

disk_ioctl的返回值:
RES_OK (0):函数成功。
RES_ERROR:发生错误。
RES_PARERR:命令代码或参数无效。
RES_NOTRDY:设备尚未初始化。

实时时钟

get_fattime - 获取当前时间

描述
即使系统不支持实时时钟,get_fattime 函数也应返回任何有效时间。 如果返回零,则文件将没有有效的时间戳。

DWORD get_fattime (void);

DWORD get_fattime (void)
{
    time_t t;
    struct tm *stm;
    
    t = time(0);
    stm = localtime(&t);

    return (DWORD)(stm->tm_year - 80) << 25 |
           (DWORD)(stm->tm_mon + 1) << 21 |
           (DWORD)stm->tm_mday << 16 |
           (DWORD)stm->tm_hour << 11 |
           (DWORD)stm->tm_min << 5 |
           (DWORD)stm->tm_sec >> 1;
}

get_fattime的返回值: Currnet 本地时间应作为位字段返回到 DWORD 值中。
位域如下:

  • bit31:25:从 1980 年开始的年份(0…127,例如 2017 年为 37)
  • bit24:21:月份(1-12)
  • bit20:16:日(1-31)
  • bit15:11:小时(0-23)
  • bit10:5: 分钟(0-59)
  • bit4:0 :秒(0-29, 25代表50)
  • 5
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值