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 #endif 111 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_FASTSEEK 120 fp->cltbl = 0; /* Normal seek mode */ 121 #endif 122 fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */ 123 } 124 125 LEAVE_FF(dj.fs, res); 126 }
函数功能:创建/打开一个用于访问文件的文件对象
描述:如果函数成功,则创建一个文件对象。该文件对象被后续的读/写函数用来访问文件。如果想要关闭一个打开的文件对象,则使用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_READONLY 12 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 #else 18 res = f_sync(fp); /* Flush cached data */ 19 #if _FS_SHARE 20 if (res == FR_OK) { /* Decrement open counter */ 21 #if _FS_REENTRANT 22 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 #else 28 res = dec_lock(fp->lockid); 29 #endif 30 } 31 #endif 32 if (res == FR_OK) fp->fs = 0; /* Discard file object */ 33 return res; 34 #endif 35 }
函数功能:关闭一个已打开的文件
描述: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 else 17 { 18 // ... 19 } 20 21 f_mount(0, NULL); 22 }
FATFS 初学之 f_open/ f_close
时间: 2024-10-08 01:57:41