目录

函数参数:

源码分析:

1)解析逻辑驱动号

2)初始化FatFs结构

3)挂载驱动

主引导记录MBR

未完待续...


先来看一张在fatfs截取的一张图,文件系统就是中间这个带颜色一层,它贯通连接着底层硬件和上层软。上层软件不用太关系你底层使用的flash、磁盘、u盘、sd卡、、、,底层呢也不需要上层写了什么文件,读了什么文件,只需要把数据在硬件上大小烙印就可以了。

挂载文件系统使用的接口函数如下,接下来就分析一下函数的基本流程。

/*-----------------------------------------------------------------------*/
/* Mount/Unmount a Logical Drive                                         */
/*-----------------------------------------------------------------------*/FRESULT f_mount (FATFS* fs,          /* Pointer to the filesystem object to be registered (NULL:unmount)*/const TCHAR* path, /* Logical drive number to be mounted/unmounted */BYTE opt          /* Mount option: 0=Do not mount (delayed mount), 1=Mount immediately */
)

函数参数:

1)fs:FATFS的指针,是文件系统的主要结构,包含了文件系统类型、状态、编号、大小等;

2)path:char型指针,是逻辑驱动号,这个号在底层驱动里,也是上层唯一需要知道的底层的东西,格式为"0:",一个驱动号加一个冒号":",驱动号在底层接口中init,read,write等函数中的pdrv物理驱动号;

3)opt,0是不挂载或延时挂载,1是立即挂载,在代码的最后可以看到,如下代码;

 if (opt == 0) return FR_OK;           /* Do not mount now, it will be mounted later */res = mount_volume(&path, &fs, 0); /* Force mounted the volume */LEAVE_FF(fs, res);

源码分析:

源码主要有三布

1)解析逻辑驱动号

int vol;
const TCHAR *rp = path;/* Get logical drive number */
vol = get_ldnumber(&rp);

把输入的驱动号字符串解析成一个int逻辑号,这其中涉及到两个配置文件中的宏定义,FF_VOLUMES是支持挂载的逻辑驱动个数,FF_STR_VOLUME_ID是解析驱动号的格式。

#define FF_VOLUMES       1
/* Number of volumes (logical drives) to be used. (1-10) */#define FF_STR_VOLUME_ID 0/* 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:
/
*///--------------------------------------------------------------------//...
#if FF_STR_VOLUME_ID == 1 /* Arbitrary string is enabled */
...
#if FF_STR_VOLUME_ID == 2     /* Unix style volume ID is enabled */
...

2)初始化FatFs结构

fatfs有一个全局的文件系统结构体指针,这里基本就是清里存在的fs_type=0,这个在后面也会用到。

static FATFS* FatFs[FF_VOLUMES]; /* Pointer to the filesystem objects (logical drives) *///----------------------------------//cfs = FatFs[vol];                    /* Pointer to fs object */if(cfs){
...
}if(fs){
...
}

3)挂载驱动

挂载驱动就用了一个下面一个函数。

res = mount_volume(&path, &fs, 0);  /* Force mounted the volume */
LEAVE_FF(fs, res);

下面就来分析一下这个主要又重要的函数

/*-----------------------------------------------------------------------*/
/* Determine logical drive number and mount the volume if needed         */
/*-----------------------------------------------------------------------*/static FRESULT mount_volume (    /* FR_OK(0): successful, !=0: an error occurred */const TCHAR** path,          /* Pointer to pointer to the path name (drive number) */FATFS** rfs,                /* Pointer to pointer to the found filesystem object */BYTE mode                    /* !=0: Check write protection for write access */
)

​​​​​​​​​​​​​​

通过流程分析我们可以看到最后使用move_window()这个函数调用了disk_read()读取了0扇区的数据存放在FATFS结构图的fs->win[FF_MAX_SS]这个成员数组中。

#define FF_MAX_SS        512BYTE   win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */

static FRESULT move_window (    /* Returns FR_OK or FR_DISK_ERR */FATFS* fs,        /* Filesystem object */LBA_t sect       /* Sector LBA to make appearance in the fs->win[] */
)
{FRESULT res = FR_OK;if (sect != fs->winsect) {    /* Window offset changed? */
#if !FF_FS_READONLYres = sync_window(fs);      /* Flush the window */
#endifif (res == FR_OK) {         /* Fill sector window with new data */if (disk_read(fs->pdrv, fs->win, sect, 1) != RES_OK) {sect = (LBA_t)0 - 1;    /* Invalidate window if read data is not valid */res = FR_DISK_ERR;}fs->winsect = sect;}}return res;
}

既然读取了0号扇区,那么这个扇区中到底放了什么呢。

主引导记录MBR

没错这就是MBR,主引导记录(MBR,Master Boot Record)是硬盘磁盘等的第一个扇区,即C/H/S地址的0柱面0磁头1扇区,也叫做MBR扇区。

关于fatfs的主引导扇区这里就不介绍了,分享两篇博文可以看一下

1)  FAT32文件系统结构详解

2)  FatFs文件系统结构分析

主引导扇区解析完成后,会有下面代码,挂载文件系统基本就挂载完成了。

