SD卡与fatfs文件系统(4)

来源:互联网 发布:艾瑞咨询数据 编辑:程序博客网 时间:2024/05/16 07:53

FatFs的初始化和加载的操作是在函数auto_mount中进行的。

[cpp] view plain copy
print?
  1. static  
  2. FRESULT auto_mount (    /* FR_OK(0): successful, !=0: any error occured */  
  3.     const char **path,  /* Pointer to pointer to the path name (drive number) */  
  4.     FATFS **rfs,        /* Pointer to pointer to the found file system object */  
  5.     BYTE chk_wp         /* !=0: Check media write protection for write access */  
  6. )  
  7. {  
  8.     BYTE drv, fmt, *tbl;  
  9.     DSTATUS stat;  
  10.     DWORD bootsect, fatsize, totalsect, maxclust;  
  11.     const char *p = *path;  
  12.     FATFS *fs;  
  13.   
  14.     //分析路径字符串  
  15.     /* Get drive number from the path name */  
  16.     while (*p == ‘ ’) p++;      /* Strip leading spaces */  
  17.     drv = p[0] - ’0’;           /* Is there a drive number? */  
  18.     if (drv <= 9 && p[1] == ‘:’)  
  19.         p += 2;             /* Found a drive number, get and strip it */  
  20.     else  
  21.         drv = 0;            /* No drive number is given, use drive number 0 as default */  
  22.     if (*p == ‘/’) p++;     /* Strip heading slash */  
  23.     *path = p;              /* Return pointer to the path name */  
  24.   
  25.     /* Check if the drive number is valid or not */  
  26.     if (drv >= _DRIVES) return FR_INVALID_DRIVE; /* Is the drive number valid? */  
  27.     *rfs = fs = FatFs[drv];                 /* Returen pointer to the corresponding file system object */  
  28.     if (!fs) return FR_NOT_ENABLED;         /* Is the file system object registered? */  
  29.   
  30.     if (fs->fs_type) {                       /* If the logical drive has been mounted */  
  31.         stat = disk_status(fs->drive);  
  32.         if (!(stat & STA_NOINIT)) {         /* and physical drive is kept initialized (has not been changed), */  
  33. #if !_FS_READONLY  
  34.             if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */  
  35.                 return FR_WRITE_PROTECTED;  
  36. #endif  
  37.             return FR_OK;                   /* The file system object is valid */  
  38.         }  
  39.     }  
  40.   
  41.     /* The logical drive must be re-mounted. Following code attempts to mount the logical drive */  
  42.   
  43.     memset(fs, 0, sizeof(FATFS));       /* Clean-up the file system object */  
  44.     fs->drive = LD2PD(drv);              /* Bind the logical drive and a physical drive */  
  45.     stat = disk_initialize(fs->drive);   /* Initialize low level disk I/O layer */  
  46.     if (stat & STA_NOINIT)              /* Check if the drive is ready */  
  47.         return FR_NOT_READY;  
  48. #if S_MAX_SIZ > 512                      /* Get disk sector size if needed */  
  49.     if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > S_MAX_SIZ)  
  50.         return FR_NO_FILESYSTEM;  
  51. #endif  
  52. #if !_FS_READONLY  
  53.     if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */  
  54.         return FR_WRITE_PROTECTED;  
  55. #endif  
  56.     /* Search FAT partition on the drive */  
  57.     fmt = check_fs(fs, bootsect = 0);   /* Check sector 0 as an SFD format */  读取MBR和分区表  
  58.     if (fmt == 1) {                     /* Not an FAT boot record, it may be patitioned */  
  59.         /* Check a partition listed in top of the partition table */  
  60.         tbl = &fs->win[MBR_Table + LD2PT(drv) * 16]; /* Partition table */  
  61.         if (tbl[4]) {                                   /* Is the partition existing? */  
  62.             bootsect = LD_DWORD(&tbl[8]);               /* Partition offset in LBA */  
  63.             fmt = check_fs(fs, bootsect);               /* Check the partition */  读取分区DBR信息  
  64.         }  
  65.     }  
  66.     if (fmt || LD_WORD(&fs->win[BPB_BytsPerSec]) != SS(fs))  /* No valid FAT patition is found */  
  67.         return FR_NO_FILESYSTEM;  
  68.   
  69.     /* Initialize the file system object */  从读取的数据中初始化fs结构体  
  70.     fatsize = LD_WORD(&fs->win[BPB_FATSz16]);            /* Number of sectors per FAT */  
  71.     if (!fatsize) fatsize = LD_DWORD(&fs->win[BPB_FATSz32]);  
  72.     fs->sects_fat = fatsize;  
  73.     fs->n_fats = fs->win[BPB_NumFATs];                    /* Number of FAT copies */  
  74.     fatsize *= fs->n_fats;                               /* (Number of sectors in FAT area) */  
  75.     fs->fatbase = bootsect + LD_WORD(&fs->win[BPB_RsvdSecCnt]); /* FAT start sector (lba) */  
  76.     fs->csize = fs->win[BPB_SecPerClus];              /* Number of sectors per cluster */  
  77.     fs->n_rootdir = LD_WORD(&fs->win[BPB_RootEntCnt]);    /* Nmuber of root directory entries */  
  78.     totalsect = LD_WORD(&fs->win[BPB_TotSec16]);     /* Number of sectors on the file system */  
  79.     if (!totalsect) totalsect = LD_DWORD(&fs->win[BPB_TotSec32]);  
  80.     fs->max_clust = maxclust = (totalsect                /* max_clust = Last cluster# + 1 */  
  81.         - LD_WORD(&fs->win[BPB_RsvdSecCnt]) - fatsize - fs->n_rootdir / (SS(fs)/32)  
  82.         ) / fs->csize + 2;  
  83.   
  84.     fmt = FS_FAT12;                                     /* Determine the FAT sub type */  
  85.     if (maxclust >= 0xFF7) fmt = FS_FAT16;  
  86.     if (maxclust >= 0xFFF7) fmt = FS_FAT32;  
  87.   
  88.     if (fmt == FS_FAT32)  
  89.         fs->dirbase = LD_DWORD(&fs->win[BPB_RootClus]);   /* Root directory start cluster */  
  90.     else  
  91.         fs->dirbase = fs->fatbase + fatsize;          /* Root directory start sector (lba) */  
  92.     fs->database = fs->fatbase + fatsize + fs->n_rootdir / (SS(fs)/32);    /* Data start sector (lba) */  
  93.   
  94. #if !_FS_READONLY  
  95.     /* Initialize allocation information */  
  96.     fs->free_clust = 0xFFFFFFFF;  
  97. #if _USE_FSINFO  
  98.     /* Get fsinfo if needed */  
  99.     if (fmt == FS_FAT32) {   //读取额外的FAT32信息  
  100.         fs->fsi_sector = bootsect + LD_WORD(&fs->win[BPB_FSInfo]);  
  101.         if (disk_read(fs->drive, fs->win, fs->fsi_sector, 1) == RES_OK &&  
  102.             LD_WORD(&fs->win[BS_55AA]) == 0xAA55 &&  
  103.             LD_DWORD(&fs->win[FSI_LeadSig]) == 0x41615252 &&  
  104.             LD_DWORD(&fs->win[FSI_StrucSig]) == 0x61417272) {  
  105.             fs->last_clust = LD_DWORD(&fs->win[FSI_Nxt_Free]);  
  106.             fs->free_clust = LD_DWORD(&fs->win[FSI_Free_Count]);  
  107.         }  
  108.     }  
  109. #endif  
  110. #endif  
  111.   
  112.     fs->fs_type = fmt;           /* FAT syb-type */  
  113.     fs->id = ++fsid;         /* File system mount ID */  
  114.     return FR_OK;  
  115. }  
