简介

FATFS是一种开源文件系统模块,提供了一种轻量级、易移植的文件系统解决方案,使得嵌入式设备能够方便地管理存储设备上的文件。

对于有过编程经验的同学来说,通过FATFS在PS端进行文件交互操作,与其他编程语言在电脑上读取文件有着基本一致的流程,其调用的函数和实现的功能为

  1. 【f_mount】加载文件系统
  2. 【f_open】打开文件
  3. 【f_lseek】移动文件指针到指定位置
  4. 【f_write】写入文件
  5. 【f_read】读取文件
  6. 【f_close】关闭文件

这些函数在执行操作后均会返回一个表示状态的量,当其值为【FR_OK】即0时,表示该函数执行成功。由于FR_OK的通用性,故后文只介绍失败返回值。

和C语言标准库相比,这六个中只有f_mount相对陌生,其功能是在FatFs模块上注册/注销一个工作区,定义如下

FRESULT f_mount ( 
  BYTE  Drive,             /*  逻辑驱动器号  */ 
  FATFS*  FileSystemObject /*  工作区指针  */ 
);

参数

  • Drive 注册/注销工作区的逻辑驱动器号 (0-9) 。
  • FileSystemObject工作区(文件系统对象)指针,若为NULL,则该工作区将被丢弃。

当其返回值不为0时,返回R_INVALID_DRIVE表示驱动器号无效。

打开与关闭

打开、关闭、移动指针、读写这五个函数,在调用时都需要指名被操作的函数,即文件指针FileObject,因其通用性,故下文对此参数不再说明。

【f_open】用于创建/打开一个用于访问文件的文件对象,如果函数成功,则创建一个文件对象,该文对象可供读写和访问。需要注意,当文件使用过后,需要用f_close进行关闭,否则文件可能会崩溃。而在使用f_open之前,必须先用f_mount注册一个工作区。

FRESULT f_open ( 
  FIL* FileObject,         /*  空白文件对象结构指针  */ 
  const XCHAR* FileName,   /*  文件名指针  */ 
  BYTE ModeFlags           /*  模式标志  */ 
); 

参数

  • FileName 即文件名,是NULL 结尾的字符串指针
  • ModeFlags 文件模式,可选值包括
    • 【FA_READ】 读取模式
    • 【FA_WRITE】 写入模式
    • 【FA_OPEN_EXISTING】打开文件。如果文件不存在,则打开失败。 ( 默认 )
    • 【FA_OPEN_ALWAYS】如果文件存在,则打开;否则创建新文件。
    • 【FA_CREATE_NEW】创建一个新文件。如果文件已存在,则创建失败。
    • 不同模式可以用|进行连接,例如FA_READ|FA_WRITE表示读写模式。

失败返回值

  • FR_NO_FILE 找不到该文件。
  • FR_NO_PATH 找不到该路径。
  • FR_INVALID_NAME 文件名无效。
  • FR_INVALID_DRIVE 驱动器号无效。
  • FR_EXIST 该文件已存在。
  • FR_DENIED 由于下列原因,所需的访问被拒绝:
    • 以写模式打开一个只读文件。
    • 由于存在一个同名的只读文件或目录,而导致文件无法被创建。
    • 由于目录表或磁盘已满,而导致文件无法被创建。
  • FR_NOT_READY 由于驱动器中没有存储介质或任何其他原因,而导致磁盘驱动器无法工作。
  • FR_WRITE_PROTECTED 在存储介质被写保护的情况下,以写模式打开或创建文件对象。
  • FR_DISK_ERR 由于底层磁盘 I/O 接口函数中的一个错误,而导致该函数失败。
  • FR_INT_ERR 由于一个错误的 FAT 结构或一个内部错误,而导致该函数失败。
  • FR_NOT_ENABLED 逻辑驱动器没有工作区。
  • FR_NO_FILESYSTEM 磁盘上没有有效地 FAT 卷。

【f_close】关闭一个打开的文件,无论向文件写入任何数据,文件的缓存信息都将被写回到磁盘。该函数成功后,文件对象不再有效,并且可以被丢弃。如果文件对象是在只读模式下打开的,不需要使用该函数,也能被丢弃。

FRESULT f_close ( 
  FIL* FileObject          /*  文件对象结构的指针  */ 
); 

失败返回值:

  • FR_DISK_ERR、FR_INT_ERR、FR_NOT_READY 与f_open相同。
  • FR_INVALID_OBJECT 文件对象无效。

文件读写

文件读写互为正逆过程,故其输入输出也颇有相似性,故而放在一起介绍

【f_read】从一个文件读取数据

FRESULT f_read ( 
  FIL* FileObject,
  void* Buffer,
  UINT ByteToRead,
  UINT* ByteRead
); 

FRESULT f_write ( 
  FIL* FileObject,
  const void* Buffer,
  UINT ByteToWrite,
  UINT* ByteWritten
); e

参数

  • Buffer 指向存储读取/写入数据的缓冲区的指针。
  • ByteToRead/ByteToWrite 要读取/写入的字节数。
  • ByteRead/ByteWritten 已读取/写入字节数,由于事实上起到返回值的作用,故在调用时需要传入指针。

失败返回值

  • FR_DENIED 由于文件是以非读模式打开的,而导致该函数被拒绝。
  • FR_DISK_ERR 底层磁盘I/O函数错误。
  • FR_INT_ERR 由于一个错误的 FAT 结构或一个内部错误,而导致该函数失败。
  • FR_NOT_READY 驱动器中没有存储介质或任何其他原因。
  • FR_INVALID_OBJECT 文件对象无效。

文件对象中的读/写指针以已读取字节数增加。该函数成功后,应该检查 *ByteRead 来检测文件是否结束。在读操作过程中,一旦 *ByteRead < ByteToRead ,则读/写指针到达了文件结束位置。

指针移动

【f_lseek】移动一个打开的文件对象的文件读/写指针。也可以被用来扩展文件大小 ( 簇预分配 ) 。

FRESULT f_lseek ( 
  FIL* FileObject,         /*  文件对象结构指针  */ 
  DWORD Offset             /*  文件字节偏移  */ 
); 

其中,Offset为相对于文件起始处的字节数。

其失败返回值有4个,分别是FR_DISK_ERR、FR_INT_ERR、FR_NOT_READY、FR_INVALID_OBJECT,与文件读写中的含义相同。

f_lseek 当 FS_MINIMIZE <= 2 时可用。offset 只能被指定为相对于文件起始处的字节数。在写模式中,若offset超出文件大小,则文件将被扩展,这种方法可以快速生成一个大文件。f_lseek 函数成功后,为了确保读/写指针已被正确地移动,必须检查文件对象中的成员 fptr 。如果 fptr 不是所期望的值,则可能文件处于只读模式,或者磁盘已满。

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