FATFS:一个兼容windows的嵌入式文件系统API使用详解

FATFS:一个兼容windows的嵌入式文件系统API使用详解



FATFS官网:http://elm-chan.org/fsw/ff/00index_e.html

本篇博客不讲解移植教程,只讲解常用API如何使用。


(1)API分类

文件操作类:

目录操作类:

文件和目录管理:

文件系统管理:


(2)常用API说明

2.1 挂载文件系统与解除挂载

/**
 * 挂载文件系统
 * @param  fs   文件系统句柄
 * @param  path 逻辑驱动器号码
 * @param  opt  初始化属性,=0:在第一次访问文件系统的时候挂载,=1:立刻挂载
 * @return      成功返回FR_OK,失败返回其他值,具体看FRESULT定义
 *
 * FATFS fs;
 * 示例:f_mount(&fs, "0:/", 1);
 */
FRESULT f_mount(FATFS* fs, const TCHAR* path, BYTE opt);


/**
 * 解除挂载
 * @param  path 逻辑驱动器号码
 * @return      成功返回FR_OK,失败返回其他值,具体看FRESULT定义
 *
 * 示例:f_unmount("0:/");
 */
FRESULT f_unmount (const TCHAR* path);

注意:旧版本的FATFS没有f_unmount函数,取消挂载是使用f_mount函数:

f_mount(NULL, "0:/", 1);
2.2 文件操作
2.2.1 文件的打开和关闭
/**
 * 打开文件
 * @param  fp   文件句柄
 * @param  path 文件路径
 * @param  mode 打开模式
 * @return      成功返回FR_OK,失败返回其他值,具体看FRESULT定义
 *
 * FIL fp;
 * 示例:f_open(&fp, "0:/helloworld.txt", FA_CREATE_ALWAYS | FA_WRITE | FA_READ)
 */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode);

/**
 * 关闭文件
 * @param  fp 文件句柄
 * @return    成功返回FR_OK,失败返回其他值,具体看FRESULT定义
 */
FRESULT f_close (FIL* fp);

mode参数说明:

  • FA_READ:只读
  • FA_WRITE:只写
  • FA_OPEN_EXISTING:打开已经存在的文件,如果文件不存在则打开失败
  • FA_CREATE_NEW:创建文件,如果文件已存在则创建失败
  • FA_CREATE_ALWAYS:始终创建文件,如果文件已存在则会清空文件
  • FA_OPEN_ALWAYS:始终打开文件,如果文件不存在则创建
  • FA_OPEN_APPEND:以追加的形式打开文件

以上参数可以组合使用。

2.2.2 读写文件和获取文件大小

读文件:

/**
 * 从文件中读数据
 * @param  fp   文件句柄
 * @param  buff 存放读取到的数据
 * @param  btr  要读取的字节数
 * @param  br   实际读取到的字节数
 * @return      成功返回FR_OK,失败返回其他值,具体看FRESULT定义
 *
 * 示例:
 * FIL fp;
 * char buf[128];
 * UINT nread = 0;
 * f_read(&fp, buf, sizeof(buf), &nread);
 */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br);

写文件:

/**
 * 向文件写数据
 * @param  fp   文件句柄
 * @param  buff 待写入的数据
 * @param  btw  待写入的数据字节数
 * @param  bw   实际写入的字节数
 * @return      成功返回FR_OK,失败返回其他值,具体看FRESULT定义
 *
 * 示例:
 * FIL fp;
 * const char* str = "helloworld";
 * UINT nwrite = 0;
 * f_write(&fp, str, strlen(buf), &nwrite);
 */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw);

获取打开的文件大小:

/**
 * 获取文件大小
 * @param  fp 文件句柄
 * @return    成功返回FR_OK,失败返回其他值,具体看FRESULT定义
 */
FSIZE_t f_size (FIL* fp);

注意:f_size只能用于文件被打开后,它其实是一个宏定义:

