首页 > 代码库 > FATFS 初学之 f_open/ f_close

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 file object */  7     const TCHAR *path,    /* Pointer to the file name */  8     BYTE mode            /* Access mode and file open mode flags */  9 ) 10 { 11     FRESULT res; 12     DIR dj; 13     BYTE *dir; 14     DEF_NAMEBUF; 15  16  17     fp->fs = 0;            /* Clear file object */ 18  19 #if !_FS_READONLY 20     mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW; 21     res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ)); 22 #else 23     mode &= FA_READ; 24     res = chk_mounted(&path, &dj.fs, 0); 25 #endif 26     INIT_BUF(dj); 27     if (res == FR_OK) 28         res = follow_path(&dj, path);    /* Follow the file path */ 29     dir = dj.dir; 30  31 #if !_FS_READONLY    /* R/W configuration */ 32     if (res == FR_OK) { 33         if (!dir)    /* Current dir itself */ 34             res = FR_INVALID_NAME; 35 #if _FS_SHARE 36         else 37             res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); 38 #endif 39     } 40     /* Create or Open a file */ 41     if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { 42         DWORD dw, cl; 43  44         if (res != FR_OK) {                    /* No file, create new */ 45             if (res == FR_NO_FILE)            /* There is no file to open, create a new entry */ 46 #if _FS_SHARE 47                 res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; 48 #else 49                 res = dir_register(&dj); 50 #endif 51             mode |= FA_CREATE_ALWAYS;        /* File is created */ 52             dir = dj.dir;                    /* New entry */ 53         } 54         else {                                /* Any object is already existing */ 55             if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) {    /* Cannot overwrite it (R/O or DIR) */ 56                 res = FR_DENIED; 57             } else { 58                 if (mode & FA_CREATE_NEW)    /* Cannot create as new file */ 59                     res = FR_EXIST; 60             } 61         } 62         if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) {    /* Truncate it if overwrite mode */ 63             dw = get_fattime();                    /* Created time */ 64             ST_DWORD(dir+DIR_CrtTime, dw); 65             dir[DIR_Attr] = 0;                    /* Reset attribute */ 66             ST_DWORD(dir+DIR_FileSize, 0);        /* size = 0 */ 67             cl = LD_CLUST(dir);                    /* Get start cluster */ 68             ST_CLUST(dir, 0);                    /* cluster = 0 */ 69             dj.fs->wflag = 1; 70             if (cl) {                            /* Remove the cluster chain if exist */ 71                 dw = dj.fs->winsect; 72                 res = remove_chain(dj.fs, cl); 73                 if (res == FR_OK) { 74                     dj.fs->last_clust = cl - 1;    /* Reuse the cluster hole */ 75                     res = move_window(dj.fs, dw); 76                 } 77             } 78         } 79     } 80     else {    /* Open an existing file */ 81         if (res == FR_OK) {                        /* Follow succeeded */ 82             if (dir[DIR_Attr] & AM_DIR) {        /* It is a directory */ 83                 res = FR_NO_FILE; 84             } else { 85                 if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ 86                     res = FR_DENIED; 87             } 88         } 89     } 90     if (res == FR_OK) { 91         if (mode & FA_CREATE_ALWAYS)            /* Set file change flag if created or overwritten */ 92             mode |= FA__WRITTEN; 93         fp->dir_sect = dj.fs->winsect;            /* Pointer to the directory entry */ 94         fp->dir_ptr = dir; 95 #if _FS_SHARE 96         fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); 97         if (!fp->lockid) res = FR_INT_ERR; 98 #endif 99     }100 101 #else                /* R/O configuration */102     if (res == FR_OK) {                    /* Follow succeeded */103         if (!dir) {                        /* Current dir itself */104             res = FR_INVALID_NAME;105         } else {106             if (dir[DIR_Attr] & AM_DIR)    /* It is a directory */107                 res = FR_NO_FILE;108         }109     }110 #endif111     FREE_BUF();112 113     if (res == FR_OK) {114         fp->flag = mode;                    /* File access mode */115         fp->sclust = LD_CLUST(dir);            /* File start cluster */116         fp->fsize = LD_DWORD(dir+DIR_FileSize);    /* File size */117         fp->fptr = 0;                        /* File pointer */118         fp->dsect = 0;119 #if _USE_FASTSEEK120         fp->cltbl = 0;                        /* Normal seek mode */121 #endif122         fp->fs = dj.fs; fp->id = dj.fs->id;    /* Validate file object */123     }124 125     LEAVE_FF(dj.fs, res);126 }
View Code

函数功能:创建/打开一个用于访问文件的文件对象

描述:如果函数成功,则创建一个文件对象。该文件对象被后续的读/写函数用来访问文件。如果想要关闭一个打开的文件对象,则使用f_close函数。如果不关闭修改后的文件,那么文件可能会崩溃。

在使用任何文件函数之前,必须使用 f_mount函数为驱动器注册一个工作区。只有这样,其他文件函数才能正常工作。

将打开的文件名、文件目录及读写属性等装入 fp,为后续操作做准备。

 

f_close:

 1 /*-----------------------------------------------------------------------*/ 2 /* Close File                                                            */ 3 /*-----------------------------------------------------------------------*/ 4  5 FRESULT f_close ( 6     FIL *fp        /* Pointer to the file object to be closed */ 7 ) 8 { 9     FRESULT res;10 11 #if _FS_READONLY12     FATFS *fs = fp->fs;13     res = validate(fs, fp->id);14     if (res == FR_OK) fp->fs = 0;    /* Discard file object */15     LEAVE_FF(fs, res);16 17 #else18     res = f_sync(fp);        /* Flush cached data */19 #if _FS_SHARE20     if (res == FR_OK) {        /* Decrement open counter */21 #if _FS_REENTRANT22         res = validate(fp->fs, fp->id);23         if (res == FR_OK) {24             res = dec_lock(fp->lockid);    25             unlock_fs(fp->fs, FR_OK);26         }27 #else28         res = dec_lock(fp->lockid);29 #endif30     }31 #endif32     if (res == FR_OK) fp->fs = 0;    /* Discard file object */33     return res;34 #endif35 }
View Code

函数功能:关闭一个已打开的文件

描述:f_close函数关闭一个打开的文件对象。无论向文件写入任何数据,文件的缓存信息都将被写回到磁盘。该函数成功后,文件对象不再有效,并且可以被丢弃。如果文件对象是在只读模式下打开的,不需要使用该函数,也能被丢弃。

 

例:

 1 FATFS fs;        /* 逻辑驱动器的工作区(文件系统对象) */ 2 FIL fsrc;        /* 文件对象 */ 3 FRESULT res;    /* FatFs 函数公共结果代码 */ 4  5 void main(void) 6 { 7     // 设备初始化... 8      9     f_mount(0,&fs);10     res = f_open(&fdst,"0:/Demo.TXT", FA_WRITE | FA_READ);11     if(FR_OK == res)12     {13         // ...14         f_close(&fdst);15     }16     else17     {18         // ...19     }20     21     f_mount(0, NULL);22 }