zoukankan      html  css  js  c++  java
  • FATFS 初学之 f_mkfs

      1 /*-----------------------------------------------------------------------*/
      2 /* Create File System on the Drive                                       */
      3 /*-----------------------------------------------------------------------*/
      4 
      5 FRESULT f_mkfs (
      6     BYTE drv,        /* Logical drive number */
      7     BYTE sfd,        /* Partitioning rule 0:FDISK, 1:SFD */
      8     UINT au            /* Allocation unit size [bytes] */
      9 )
     10 {
     11     static const WORD vst[] = { 1024,   512,  256,  128,   64,    32,   16,    8,    4,    2,   0};
     12     static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512};
     13     BYTE fmt, md, sys, *tbl, pdrv, part;
     14     DWORD n_clst, vs, n, wsect;
     15     UINT i;
     16     DWORD b_vol, b_fat, b_dir, b_data;    /* LBA */
     17     DWORD n_vol, n_rsv, n_fat, n_dir;    /* Size */
     18     FATFS *fs;
     19     DSTATUS stat;
     20 
     21 
     22     /* Check mounted drive and clear work area */
     23     if (drv >= _VOLUMES) return FR_INVALID_DRIVE;
     24     if (sfd > 1) return FR_INVALID_PARAMETER;
     25     if (au & (au - 1)) return FR_INVALID_PARAMETER;
     26     fs = FatFs[drv];
     27     if (!fs) return FR_NOT_ENABLED;
     28     fs->fs_type = 0;
     29     pdrv = LD2PD(drv);    /* Physical drive */
     30     part = LD2PT(drv);    /* Partition (0:auto detect, 1-4:get from partition table)*/
     31 
     32     /* Get disk statics */
     33     stat = disk_initialize(pdrv);
     34     if (stat & STA_NOINIT) return FR_NOT_READY;
     35     if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
     36 #if _MAX_SS != 512                    /* Get disk sector size */
     37     if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS)
     38         return FR_DISK_ERR;
     39 #endif
     40     if (_MULTI_PARTITION && part) {
     41         /* Get partition information from partition table in the MBR */
     42         if (disk_read(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR;
     43         if (LD_WORD(fs->win+BS_55AA) != 0xAA55) return FR_MKFS_ABORTED;
     44         tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
     45         if (!tbl[4]) return FR_MKFS_ABORTED;    /* No partition? */
     46         b_vol = LD_DWORD(tbl+8);    /* Volume start sector */
     47         n_vol = LD_DWORD(tbl+12);    /* Volume size */
     48     } else {
     49         /* Create a partition in this function */
     50         if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128)
     51             return FR_DISK_ERR;
     52         b_vol = (sfd) ? 0 : 63;        /* Volume start sector */
     53         n_vol -= b_vol;                /* Volume size */
     54     }
     55 
     56     if (!au) {                /* AU auto selection */
     57         vs = n_vol / (2000 / (SS(fs) / 512));
     58         for (i = 0; vs < vst[i]; i++) ;
     59         au = cst[i];
     60     }
     61     au /= SS(fs);        /* Number of sectors per cluster */
     62     if (au == 0) au = 1;
     63     if (au > 128) au = 128;
     64 
     65     /* Pre-compute number of clusters and FAT syb-type */
     66     n_clst = n_vol / au;
     67     fmt = FS_FAT12;
     68     if (n_clst >= MIN_FAT16) fmt = FS_FAT16;
     69     if (n_clst >= MIN_FAT32) fmt = FS_FAT32;
     70 
     71     /* Determine offset and size of FAT structure */
     72     if (fmt == FS_FAT32) {
     73         n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs);
     74         n_rsv = 32;
     75         n_dir = 0;
     76     } else {
     77         n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4;
     78         n_fat = (n_fat + SS(fs) - 1) / SS(fs);
     79         n_rsv = 1;
     80         n_dir = (DWORD)N_ROOTDIR * SZ_DIR / SS(fs);
     81     }
     82     b_fat = b_vol + n_rsv;                /* FAT area start sector */
     83     b_dir = b_fat + n_fat * N_FATS;        /* Directory area start sector */
     84     b_data = b_dir + n_dir;                /* Data area start sector */
     85     if (n_vol < b_data + au - b_vol) return FR_MKFS_ABORTED;    /* Too small volume */
     86 
     87     /* Align data start sector to erase block boundary (for flash memory media) */
     88     if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &n) != RES_OK || !n || n > 32768) n = 1;
     89     n = (b_data + n - 1) & ~(n - 1);    /* Next nearest erase block from current data start */
     90     n = (n - b_data) / N_FATS;
     91     if (fmt == FS_FAT32) {        /* FAT32: Move FAT offset */
     92         n_rsv += n;
     93         b_fat += n;
     94     } else {                    /* FAT12/16: Expand FAT size */
     95         n_fat += n;
     96     }
     97 
     98     /* Determine number of clusters and final check of validity of the FAT sub-type */
     99     n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au;
    100     if (   (fmt == FS_FAT16 && n_clst < MIN_FAT16)
    101         || (fmt == FS_FAT32 && n_clst < MIN_FAT32))
    102         return FR_MKFS_ABORTED;
    103 
    104     switch (fmt) {    /* Determine system ID for partition table */
    105     case FS_FAT12:    sys = 0x01; break;
    106     case FS_FAT16:    sys = (n_vol < 0x10000) ? 0x04 : 0x06; break;
    107     default:         sys = 0x0C;
    108     }
    109 
    110     if (_MULTI_PARTITION && part) {
    111         /* Update system ID in the partition table */
    112         tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
    113         tbl[4] = sys;
    114         if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR;
    115         md = 0xF8;
    116     } else {
    117         if (sfd) {    /* No patition table (SFD) */
    118             md = 0xF0;
    119         } else {    /* Create partition table (FDISK) */
    120             mem_set(fs->win, 0, SS(fs));
    121             tbl = fs->win+MBR_Table;    /* Create partiton table for single partition in the drive */
    122             tbl[1] = 1;                        /* Partition start head */
    123             tbl[2] = 1;                        /* Partition start sector */
    124             tbl[3] = 0;                        /* Partition start cylinder */
    125             tbl[4] = sys;                    /* System type */
    126             tbl[5] = 254;                    /* Partition end head */
    127             n = (b_vol + n_vol) / 63 / 255;
    128             tbl[6] = (BYTE)((n >> 2) | 63);    /* Partiiton end sector */
    129             tbl[7] = (BYTE)n;                /* End cylinder */
    130             ST_DWORD(tbl+8, 63);            /* Partition start in LBA */
    131             ST_DWORD(tbl+12, n_vol);        /* Partition size in LBA */
    132             ST_WORD(fs->win+BS_55AA, 0xAA55);    /* MBR signature */
    133             if (disk_write(pdrv, fs->win, 0, 1) != RES_OK)    /* Write it to the MBR sector */
    134                 return FR_DISK_ERR;
    135             md = 0xF8;
    136         }
    137     }
    138 
    139     /* Create BPB in the VBR */
    140     tbl = fs->win;                            /* Clear sector */
    141     mem_set(tbl, 0, SS(fs));
    142     mem_cpy(tbl, "xEBxFEx90" "MSDOS5.0", 11);/* Boot jump code, OEM name */
    143     i = SS(fs);                                /* Sector size */
    144     ST_WORD(tbl+BPB_BytsPerSec, i);
    145     tbl[BPB_SecPerClus] = (BYTE)au;            /* Sectors per cluster */
    146     ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv);        /* Reserved sectors */
    147     tbl[BPB_NumFATs] = N_FATS;                /* Number of FATs */
    148     i = (fmt == FS_FAT32) ? 0 : N_ROOTDIR;    /* Number of rootdir entries */
    149     ST_WORD(tbl+BPB_RootEntCnt, i);
    150     if (n_vol < 0x10000) {                    /* Number of total sectors */
    151         ST_WORD(tbl+BPB_TotSec16, n_vol);
    152     } else {
    153         ST_DWORD(tbl+BPB_TotSec32, n_vol);
    154     }
    155     tbl[BPB_Media] = md;                    /* Media descriptor */
    156     ST_WORD(tbl+BPB_SecPerTrk, 63);            /* Number of sectors per track */
    157     ST_WORD(tbl+BPB_NumHeads, 255);            /* Number of heads */
    158     ST_DWORD(tbl+BPB_HiddSec, b_vol);        /* Hidden sectors */
    159     n = get_fattime();                        /* Use current time as VSN */
    160     if (fmt == FS_FAT32) {
    161         ST_DWORD(tbl+BS_VolID32, n);        /* VSN */
    162         ST_DWORD(tbl+BPB_FATSz32, n_fat);    /* Number of sectors per FAT */
    163         ST_DWORD(tbl+BPB_RootClus, 2);        /* Root directory start cluster (2) */
    164         ST_WORD(tbl+BPB_FSInfo, 1);            /* FSInfo record offset (VBR+1) */
    165         ST_WORD(tbl+BPB_BkBootSec, 6);        /* Backup boot record offset (VBR+6) */
    166         tbl[BS_DrvNum32] = 0x80;            /* Drive number */
    167         tbl[BS_BootSig32] = 0x29;            /* Extended boot signature */
    168         mem_cpy(tbl+BS_VolLab32, "NO NAME    " "FAT32   ", 19);    /* Volume label, FAT signature */
    169     } else {
    170         ST_DWORD(tbl+BS_VolID, n);            /* VSN */
    171         ST_WORD(tbl+BPB_FATSz16, n_fat);    /* Number of sectors per FAT */
    172         tbl[BS_DrvNum] = 0x80;                /* Drive number */
    173         tbl[BS_BootSig] = 0x29;                /* Extended boot signature */
    174         mem_cpy(tbl+BS_VolLab, "NO NAME    " "FAT     ", 19);    /* Volume label, FAT signature */
    175     }
    176     ST_WORD(tbl+BS_55AA, 0xAA55);            /* Signature (Offset is fixed here regardless of sector size) */
    177     if (disk_write(pdrv, tbl, b_vol, 1) != RES_OK)    /* Write it to the VBR sector */
    178         return FR_DISK_ERR;
    179     if (fmt == FS_FAT32)                            /* Write backup VBR if needed (VBR+6) */
    180         disk_write(pdrv, tbl, b_vol + 6, 1);
    181 
    182     /* Initialize FAT area */
    183     wsect = b_fat;
    184     for (i = 0; i < N_FATS; i++) {        /* Initialize each FAT copy */
    185         mem_set(tbl, 0, SS(fs));            /* 1st sector of the FAT  */
    186         n = md;                                /* Media descriptor byte */
    187         if (fmt != FS_FAT32) {
    188             n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00;
    189             ST_DWORD(tbl+0, n);                /* Reserve cluster #0-1 (FAT12/16) */
    190         } else {
    191             n |= 0xFFFFFF00;
    192             ST_DWORD(tbl+0, n);                /* Reserve cluster #0-1 (FAT32) */
    193             ST_DWORD(tbl+4, 0xFFFFFFFF);
    194             ST_DWORD(tbl+8, 0x0FFFFFFF);    /* Reserve cluster #2 for root dir */
    195         }
    196         if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
    197             return FR_DISK_ERR;
    198         mem_set(tbl, 0, SS(fs));            /* Fill following FAT entries with zero */
    199         for (n = 1; n < n_fat; n++) {        /* This loop may take a time on FAT32 volume due to many single sector writes */
    200             if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
    201                 return FR_DISK_ERR;
    202         }
    203     }
    204 
    205     /* Initialize root directory */
    206     i = (fmt == FS_FAT32) ? au : n_dir;
    207     do {
    208         if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
    209             return FR_DISK_ERR;
    210     } while (--i);
    211 
    212 #if _USE_ERASE    /* Erase data area if needed */
    213     {
    214         DWORD eb[2];
    215 
    216         eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;
    217         disk_ioctl(pdrv, CTRL_ERASE_SECTOR, eb);
    218     }
    219 #endif
    220 
    221     /* Create FSInfo if needed */
    222     if (fmt == FS_FAT32) {
    223         ST_DWORD(tbl+FSI_LeadSig, 0x41615252);
    224         ST_DWORD(tbl+FSI_StrucSig, 0x61417272);
    225         ST_DWORD(tbl+FSI_Free_Count, n_clst - 1);    /* Number of free clusters */
    226         ST_DWORD(tbl+FSI_Nxt_Free, 2);                /* Last allocated cluster# */
    227         ST_WORD(tbl+BS_55AA, 0xAA55);
    228         disk_write(pdrv, tbl, b_vol + 1, 1);    /* Write original (VBR+1) */
    229         disk_write(pdrv, tbl, b_vol + 7, 1);    /* Write backup (VBR+7) */
    230     }
    231 
    232     return (disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;
    233 }
    View Code

    函数功能:在驱动器上创建一个文件系统(格式化 SD卡)

    描述:

    f_mkfs函数当_FS_READOLNY == 0并且_USE_MKFS == 1时可用。
    f_mkfs函数在驱动器中创建一个FAT文件系统。对于可移动媒介,有两种分区规则:FDISK和SFD,通过参数PartitioningRule选择。FDISK格式在大多数情况下被推荐使用。该函数当前不支持多分区,因此,物理驱动器上已存在的分区将被删除,并且重新创建一个占据全部磁盘空间的新分区。
    根据Microsoft发布的FAT规范,FAT分类:FAT12/FAT16/FAT32,由驱动器上的簇数决定。因此,选择哪种FAT分类,取决于卷大小和指定的簇大小。簇大小影响文件系统的性能,并且大簇会提高性能。

    例:

     1   FATFS fs;
     2   FIL file;
     3   FRESULT res;
     4   char array[512]={0}, *parray = array;
     5   
     6   res = f_mount(0, &fs);
     7   res = f_mkfs(0 , 0, _MAX_SS);
     8   res = f_open(&file, "data.txt", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
     9   f_printf(&file, "%s
    ", "Success");        /* "Success" */
    10   parray = f_gets(parray , 8, &file);
    11   LCMTextOutExt(  0, 0, parray );
    12   f_close(&file);
    13   f_mount(0, NULL);
    View Code
  • 相关阅读:
    Android studio ocr初级app开发问题汇总(含工程代码)
    面试题思路,25匹马 5个跑道取前三,前五,最少比赛次数--七次
    中国计算机学会推荐国际学术会议和期刊目录(CCF)2019年
    swift 数组部分排序
    SceneKit下关于修改SCNNode 的Shader展示自定义图形
    汇编语言实现字母下落效果
    组合数计算-java
    miniblast_hash算法c语言实现
    日常开发知识点备忘
    骑士周游问题跳马问题C#实现(附带WPF工程代码)
  • 原文地址:https://www.cnblogs.com/Danhuise/p/3911972.html
Copyright © 2011-2022 走看看