FATFS 初学之 f_forward

 1 /*-----------------------------------------------------------------------*/
 2 /* Forward data to the stream directly (available on only tiny cfg)      */
 3 /*-----------------------------------------------------------------------*/
 4
 5 FRESULT f_forward (
 6     FIL *fp,                         /* Pointer to the file object */
 7     UINT (*func)(const BYTE*,UINT),    /* Pointer to the streaming function */
 8     UINT btr,                        /* Number of bytes to forward */
 9     UINT *bf                        /* Pointer to number of bytes forwarded */
10 )
11 {
12     FRESULT res;
13     DWORD remain, clst, sect;
14     UINT rcnt;
15     BYTE csect;
16
17
18     *bf = 0;    /* Initialize byte counter */
19
20     res = validate(fp->fs, fp->id);                    /* Check validity of the object */
21     if (res != FR_OK) LEAVE_FF(fp->fs, res);
22     if (fp->flag & FA__ERROR)                        /* Check error flag */
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
27     remain = fp->fsize - fp->fptr;
28     if (btr > remain) btr = (UINT)remain;            /* Truncate btr by remaining bytes */
29
30     for ( ;  btr && (*func)(0, 0);                    /* Repeat until all data transferred or stream becomes busy */
31         fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) {
32         csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));    /* Sector offset in the cluster */
33         if ((fp->fptr % SS(fp->fs)) == 0) {            /* On the sector boundary? */
34             if (!csect) {                            /* On the cluster boundary? */
35                 clst = (fp->fptr == 0) ?            /* On the top of the file? */
36                     fp->sclust : get_fat(fp->fs, fp->clust);
37                 if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);
38                 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
39                 fp->clust = clst;                    /* Update current cluster */
40             }
41         }
42         sect = clust2sect(fp->fs, fp->clust);        /* Get current data sector */
43         if (!sect) ABORT(fp->fs, FR_INT_ERR);
44         sect += csect;
45         if (move_window(fp->fs, sect))                /* Move sector window */
46             ABORT(fp->fs, FR_DISK_ERR);
47         fp->dsect = sect;
48         rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs));    /* Forward data from sector window */
49         if (rcnt > btr) rcnt = btr;
50         rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt);
51         if (!rcnt) ABORT(fp->fs, FR_INT_ERR);
52     }
53
54     LEAVE_FF(fp->fs, FR_OK);
55 }

函数功能:读取文件数据并将其转发到数据流设备。

描述:

f_forward函数当_USE_FORWARD == 1并且_FS_TINY == 1时可用。
f_forward函数从文件中读取数据并将数据转发到输出流,而不使用数据缓冲区。这适用于小存储系统,因为它在应用模块中不需要任何数据缓冲区。文件对象的文件指针以转发的字节数增加。如果*ByteFwd <ByteToFwd并且没有错误,则意味着由于文件结束或在数据传输过程中流忙,请求的字节不能被传输。

例(音频播放):

 1 /*-----------------------------------------------------------------------*/
 2 /* 示例代码:数据传输函数,将被f_forward函数调用                                 */
 3 /*-----------------------------------------------------------------------*/
 4
 5 UINT out_stream (   /* 返回已发送字节数或流状态 */
 6     const BYTE *p,  /* 将被发送的数据块的指针 */
 7     UINT btf        /* >0: 传输调用(将被发送的字节数)。0: 检测调用 */
 8 )
 9 {
10     UINT cnt = 0;
11
12     if (btf == 0) {     /* 检测调用 */
13         /* 返回流状态(0: 忙,1: 就绪) */
14         /* 当检测调用时,一旦它返回就绪,那么在后续的传输调用时,它必须接收至少一个字节,或者f_forward将以FR_INT_ERROR而失败。 */
15         if (FIFO_READY) cnt = 1;
16     }
17     else {              /* 传输调用 */
18         do {    /* 当有数据要发送并且流就绪时重复 */
19             FIFO_PORT = *p++;
20             cnt++;
21         } while (cnt < btf && FIFO_READY);
22     }
23
24     return cnt;
25 }
26
27
28 /*-----------------------------------------------------------------------*/
29 /* 示例代码:使用f_forward函数                                                    */
30 /*-----------------------------------------------------------------------*/
31
32 FRESULT play_file (
33     char *fn        /* 待播放的音频文件名的指针 */
34 )
35 {
36     FRESULT rc;
37     FIL fil;
38     UINT dmy;
39
40     /* 以只读模式打开音频文件 */
41     rc = f_open(&fil, fn, FA_READ);
42
43     /* 重复,直到文件指针到达文件结束位置 */
44     while (rc == FR_OK && fil.fptr < fil.fsize) {
45
46         /* 任何其他处理... */
47
48         /* 定期或请求式填充输出流 */
49         rc = f_forward(&fil, out_stream, 1000, &dmy);
50     }
51
52     /* 该只读的音频文件对象不需要关闭就可以被丢弃 */
53     return rc;
54 }