/* Determine the FAT sub type */
sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE);   /* RSV + FAT + DIR */
if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */
nclst = (tsect - sysect) / fs->csize;           /* Number of clusters */
if (nclst == 0) return FR_NO_FILESYSTEM;      /* (Invalid volume size) */
fmt = 0;
if (nclst <= MAX_FAT32) fmt = FS_FAT32;
if (nclst <= MAX_FAT16) fmt = FS_FAT16;
if (nclst <= MAX_FAT12) fmt = FS_FAT12;
if (fmt == 0) return FR_NO_FILESYSTEM;
...
...
fs->fs_type = (BYTE)fmt;/* FAT sub-type */
fs->id = ++Fsid;      /* Volume mount ID */

有感兴趣的可以在去研读一下详细源码这里只给出了函数的基本流程。


未完待续...

Fatfs文件系统挂载相关推荐

  1. 关于FATFS文件系统挂载多个磁盘

    关于FATFS文件系统挂载多个磁盘以及SPI FLASH的应用问题!

  2. USB2.0挂载FatFs文件系统

    一.前期准备 1.协议栈 USB协议栈 FatFs文件系统协议栈 2.物理芯片 W25Q64的8M大小的flash芯片 二.描述 文件系统fatfs.USB协议栈.物理层flash存储芯片关系. 1. ...

  3. STM32挂载SD卡基于Fatfs文件系统读取文件信息

    STM32挂载SD卡基于Fatfs文件系统读取文件信息

  4. RT-Thread--外部 flash 挂载 fatfs 文件系统

    外部 flash 挂载 fatfs 文件系统 /** Copyright (c) 2006-2018, RT-Thread Development Team** SPDX-License-Identi ...

  5. 基于SD卡的FatFs文件系统(FatFs移植到STM32)

    平台:STM32ZET6(核心板)+ST-LINK/V2+SD卡+USB串口线 工程介绍:主要文件在USER组中,bsp_sdio_sdcard.c,bsp_sdio_sdcard.h和main.c, ...

  6. STM32F407ZGT6 fatfs出现挂载成功,但是文件读写失败的原因

    使用正点原子的板子f407,使用野火代码参考博客 2021-07-25 野火板子25MHz晶振改为正点原子8MH晶振_Car12-CSDN博客 参考源码 修复了野火的bug,使用cubemx初始化代码 ...

  7. STM32CubeMX学习笔记(25)——FatFs文件系统使用(操作SPI Flash)

    一.FatFs简介 FatFs 是面向小型嵌入式系统的一种通用的 FAT 文件系统.它完全是由 ANSI C 语言编写并且完全独立于底层的 I/O 介质.因此它可以很容易地不加修改地移植到其他的处理器 ...

  8. 2021-08-11 TM32F103 Buffer FatFs 文件系统移植

    FatFs 本文展示了STM32 FatFs文件系统移植 内容涉及 : FatFs 文件系统移植 SPI函数移植过程 SPI字节数据模拟输出独写 缓存读写 USART串口的识别 IO口输入输出 按键的 ...

  9. STM32CubeMX系列09——SDIO(SD卡读写、SD卡移植FATFS文件系统)

    文章目录 1. 准备工作 1.1. 简单扫盲 1.1.1. SD卡 1.1.2. TF卡 1.1.3. SDIO接口 1.2. 所用硬件及原理图 2. 创建工程 2.1. 选择主控 2.2. 系统配置 ...

最新文章

  1. textarea输入框限制字数(JS)
  2. python输入函数后无法运行_python - 如何在函数运行期间忽略所有用户输入?_python_酷徒编程知识库...
  3. EXPORT_SYMBOL的作用是什么
  4. java pdf添加图片_java实现在pdf模板的指定位置插入图片
  5. 12.04 深圳站 | Serverless Developer Meetup 开放报名啦
  6. TensorFlow2快速模型构建及tensorboard初体验
  7. discuz邮件设置PHP,Discuz!6.0—如何配置发送邮件的参数
  8. SpringBoot集成Mybatis用法笔记
  9. java volatile 原子性_Java中volatile不能保证原子性的证明
  10. CVPR 2020 oral:亮风台提出完全可训练的图匹配方法
  11. 随想录(以师带徒的原则)
  12. Hadoop云计算大数据书籍分享
  13. 图像处理程序,在状态栏显示图像尺寸
  14. 手机WIFI的上行下行速度不同
  15. 对于通用计算机而言,《计算机操作系统》第二次作业
  16. Qt调用ffmpeg录制屏幕
  17. 小白也能看懂的手机配置攻略
  18. mysql 别名排序没效果_除了会排序,你对ORDER BY的用法可能一无所知!
  19. Windows Server 2008密码破解
  20. js判断早上好,上午好,下午好,傍晚好,晚上好

热门文章

  1. 为什么同一张图png反而比jpg小?
  2. Math.floor 和 Math.ceil
  3. 初学者需了解的AutoCAD三大基础功能,具体有哪些?
  4. 游戏发烧型计算机配置方案,游戏多开无压力 七千元八核独显发烧游戏电脑配置推荐...
  5. 一个人的号码——霜雪盈天
  6. tomcat是干嘛的
  7. 常见web安全漏洞介绍
  8. 哈尔滨工业大学与山东大学相比考研计算机科学与技术哪个好考,计算机考研,我该选浙大还是哈工大?...
  9. 螺栓、螺钉、螺柱的材料及机械性能
  10. 高校考研真题和答案下载链接合集