#define f_size(fp) ((fp)->obj.objsize)

(3)FATFS二次接口

//
/**
 * @file  fops.c
 * @autor lakun@qq.com
 * @data  2020/3/5
 */
//
#include "fops.h"
#include <stdio.h>

FILINFO USERFileInfo;	//文件信息
DIR USERDir;  			//目录

void exf_getfree(SDCard_InfoTypedef *sdinfo)
{
    FATFS *fs = NULL;
    DWORD fre_clust = 0;
    if (sdinfo != NULL)
    {
        memset(sdinfo, 0X00, sizeof(SDCard_InfoTypedef));
        if (f_getfree(USERPath, &fre_clust, &fs) == FR_OK)
        {
            sdinfo->tot_sect = (fs->n_fatent - 2) * fs->csize;		// 总扇区数
            sdinfo->fre_sect = fre_clust * fs->csize;				// 空闲扇区数
            sdinfo->tol_capacity = sdinfo->tot_sect >> 11;		// 转为MB
            sdinfo->fre_capacity = sdinfo->fre_sect >> 11;		// 转为MB
        }
    }
}

FRESULT exf_mount(void)
{
#if _USE_LFN
    static char LFNAME[_MAX_LFN * 2 + 1];  /* 一个汉字占用2个字节 */
    USERFileInfo.lfsize = sizeof(LFNAME);
    USERFileInfo.lfname = LFNAME;
#endif
    FATFS_LinkDriver(&USER_Driver, USERPath);
    return f_mount(&USERFatFS, USERPath, 1);
}

FRESULT exf_format(
    BYTE sfd,			/* Partitioning rule 0:FDISK, 1:SFD */
    UINT au				/* Size of allocation unit in unit of byte or sector */
)
{
    return f_mkfs(USERPath, sfd, au);
}

FRESULT exf_unmount(void)
{
    FATFS_UnLinkDriver(USERPath);
    return f_mount(NULL, USERPath, 1);
}

FRESULT exf_open(const void *filename, BYTE mode)
{
    return f_open(&USERFile, filename, mode);
}

uint32_t exf_get_open_file_size(void)
{
    return USERFile.fsize;
}

int exf_write(const void *buf, uint32_t len)
{
    FRESULT res = FR_OK;
    UINT btw = 0;
    res = f_write(&USERFile, (uint8_t*) buf, len, &btw);
    if(res != FR_OK)
    {
        return -1;
    }
    return (int)btw;
}

int exf_read(void *buf, uint32_t len)
{
    FRESULT res = FR_OK;
    UINT btr = 0;
    res = f_read(&USERFile, buf, len, &btr);
    if(res != FR_OK)
    {
        return -1;
    }
    return (int)btr;
}

bool exf_gets(void* buf, uint32_t len)
{
    return f_gets((TCHAR *)buf, len, &USERFile) == NULL ? false : true;
}

FRESULT exf_scan_files (char* path)
{
    FRESULT res;
    DIR dir;                //目录信息,注意这个结构很大
	FILINFO USERFileInfo;	//文件信息,注意这个结构很大
    UINT i;
    char *fn;   /* This function is assuming non-Unicode cfg. */
    res = f_opendir(&dir, path);                       /* Open the directory */
    if (res == FR_OK)
    {
        for (;;)
        {
            res = f_readdir(&dir, &USERFileInfo);                   /* Read a directory item */
            if (res != FR_OK || USERFileInfo.fname[0] == 0) break;  /* Break on error or end of dir */
			//if (USERFileInfo.fname[0] == '.') continue;             /* 忽略上级目录 */
            if (USERFileInfo.fattrib & AM_DIR)                      /* It is a directory */
            {
                i = strlen(path);
#if _USE_LFN
                fn = *USERFileInfo.lfname ? USERFileInfo.lfname : USERFileInfo.fname;
#else
                fn = USERFileInfo.fname;
#endif
                sprintf(&path[i], "/%s", fn);
                res = exf_scan_files(path);                    /* Enter the directory */
                if (res != FR_OK) break;
                path[i] = 0;
            }
            else                                           /* It is a file. */
            {
#if _USE_LFN
                fn = *USERFileInfo.lfname ? USERFileInfo.lfname : USERFileInfo.fname;
#else
                fn = USERFileInfo.fname;
#endif
                printf("%s/%s\n", path, fn);
            }
        }
        f_closedir(&dir);
    }

    return res;
}

