大家帮帮忙,使用FSTFS文件系统时创建文件失败原因,感激不尽!具体问题如下如下:
使用SPI驱动SD卡,移植的是FATFS_R0.09文件系统,可以正常读文件中的内容,但是创建文件时失败,返回错误2 FR_INT_ERR。使用电脑打卡SD卡后发现有所要创建的文件存在,但是无法打开,提示“文件或目录损坏且无法读取”
代码如下
/* Register work area for each volume (Always succeeds regardless of disk status) */
res = f_mount(0,&fs);
/* Create new file on the drive 0 */
res = f_open(&fnew, "0:1.txt", FA_CREATE_ALWAYS | FA_WRITE );
if ( res == FR_OK )
{
res = f_write(&fnew, textFileBuffer, sizeof(textFileBuffer), &bw);
f_close(&fnew);
}
else if(res == FR_EXIST)
{
printf("\r\n 文件已经存在 \r\n");
}
仿真调试发现错误产生的函数为
res = remove_chain(dj.fs, cl);
/*-----------------------------------------------------------------------*/
/* Open or Create a File */
/*-----------------------------------------------------------------------*/
FRESULT f_open (
FIL *fp, /* Pointer to the blank file object */
const TCHAR *path, /* Pointer to the file name */
BYTE mode /* Access mode and file open mode flags */
)
{
FRESULT res;
DIR dj;
BYTE *dir;
DEF_NAMEBUF;
fp->fs = 0; /* Clear file object */
#if !_FS_READONLY
mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW;
res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ));
#else
mode &= FA_READ;
res = chk_mounted(&path, &dj.fs, 0);
#endif
INIT_BUF(dj);
if (res == FR_OK)
res = follow_path(&dj, path); /* Follow the file path */
dir = dj.dir;
#if !_FS_READONLY /* R/W configuration */
if (res == FR_OK) {
if (!dir) /* Current dir itself */
res = FR_INVALID_NAME;
#if _FS_SHARE
else
res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
#endif
}
/* Create or Open a file */
if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {
DWORD dw, cl;
if (res != FR_OK) { /* No file, create new */
if (res == FR_NO_FILE) /* There is no file to open, create a new entry */
#if _FS_SHARE
res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;
#else
res = dir_register(&dj);
#endif
mode |= FA_CREATE_ALWAYS; /* File is created */
dir = dj.dir; /* New entry */
}
else { /* Any object is already existing */
if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */
res = FR_DENIED;
} else {
if (mode & FA_CREATE_NEW) /* Cannot create as new file */
res = FR_EXIST;
}
}
if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */
dw = get_fattime(); /* Created time */
ST_DWORD(dir+DIR_CrtTime, dw);
dir[DIR_Attr] = 0; /* Reset attribute */
ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */
cl = LD_CLUST(dir); /* Get start cluster */
ST_CLUST(dir, 0); /* cluster = 0 */
dj.fs->wflag = 1;
if (cl) { /* Remove the cluster chain if exist */
dw = dj.fs->winsect;
res = remove_chain(dj.fs, cl); //产生 FR_INT_ERR 错误 此处 参数 cl = 0xFFFFFFFF 估计是前面对cl赋值时出错了 但不知什么原因
/*
static
FRESULT remove_chain (
FATFS *fs, /* File system object */
DWORD clst /* Cluster# to remove a chain from */
)
{
FRESULT res;
DWORD nxt;
#if _USE_ERASE
DWORD scl = clst, ecl = clst, resion[2];
#endif
if (clst < 2 || clst >= fs->n_fatent) { /* Check range */
res = FR_INT_ERR;
*/
if (res == FR_OK) {
dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */
res = move_window(dj.fs, dw);
}
}
}
}
else { /* Open an existing file */
if (res == FR_OK) { /* Follow succeeded */
if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */
res = FR_NO_FILE;
} else {
if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */
res = FR_DENIED;
}
}
}
if (res == FR_OK) {
if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */
mode |= FA__WRITTEN;
fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */
fp->dir_ptr = dir;
#if _FS_SHARE
fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
if (!fp->lockid) res = FR_INT_ERR;
#endif
}
#else /* R/O configuration */
if (res == FR_OK) { /* Follow succeeded */
if (!dir) { /* Current dir itself */
res = FR_INVALID_NAME;
} else {
if (dir[DIR_Attr] & AM_DIR) /* It is a directory */
res = FR_NO_FILE;
}
}
#endif
FREE_BUF();
if (res == FR_OK) {
fp->flag = mode; /* File access mode */
fp->sclust = LD_CLUST(dir); /* File start cluster */
fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */
fp->fptr = 0; /* File pointer */
fp->dsect = 0;
#if _USE_FASTSEEK
fp->cltbl = 0; /* Normal seek mode */
#endif
fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */
}
LEAVE_FF(dj.fs, res);
}
|
|