FATFS 初学之 f_forward

时间: 2024-08-30 08:16:48

FATFS 初学之 f_forward的相关文章

FATFS 初学之 f_mkdir/ unlink

f_mkdir: 1 /*-----------------------------------------------------------------------*/ 2 /* Create a Directory */ 3 /*-----------------------------------------------------------------------*/ 4 5 FRESULT f_mkdir ( 6 const TCHAR *path /* Pointer to th

FATFS 初学之 f_rename

1 /*-----------------------------------------------------------------------*/ 2 /* Rename File/Directory */ 3 /*-----------------------------------------------------------------------*/ 4 5 FRESULT f_rename ( 6 const TCHAR *path_old, /* Pointer to th

FATFS 初学之 f_mkfs

1 /*-----------------------------------------------------------------------*/ 2 /* Create File System on the Drive */ 3 /*-----------------------------------------------------------------------*/ 4 5 FRESULT f_mkfs ( 6 BYTE drv, /* Logical drive numb

FATFS 初学之 f_getfree

1 /*-----------------------------------------------------------------------*/ 2 /* Get Number of Free Clusters */ 3 /*-----------------------------------------------------------------------*/ 4 5 FRESULT f_getfree ( 6 const TCHAR *path, /* Pointer to

FATFS 初学之 f_chmod/ f_utime

f_chmod: 1 /*-----------------------------------------------------------------------*/ 2 /* Change Attribute */ 3 /*-----------------------------------------------------------------------*/ 4 5 FRESULT f_chmod ( 6 const TCHAR *path, /* Pointer to the

FATFS 初学之 f_open/ f_close

f_open: 1 /*-----------------------------------------------------------------------*/ 2 /* Open or Create a File */ 3 /*-----------------------------------------------------------------------*/ 4 5 FRESULT f_open ( 6 FIL *fp, /* Pointer to the blank

FATFS 初学之 f_chdir/ f_chdrive

1 FRESULT f_chdir ( 2 const TCHAR *path /* Pointer to the directory path */ 3 ) 4 { 5 FRESULT res; 6 DIR dj; 7 DEF_NAMEBUF; 8 9 10 res = chk_mounted(&path, &dj.fs, 0); 11 if (res == FR_OK) { 12 INIT_BUF(dj); 13 res = follow_path(&dj, path); /*

FATFS 初学之 f_opendir/ f_readdir

f_opendir: 1 /*-----------------------------------------------------------------------*/ 2 /* Create a Directroy Object */ 3 /*-----------------------------------------------------------------------*/ 4 5 FRESULT f_opendir ( 6 DIR *dj, /* Pointer to

FATFS 初学之 f_gets/ f_putc/ f_puts/ f_printf

详见:嵌入式大讲堂 f_gets: 1 /*-----------------------------------------------------------------------*/ 2 /* Get a string from the file */ 3 /*-----------------------------------------------------------------------*/ 4 TCHAR* f_gets ( 5 TCHAR* buff, /* Point