FATFS 初学之 f_read/ f_write

/-----------------------------------------------------------------------/
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 }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值