bool exf_lseek(DWORD offset)
{
    if(f_lseek(&USERFile, offset) == FR_OK)
    {
        return true;
    }
    return false;
}

void exf_close(void)
{
    f_close(&USERFile);
}


//
/**
 * @file  fops.h
 * @autor lakun@qq.com
 * @data  2020/3/5
 * @note  FatFs操作SD卡API
 */
//

#ifndef __FOPS_H
#define __FOPS_H

#include "main.h"
#include "fatfs.h"
#include <string.h>
#include <stdbool.h>

typedef struct
{
    DWORD fre_sect;        /* 空闲扇区数 */
    DWORD tot_sect;        /* 总扇区数 */
    DWORD fre_capacity;    /* 空闲容量,单位MB */
    DWORD tol_capacity;    /* 总容量,单位MB */
} SDCard_InfoTypedef;

void exf_getfree(SDCard_InfoTypedef* sdinfo);
FRESULT exf_mount(void);
FRESULT exf_unmount(void);
FRESULT exf_open(const void* filename, BYTE mode);
int exf_write(const void *buf, uint32_t len);
int exf_read(void* buf, uint32_t len);
bool exf_gets(void* buf, uint32_t len);
bool exf_lseek(DWORD offset);
void exf_close(void);
FRESULT exf_format(BYTE sfd, UINT au);
uint32_t exf_get_open_file_size(void);
FRESULT exf_scan_files (char* path);

extern FILINFO USERFileInfo;	//文件信息
extern DIR USERDir;  			//目录

#endif

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用FatFs库读取一个bin文件,你需要按照以下步骤进行操作: 1. 首先,确保你已经集成了FatFs库到你的项目中。你可以从FatFs的官方网站(http://elm-chan.org/fsw/ff/00index_e.html)下载最新版本的库,并将其添加到你的项目中。 2. 在你的代码中,包含FatFs库的头文件: ```c #include "ff.h" ``` 3. 初始化FatFs库和磁盘驱动器。你需要选择正确的驱动器号和挂载路径。以下是一个示例: ```c FATFS fs; FRESULT res; // 初始化FatFs库 res = f_mount(&fs, "0:", 0); if (res != FR_OK) { // 处理挂载错误 } ``` 4. 打开bin文件并读取内容。你可以使用`f_open`函数打开文件,并使用`f_read`函数读取文件内容。以下是一个示例: ```c FIL file; UINT br; // 打开bin文件 res = f_open(&file, "0:test.bin", FA_READ); if (res != FR_OK) { // 处理文件打开错误 } // 读取文件内容 uint8_t buffer[512]; // 设置一个缓冲区来存储读取到的数据 res = f_read(&file, buffer, sizeof(buffer), &br); if (res != FR_OK) { // 处理读取错误 } // 处理读取到的数据(buffer中的内容) ``` 5. 关闭文件并卸载FatFs库。在完成文件读取后,使用`f_close`函数关闭文件,并使用`f_mount`函数卸载FatFs库。以下是一个示例: ```c // 关闭文件 res = f_close(&file); if (res != FR_OK) { // 处理文件关闭错误 } // 卸载FatFs库 res = f_mount(NULL, "0:", 0); if (res != FR_OK) { // 处理卸载错误 } ``` 请根据你的具体需求修改上述代码,并确保在使用FatFs库时遵循其文档中的要求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

觉皇嵌入式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值