stm32 sd fatfs应用理解

时间:2024-03-13 13:53:08

fatfs:

摘抄自百度百科:

     FatFs [1]  是一个通用的文件系统(FAT/exFAT)模块,用于在小型嵌入式系统中实现FAT文件系统。 FatFs 组件的编写遵循ANSI C(C89),完全分离于磁盘 I/O 层,因此不依赖于硬件平台。它可以嵌入到便宜的微控制器中,如 8051, PIC, AVR, ARM, Z80, RX等等,不需要做任何修改

因为FatFs模块完全与磁盘I/O层分开,因此需要下面的函数来实现底层物理磁盘的读写与获取当前时间。底层磁盘I/O模块并不是FatFs的一部分,并且必须由用户提供。资源文件中也包含有范例驱动。

disk_initialize - Initialize disk drive 初始化磁盘驱动器

disk_status - Get disk status 获取磁盘状态

disk_read - Read sector(s) 读扇区

disk_write - Write sector(s) 写扇区

disk_ioctl - Control device dependent features 设备相关的控制特性

get_fattime - Get current time 获取当前时间

 

stm32 + fatfs + sd

按文件依次从上往下调用:

main.c //
file operation steps:
1.  link the micro SD disk I/O driver
FATFS_LinkDriver(&SD_Driver, SDPath)
2. Register the file system object to the FatFs module
f_mount(&SDFatFs, (TCHAR const*)SDPath, 0)
3. Create a FAT file system (format) on the logical drive
f_mkfs((TCHAR const*)SDPath, FM_ANY, 0, buffer, sizeof(buffer))

4. Create and Open a new text file object with write access
f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE)
5. Write data to the text file
f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten)
6. Close the open text file
f_close(&MyFile);

7. Open the text file object with read access
f_open(&MyFile, "STM32.TXT", FA_READ)
8. Read data from the text file
f_read(&MyFile, rtext, sizeof(rtext), (UINT*)&bytesread)
9. Close the open text file
f_close(&MyFile)

and structure of MyFile is below:

typedef struct {
    _FDID    obj;            /* Object identifier (must be the 1st member to detect invalid object pointer) */
    BYTE    flag;            /* File status flags */
    BYTE    err;            /* Abort flag (error code) */
    FSIZE_t    fptr;            /* File read/write pointer (Zeroed on file open) */
    DWORD    clust;            /* Current cluster of fpter (invalid when fptr is 0) */
    DWORD    sect;            /* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLY
    DWORD    dir_sect;        /* Sector number containing the directory entry */
    BYTE*    dir_ptr;        /* Pointer to the directory entry in the win[] */
#endif
#if _USE_FASTSEEK
    DWORD*    cltbl;            /* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
#if !_FS_TINY
    BYTE    buf[_MAX_SS];    /* File private data read/write window */
#endif
} FIL;

ff.c  //no need to modify
FatFs 提供下面的函数:
f_mount - 注册/注销一个工作区域(Work Area)
f_open - 打开/创建一个文件
f_close - 关闭一个文件
f_read - 读文件
f_write - 写文件
f_lseek - 移动文件读/写指针
f_truncate - 截断文件
f_sync - 冲洗缓冲数据 Flush Cached Data
f_opendir - 打开一个目录
f_readdir - 读取目录条目
f_getfree - 获取空闲簇 Get Free Clusters
f_stat - 获取文件状态
f_mkdir - 创建一个目录
f_unlink - 删除一个文件或目录
f_chmod - 改变属性(Attribute)
f_utime - 改变时间戳(Timestamp)
f_rename - 重命名/移动一个文件或文件夹
f_mkfs - 在驱动器上创建一个文件系统
f_forward - 直接转移文件数据到一个数据流 Forward file data to the stream directly
f_gets - 读一个字符串
f_putc - 写一个字符
f_puts - 写一个字符串
f_printf - 写一个格式化的字符磁盘I/O接口

ff_gen_drv.c// used to register device to fatfs

uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path);
uint8_t FATFS_UnLinkDriver(char *path);
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, BYTE lun);
uint8_t FATFS_UnLinkDriverEx(char *path, BYTE lun);
uint8_t FATFS_GetAttachedDriversNbr(void);

typedef struct
{
  DSTATUS (*disk_initialize) (BYTE);                     /*!< Initialize Disk Drive                     */
  DSTATUS (*disk_status)     (BYTE);                     /*!< Get Disk Status                           */
  DRESULT (*disk_read)       (BYTE, BYTE*, DWORD, UINT);       /*!< Read Sector(s)                            */
  DRESULT (*disk_write)      (BYTE, const BYTE*, DWORD, UINT); /*!< Write Sector(s) when _USE_WRITE = 0       */
  DRESULT (*disk_ioctl)      (BYTE, BYTE, void*);              /*!< I/O control operation when _USE_IOCTL = 1 */

}Diskio_drvTypeDef;

typedef struct
{
  uint8_t                 is_initialized[_VOLUMES];
  const Diskio_drvTypeDef *drv[_VOLUMES];
  uint8_t                 lun[_VOLUMES];
  volatile uint8_t        nbr;

}Disk_drvTypeDef;

diskio.c  // used for fatfs

DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
DWORD get_fattime (void);

sd_diskio.c //

const Diskio_drvTypeDef  SD_Driver =
{
  SD_initialize,
  SD_status,
  SD_read,
  SD_write,
  SD_ioctl,
};
static DSTATUS SD_CheckStatus(BYTE lun)

DSTATUS SD_initialize(BYTE lun)
DSTATUS SD_status(BYTE lun)
DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
DRESULT SD_ioctl(BYTE lun, BYTE cmd, void *buff)


stm32_eval_sd.c //

该文件下为sd对应的板级driver文件。

调用关系图类似下面, 简要理解:

 ff.c文件系统调用下面的diskio.c中的接口函数,

 diskio.c: 类似于适配器驱动接口,通过fatfs_linkdriver 和 fatfs_unlinkdriver 绑定/解绑对应的driver接口(sd_diskio.c中)

 下面可以挂载多个卷, 可以按 0:/ 1:/ 2:/ 指定多个卷的访问路径。

  sd_diskio.c 调用下面的sd driver实现最底层的“文件”操作。


stm32 sd fatfs应用理解