f_lseek_FATFS 初学之 f_lseek

1 /*-----------------------------------------------------------------------*/

2 /*Seek File R/W Pointer*/

3 /*-----------------------------------------------------------------------*/

4

5 FRESULT f_lseek (6 FIL *fp, /*Pointer to the file object*/

7 DWORD ofs /*File pointer from top of file*/

8 )9 {10 FRESULT res;11

12

13 res = validate(fp->fs, fp->id); /*Check validity of the object*/

14 if (res != FR_OK) LEAVE_FF(fp->fs, res);15 if (fp->flag & FA__ERROR) /*Check abort flag*/

16 LEAVE_FF(fp->fs, FR_INT_ERR);17

18 #if _USE_FASTSEEK

19 if (fp->cltbl) { /*Fast seek*/

20 DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;21

22 if (ofs == CREATE_LINKMAP) { /*Create CLMT*/

23 tbl = fp->cltbl;24 tlen = *tbl++; ulen = 2; /*Given table size and required table size*/

25 cl = fp->sclust; /*Top of the chain*/

26 if(cl) {27 do{28 /*Get a fragment*/

29 tcl = cl; ncl = 0; ulen += 2; /*Top, length and used items*/

30 do{31 pcl = cl; ncl++;32 cl = get_fat(fp->fs, cl);33 if (cl <= 1) ABORT(fp->fs, FR_INT_ERR);34 if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);35 } while (cl == pcl + 1);36 if (ulen <= tlen) { /*Store the length and top of the fragment*/

37 *tbl++ = ncl; *tbl++ =tcl;38 }39 } while (cl < fp->fs->n_fatent); /*Repeat until end of chain*/

40 }41 *fp->cltbl = ulen; /*Number of items used*/

42 if (ulen <=tlen)43 *tbl = 0; /*Terminate table*/

44 else

45 res = FR_NOT_ENOUGH_CORE; /*Given table size is smaller than required*/

46

47 } else { /*Fast seek*/

48 if (ofs > fp->fsize) /*Clip offset at the file size*/

49 ofs = fp->fsize;50 fp->fptr = ofs; /*Set file pointer*/

51 if(ofs) {52 fp->clust = clmt_clust(fp, ofs - 1);53 dsc = clust2sect(fp->fs, fp->clust);54 if (!dsc) ABORT(fp->fs, FR_INT_ERR);55 dsc += (ofs - 1) / SS(fp->fs) & (fp->fs->csize - 1);56 if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { /*Refill sector cache if needed*/

57 #if !_FS_TINY

58 #if !_FS_READONLY

59 if (fp->flag & FA__DIRTY) { /*Write-back dirty sector cache*/

60 if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) !=RES_OK)61 ABORT(fp->fs, FR_DISK_ERR);62 fp->flag &= ~FA__DIRTY;63 }64 #endif

65 if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) /*Load current sector*/

66 ABORT(fp->fs, FR_DISK_ERR);67 #endif

68 fp->dsect =dsc;69 }70 }71 }72 } else

73 #endif

74

75 /*Normal Seek*/

76 {77 DWORD clst, bcs, nsect, ifptr;78

79 if (ofs > fp->fsize /*In read-only mode, clip offset with the file size*/

80 #if !_FS_READONLY

81 && !(fp->flag &FA_WRITE)82 #endif

83 ) ofs = fp->fsize;84

85 ifptr = fp->fptr;86 fp->fptr = nsect = 0;87 if(ofs) {88 bcs = (DWORD)fp->fs->csize * SS(fp->fs); /*Cluster size (byte)*/

89 if (ifptr > 0 &&

90 (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /*When seek to same or following cluster,*/

91 fp->fptr = (ifptr - 1) & ~(bcs - 1); /*start from the current cluster*/

92 ofs -= fp->fptr;93 clst = fp->clust;94 } else { /*When seek to back cluster,*/

95 clst = fp->sclust; /*start from the first cluster*/

96 #if !_FS_READONLY

97 if (clst == 0) { /*If no cluster chain, create a new chain*/

98 clst = create_chain(fp->fs, 0);99 if (clst == 1) ABORT(fp->fs, FR_INT_ERR);100 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);101 fp->sclust =clst;102 }103 #endif

104 fp->clust =clst;105 }106 if (clst != 0) {107 while (ofs > bcs) { /*Cluster following loop*/

108 #if !_FS_READONLY

109 if (fp->flag & FA_WRITE) { /*Check if in write mode or not*/

110 clst = create_chain(fp->fs, clst); /*Force stretch if in write mode*/

111 if (clst == 0) { /*When disk gets full, clip file size*/

112 ofs = bcs; break;113 }114 } else

115 #endif

116 clst = get_fat(fp->fs, clst); /*Follow cluster chain if not in write mode*/

117 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);118 if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR);119 fp->clust =clst;120 fp->fptr +=bcs;121 ofs -=bcs;122 }123 fp->fptr +=ofs;124 if (ofs % SS(fp->fs)) {125 nsect = clust2sect(fp->fs, clst); /*Current sector*/

126 if (!nsect) ABORT(fp->fs, FR_INT_ERR);127 nsect += ofs / SS(fp->fs);128 }129 }130 }131 if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { /*Fill sector cache if needed*/

132 #if !_FS_TINY

133 #if !_FS_READONLY

134 if (fp->flag & FA__DIRTY) { /*Write-back dirty sector cache*/

135 if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) !=RES_OK)136 ABORT(fp->fs, FR_DISK_ERR);137 fp->flag &= ~FA__DIRTY;138 }139 #endif

140 if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) /*Fill sector cache*/

141 ABORT(fp->fs, FR_DISK_ERR);142 #endif

143 fp->dsect =nsect;144 }145 #if !_FS_READONLY

146 if (fp->fptr > fp->fsize) { /*Set file change flag if the file size is extended*/

147 fp->fsize = fp->fptr;148 fp->flag |=FA__WRITTEN;149 }150 #endif

151 }152

153 LEAVE_FF(fp->fs, res);154 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值