标题:
FatFs源码剖析(2)
[打印本页]
作者:
yuyang911220
时间:
2016-7-22 20:59
标题:
FatFs源码剖析(2)
http://www.openedv.com/posts/list/27427.htm
四、源码注释
本人在不破坏源码逻辑的前提下,对FatFs 0.01源代码进行了中文注释,个别函数重新修改了排版布局,以方便阅读。结合以上示意图即伪代码,相信大家会很快理解FatFs 0.01的核心思想及架构。
[cpp]
view plain
copy
print
?
#include <string.h>
#include "ff.h" /* FatFs declarations */
#include "diskio.h" /* Include file for user provided functions */
FATFS *FatFs; /*
ointer to the file system object */
/*-------------------------------------------------------------------------
Module
rivate Functions
-------------------------------------------------------------------------*/
/*----------------------*/
/* Change Window Offset */
//读取新的扇区内容到临时缓冲区win[],
//如果sector为0,则只需要把win[]的内容写入对应的物理扇区即可
static
BOOL move_window (
DWORD sector /* Sector number to make apperance in the FatFs->win */
) /* Move to zero only writes back dirty window */
{
DWORD wsect; //wsect用于检索FAT备份表的相应扇区
FATFS *fs = FatFs;
wsect = FatFs->winsect;
/*首先检查目标扇区号是否与win[]对应的扇区号相同,如果相同则不进行任何操作。*/
if (wsect != sector) { /* Changed current window */
#ifndef _FS_READONLY
BYTE n;
//首先检测win[]的内容是否做过修改,如果修改过,则需要先将其写入SD卡中。
if (FatFs->dirtyflag) { /* Write back dirty window if needed */
if (disk_write(FatFs->win, wsect, 1) != RES_OK) return FALSE;
//清除修改标记
FatFs->dirtyflag = 0;
/*如果当前操作的是FAT表,那么需要将修改后的FAT表拷贝到对应的FAT备份中*/
if (wsect < (FatFs->fatbase + FatFs->sects_fat)) { /* In FAT area */
for (n = FatFs->n_fats; n >= 2; n--) { /* Refrect the change to all FAT copies */
wsect += FatFs->sects_fat;
if (disk_write(FatFs->win, wsect, 1) != RES_OK) break;
}
}
}
#endif
//然后再读取新的扇区内容到win[]中
if (sector) {
if (disk_read(FatFs->win, sector, 1) != RES_OK) return FALSE;
FatFs->winsect = sector; //更新当前缓冲区的扇区号
}
}
return TRUE;
}
/*--------------------------------------------------------------------------*/
/*
ublic Funciotns */
/*--------------------------------------------------------------------------*/
/*----------------------------------------------------------*/
/* Load File System Information and Initialize FatFs Module */
//本函数做三件事:
// 1.初始化SD卡
// 2.检查文件系统类型,FAT16还是FAT32
// 3.填充FatFs对象,即记录物理磁盘的相关参数
FRESULT f_mountdrv ()
{
BYTE fat;
DWORD sect, fatend;
FATFS *fs = FatFs;
if (!fs) return FR_NOT_ENABLED;
//首先对文件系统对象清空
/* Initialize file system object */
memset(fs, 0, sizeof(FATFS));
//然后初始化SD卡
/* Initialize disk drive */
if (disk_initialize() & STA_NOINIT) return FR_NOT_READY;
//接着收搜索DBR系统引导记录,先检查第0扇区是否就是DBR(无MBR的SD卡),如果是则检查文件系统的类型;
//如果不是则说明第0扇区是MBR,则根据MBR中的信息定位到DBR所在扇区,并检查该文件系统的类型
/* Search FAT partition */
fat = check_fs(sect = 0); /* Check sector 0 as an SFD format */
if (!fat) { /* Not a FAT boot record, it will be an FDISK format */
/* Check a pri-partition listed in top of the partition table */
if (fs->win[0x1C2]) { /* Is the partition existing? */
sect = LD_DWORD(&(fs->win[0x1C6])); /*
artition offset in LBA */
fat = check_fs(sect); /* Check the partition */
}
}
if (!fat) return FR_NO_FILESYSTEM; /* No FAT patition */
//初始化文件系统对象,根据DBR参数信息对Fs成员赋值
/* Initialize file system object */
//文件系统类型:FAT16/FAT32
fs->fs_type = fat; /* FAT type */
//单个FAT表所占的扇区数
fs->sects_fat = /* Sectors per FAT */
(fat == FS_FAT32) ? LD_DWORD(&(fs->win[0x24])): LD_WORD(&(fs->win[0x16]));
//单个簇所占的扇区数
fs->sects_clust = fs->win[0x0D]; /* Sectors per cluster */
//FAT表总数
fs->n_fats = fs->win[0x10]; /* Number of FAT copies */
//FAT表起始扇区(物理扇区)
fs->fatbase = sect + LD_WORD(&(fs->win[0x0E])); /* FAT start sector (physical) */
//根目录项数
fs->n_rootdir = LD_WORD(&(fs->win[0x11])); /* Nmuber of root directory entries */
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0