zoukankan      html  css  js  c++  java
  • FATFS 初学之 f_read/ f_write

    f_read:

     1 /*-----------------------------------------------------------------------*/
     2 /* Read File                                                             */
     3 /*-----------------------------------------------------------------------*/
     4 
     5 FRESULT f_read (
     6     FIL *fp,         /* Pointer to the file object */
     7     void *buff,        /* Pointer to data buffer */
     8     UINT btr,        /* Number of bytes to read */
     9     UINT *br        /* Pointer to number of bytes read */
    10 )
    11 {
    12     FRESULT res;
    13     DWORD clst, sect, remain;
    14     UINT rcnt, cc;
    15     BYTE csect, *rbuff = buff;
    16 
    17 
    18     *br = 0;    /* Initialize byte counter */
    19 
    20     res = validate(fp->fs, fp->id);                /* Check validity */
    21     if (res != FR_OK) LEAVE_FF(fp->fs, res);
    22     if (fp->flag & FA__ERROR)                    /* Aborted file? */
    23         LEAVE_FF(fp->fs, FR_INT_ERR);
    24     if (!(fp->flag & FA_READ))                     /* Check access mode */
    25         LEAVE_FF(fp->fs, FR_DENIED);
    26     remain = fp->fsize - fp->fptr;
    27     if (btr > remain) btr = (UINT)remain;        /* Truncate btr by remaining bytes */
    28 
    29     for ( ;  btr;                                /* Repeat until all data read */
    30         rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
    31         if ((fp->fptr % SS(fp->fs)) == 0) {        /* On the sector boundary? */
    32             csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));    /* Sector offset in the cluster */
    33             if (!csect) {                        /* On the cluster boundary? */
    34                 if (fp->fptr == 0) {            /* On the top of the file? */
    35                     clst = fp->sclust;            /* Follow from the origin */
    36                 } else {                        /* Middle or end of the file */
    37 #if _USE_FASTSEEK
    38                     if (fp->cltbl)
    39                         clst = clmt_clust(fp, fp->fptr);    /* Get cluster# from the CLMT */
    40                     else
    41 #endif
    42                         clst = get_fat(fp->fs, fp->clust);    /* Follow cluster chain on the FAT */
    43                 }
    44                 if (clst < 2) ABORT(fp->fs, FR_INT_ERR);
    45                 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
    46                 fp->clust = clst;                /* Update current cluster */
    47             }
    48             sect = clust2sect(fp->fs, fp->clust);    /* Get current sector */
    49             if (!sect) ABORT(fp->fs, FR_INT_ERR);
    50             sect += csect;
    51             cc = btr / SS(fp->fs);                /* When remaining bytes >= sector size, */
    52             if (cc) {                            /* Read maximum contiguous sectors directly */
    53                 if (csect + cc > fp->fs->csize)    /* Clip at cluster boundary */
    54                     cc = fp->fs->csize - csect;
    55                 if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK)
    56                     ABORT(fp->fs, FR_DISK_ERR);
    57 #if !_FS_READONLY && _FS_MINIMIZE <= 2            /* Replace one of the read sectors with cached data if it contains a dirty sector */
    58 #if _FS_TINY
    59                 if (fp->fs->wflag && fp->fs->winsect - sect < cc)
    60                     mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs));
    61 #else
    62                 if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc)
    63                     mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs));
    64 #endif
    65 #endif
    66                 rcnt = SS(fp->fs) * cc;            /* Number of bytes transferred */
    67                 continue;
    68             }
    69 #if !_FS_TINY
    70             if (fp->dsect != sect) {            /* Load data sector if not in cache */
    71 #if !_FS_READONLY
    72                 if (fp->flag & FA__DIRTY) {        /* Write-back dirty sector cache */
    73                     if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
    74                         ABORT(fp->fs, FR_DISK_ERR);
    75                     fp->flag &= ~FA__DIRTY;
    76                 }
    77 #endif
    78                 if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)    /* Fill sector cache */
    79                     ABORT(fp->fs, FR_DISK_ERR);
    80             }
    81 #endif
    82             fp->dsect = sect;
    83         }
    84         rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs));    /* Get partial sector data from sector buffer */
    85         if (rcnt > btr) rcnt = btr;
    86 #if _FS_TINY
    87         if (move_window(fp->fs, fp->dsect))        /* Move sector window */
    88             ABORT(fp->fs, FR_DISK_ERR);
    89         mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt);    /* Pick partial sector */
    90 #else
    91         mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt);    /* Pick partial sector */
    92 #endif
    93     }
    94 
    95     LEAVE_FF(fp->fs, FR_OK);
    96 }
    View Code

    函数功能:从已打开的文件中读取数据。

    描述:文件对象中的读/写指针以已读取字节数增加。该函数成功后,应该检查 *ByteRead 来检测文件是否结束。在读操作过程中,一旦 *ByteRead < ByteToRead ,则读/写指针到达了文件结束位置。

    f_write:

      1 /*-----------------------------------------------------------------------*/
      2 /* Write File                                                            */
      3 /*-----------------------------------------------------------------------*/
      4 
      5 FRESULT f_write (
      6     FIL *fp,            /* Pointer to the file object */
      7     const void *buff,    /* Pointer to the data to be written */
      8     UINT btw,            /* Number of bytes to write */
      9     UINT *bw            /* Pointer to number of bytes written */
     10 )
     11 {
     12     FRESULT res;
     13     DWORD clst, sect;
     14     UINT wcnt, cc;
     15     const BYTE *wbuff = buff;
     16     BYTE csect;
     17 
     18 
     19     *bw = 0;    /* Initialize byte counter */
     20 
     21     res = validate(fp->fs, fp->id);            /* Check validity */
     22     if (res != FR_OK) LEAVE_FF(fp->fs, res);
     23     if (fp->flag & FA__ERROR)                /* Aborted file? */
     24         LEAVE_FF(fp->fs, FR_INT_ERR);
     25     if (!(fp->flag & FA_WRITE))                /* Check access mode */
     26         LEAVE_FF(fp->fs, FR_DENIED);
     27     if ((DWORD)(fp->fsize + btw) < fp->fsize) btw = 0;    /* File size cannot reach 4GB */
     28 
     29     for ( ;  btw;                            /* Repeat until all data written */
     30         wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
     31         if ((fp->fptr % SS(fp->fs)) == 0) {    /* On the sector boundary? */
     32             csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));    /* Sector offset in the cluster */
     33             if (!csect) {                    /* On the cluster boundary? */
     34                 if (fp->fptr == 0) {        /* On the top of the file? */
     35                     clst = fp->sclust;        /* Follow from the origin */
     36                     if (clst == 0)            /* When no cluster is allocated, */
     37                         fp->sclust = clst = create_chain(fp->fs, 0);    /* Create a new cluster chain */
     38                 } else {                    /* Middle or end of the file */
     39 #if _USE_FASTSEEK
     40                     if (fp->cltbl)
     41                         clst = clmt_clust(fp, fp->fptr);    /* Get cluster# from the CLMT */
     42                     else
     43 #endif
     44                         clst = create_chain(fp->fs, fp->clust);    /* Follow or stretch cluster chain on the FAT */
     45                 }
     46                 if (clst == 0) break;        /* Could not allocate a new cluster (disk full) */
     47                 if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
     48                 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
     49                 fp->clust = clst;            /* Update current cluster */
     50             }
     51 #if _FS_TINY
     52             if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0))    /* Write-back sector cache */
     53                 ABORT(fp->fs, FR_DISK_ERR);
     54 #else
     55             if (fp->flag & FA__DIRTY) {        /* Write-back sector cache */
     56                 if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
     57                     ABORT(fp->fs, FR_DISK_ERR);
     58                 fp->flag &= ~FA__DIRTY;
     59             }
     60 #endif
     61             sect = clust2sect(fp->fs, fp->clust);    /* Get current sector */
     62             if (!sect) ABORT(fp->fs, FR_INT_ERR);
     63             sect += csect;
     64             cc = btw / SS(fp->fs);            /* When remaining bytes >= sector size, */
     65             if (cc) {                        /* Write maximum contiguous sectors directly */
     66                 if (csect + cc > fp->fs->csize)    /* Clip at cluster boundary */
     67                     cc = fp->fs->csize - csect;
     68                 if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK)
     69                     ABORT(fp->fs, FR_DISK_ERR);
     70 #if _FS_TINY
     71                 if (fp->fs->winsect - sect < cc) {    /* Refill sector cache if it gets invalidated by the direct write */
     72                     mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs));
     73                     fp->fs->wflag = 0;
     74                 }
     75 #else
     76                 if (fp->dsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
     77                     mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs));
     78                     fp->flag &= ~FA__DIRTY;
     79                 }
     80 #endif
     81                 wcnt = SS(fp->fs) * cc;        /* Number of bytes transferred */
     82                 continue;
     83             }
     84 #if _FS_TINY
     85             if (fp->fptr >= fp->fsize) {    /* Avoid silly cache filling at growing edge */
     86                 if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR);
     87                 fp->fs->winsect = sect;
     88             }
     89 #else
     90             if (fp->dsect != sect) {        /* Fill sector cache with file data */
     91                 if (fp->fptr < fp->fsize &&
     92                     disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
     93                         ABORT(fp->fs, FR_DISK_ERR);
     94             }
     95 #endif
     96             fp->dsect = sect;
     97         }
     98         wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */
     99         if (wcnt > btw) wcnt = btw;
    100 #if _FS_TINY
    101         if (move_window(fp->fs, fp->dsect))    /* Move sector window */
    102             ABORT(fp->fs, FR_DISK_ERR);
    103         mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt);    /* Fit partial sector */
    104         fp->fs->wflag = 1;
    105 #else
    106         mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt);    /* Fit partial sector */
    107         fp->flag |= FA__DIRTY;
    108 #endif
    109     }
    110 
    111     if (fp->fptr > fp->fsize) fp->fsize = fp->fptr;    /* Update file size if needed */
    112     fp->flag |= FA__WRITTEN;                        /* Set file change flag */
    113 
    114     LEAVE_FF(fp->fs, FR_OK);
    115 }
    View Code

    函数功能:向已打开的问价中写入数据。

    描述:文件对象中的读/写指针以已写入字节数增加。该函数成功后,应该检查 *ByteWritten 来检测磁盘是否满。在写操作过程中,一旦 *ByteWritten < *ByteToWritten ,则意味着该卷已满。

    这两个函数在调用过程中会将文件读写指针 fp->fptr的值累加,使得下次再次对该文件操作时从上次操作的断点处继续向下操作。

    例:

     1 void main (void)
     2 {
     3     FATFS fs[2];         /* 逻辑驱动器的工作区(文件系统对象) */
     4     FIL fsrc, fdst;      /* 文件对象 */
     5     BYTE buffer[4096];   /* 文件拷贝缓冲区 */
     6     FRESULT res;         /* FatFs 函数公共结果代码 */
     7     UINT br, bw;         /* 文件读/写字节计数 */
     8     
     9     /* 为逻辑驱动器注册工作区 */
    10     f_mount(0, &fs[0]);
    11     f_mount(1, &fs[1]);
    12     
    13     /* 打开驱动器 1 上的源文件 */
    14     res = f_open(&fsrc, "1:srcfile.dat", FA_OPEN_EXISTING | FA_READ);
    15     if (res) die(res);
    16     
    17     /* 在驱动器 0 上创建目标文件 */
    18     res = f_open(&fdst, "0:dstfile.dat", FA_CREATE_ALWAYS | FA_WRITE);
    19     if (res) die(res);
    20     
    21     /* 拷贝源文件到目标文件 */
    22     for (;;) {
    23         res = f_read(&fsrc, buffer, sizeof(buffer), &br);
    24         if (res || br == 0) break;   /* 文件结束错误 */
    25         res = f_write(&fdst, buffer, br, &bw);
    26         if (res || bw < br) break;   /* 磁盘满错误 */
    27     }
    28     
    29     /* 关闭打开的文件 */
    30     f_close(&fsrc);
    31     f_close(&fdst);
    32     
    33     /* 注销工作区(在废弃前) */
    34     f_mount(0, NULL);
    35     f_mount(1, NULL);
    36 }
    View Code
  • 相关阅读:
    i春秋暑期训练营丨渗透测试工程师开课啦
    CTF必备技能丨Linux Pwn入门教程——环境配置
    i春秋四周年中奖名单出炉丨确认过眼神,你是中奖人
    i春秋四周年福利趴丨一纸证书教你赢在起跑线
    「你学习,我买单」i春秋四周年精品课程福利专场
    i春秋四周年庆典狂欢丨价值6000元的Web安全课程免费送啦
    倒计时3天!i春秋四周年盛典狂欢,钜惠不停
    「学习攻略」0基础转型白帽黑客第一步是什么?
    奖金高达150万元的NEST即将上线,速来报名
    「白帽挖洞技能」YxCMS 1.4.7 漏洞分析
  • 原文地址:https://www.cnblogs.com/Danhuise/p/3909869.html
Copyright © 2011-2022 走看看