staticFRESULT auto_mount (    /* FR_OK(0): successful, !=0: any error occured */    const char **path,  /* Pointer to pointer to the path name (drive number) */    FATFS **rfs,        /* Pointer to pointer to the found file system object */    BYTE chk_wp         /* !=0: Check media write protection for write access */){    BYTE drv, fmt, *tbl;    DSTATUS stat;    DWORD bootsect, fatsize, totalsect, maxclust;    const char *p = *path;    FATFS *fs;    //分析路径字符串    /* Get drive number from the path name */    while (*p == ' ') p++;      /* Strip leading spaces */    drv = p[0] - '0';           /* Is there a drive number? */    if (drv <= 9 && p[1] == ':')        p += 2;             /* Found a drive number, get and strip it */    else        drv = 0;            /* No drive number is given, use drive number 0 as default */    if (*p == '/') p++;     /* Strip heading slash */    *path = p;              /* Return pointer to the path name */    /* Check if the drive number is valid or not */    if (drv >= _DRIVES) return FR_INVALID_DRIVE; /* Is the drive number valid? */    *rfs = fs = FatFs[drv];                 /* Returen pointer to the corresponding file system object */    if (!fs) return FR_NOT_ENABLED;         /* Is the file system object registered? */    if (fs->fs_type) {                       /* If the logical drive has been mounted */        stat = disk_status(fs->drive);        if (!(stat & STA_NOINIT)) {         /* and physical drive is kept initialized (has not been changed), */
#if !_FS_READONLY if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */ return FR_WRITE_PROTECTED;#endif return FR_OK; /* The file system object is valid */ } } /* The logical drive must be re-mounted. Following code attempts to mount the logical drive */ memset(fs, 0, sizeof(FATFS)); /* Clean-up the file system object */ fs->drive = LD2PD(drv); /* Bind the logical drive and a physical drive */ stat = disk_initialize(fs->drive); /* Initialize low level disk I/O layer */ if (stat & STA_NOINIT) /* Check if the drive is ready */ return FR_NOT_READY;#if S_MAX_SIZ > 512 /* Get disk sector size if needed */ if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > S_MAX_SIZ) return FR_NO_FILESYSTEM;#endif#if !_FS_READONLY if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */ return FR_WRITE_PROTECTED;#endif /* Search FAT partition on the drive */ fmt = check_fs(fs, bootsect = 0); /* Check sector 0 as an SFD format */ 读取MBR和分区表 if (fmt == 1) { /* Not an FAT boot record, it may be patitioned */ /* Check a partition listed in top of the partition table */ tbl = &fs->win[MBR_Table + LD2PT(drv) * 16]; /* Partition table */ if (tbl[4]) { /* Is the partition existing? */ bootsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */ fmt = check_fs(fs, bootsect); /* Check the partition */ 读取分区DBR信息 } } if (fmt || LD_WORD(&fs->win[BPB_BytsPerSec]) != SS(fs)) /* No valid FAT patition is found */ return FR_NO_FILESYSTEM; /* Initialize the file system object */ 从读取的数据中初始化fs结构体 fatsize = LD_WORD(&fs->win[BPB_FATSz16]); /* Number of sectors per FAT */ if (!fatsize) fatsize = LD_DWORD(&fs->win[BPB_FATSz32]); fs->sects_fat = fatsize; fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FAT copies */ fatsize *= fs->n_fats; /* (Number of sectors in FAT area) */ fs->fatbase = bootsect + LD_WORD(&fs->win[BPB_RsvdSecCnt]); /* FAT start sector (lba) */ fs->csize = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ fs->n_rootdir = LD_WORD(&fs->win[BPB_RootEntCnt]); /* Nmuber of root directory entries */ totalsect = LD_WORD(&fs->win[BPB_TotSec16]); /* Number of sectors on the file system */ if (!totalsect) totalsect = LD_DWORD(&fs->win[BPB_TotSec32]); fs->max_clust = maxclust = (totalsect /* max_clust = Last cluster# + 1 */ - LD_WORD(&fs->win[BPB_RsvdSecCnt]) - fatsize - fs->n_rootdir / (SS(fs)/32) ) / fs->csize + 2; fmt = FS_FAT12; /* Determine the FAT sub type */ if (maxclust >= 0xFF7) fmt = FS_FAT16; if (maxclust >= 0xFFF7) fmt = FS_FAT32; if (fmt == FS_FAT32) fs->dirbase = LD_DWORD(&fs->win[BPB_RootClus]); /* Root directory start cluster */ else fs->dirbase = fs->fatbase + fatsize; /* Root directory start sector (lba) */ fs->database = fs->fatbase + fatsize + fs->n_rootdir / (SS(fs)/32); /* Data start sector (lba) */#if !_FS_READONLY /* Initialize allocation information */ fs->free_clust = 0xFFFFFFFF;#if _USE_FSINFO /* Get fsinfo if needed */ if (fmt == FS_FAT32) { //读取额外的FAT32信息 fs->fsi_sector = bootsect + LD_WORD(&fs->win[BPB_FSInfo]); if (disk_read(fs->drive, fs->win, fs->fsi_sector, 1) == RES_OK && LD_WORD(&fs->win[BS_55AA]) == 0xAA55 && LD_DWORD(&fs->win[FSI_LeadSig]) == 0x41615252 && LD_DWORD(&fs->win[FSI_StrucSig]) == 0x61417272) { fs->last_clust = LD_DWORD(&fs->win[FSI_Nxt_Free]); fs->free_clust = LD_DWORD(&fs->win[FSI_Free_Count]); } }#endif#endif fs->fs_type = fmt; /* FAT syb-type */ fs->id = ++fsid; /* File system mount ID */ return FR_OK;}

(1)disk_status(fs->drive);获取设备的状态,判断设备是否存在;

(2)disk_initialize(fs->drive);它对接口做初始化;

(3)check_fs(fs, bootsect = 0);读取MBR和分区表,判断分区是否是FAT或FAT32;


原创粉丝点击