📄 fat.c
字号:
clust = 2;
do {
if ((uint16)get_cluster(clust) == 0) n++;
} while (++clust < fs->max_clust);
} else {
clust = fs->max_clust;
sect = fs->fatbase;
f = 0; p = 0;
do {
if (!f)
{
if (!move_window(sect++))
return FR_RW_ERROR;
p = fs->win;
}
if (fat == FS_FAT16)
{
if (LDF_WORD(p) == 0) n++;
p += 2; f += 1;
} else {
if (LDF_DWORD(p) == 0) n++;
p += 4; f += 2;
}
} while (--clust);
}
*nclust = n;
return FR_OK;
}
/*------------------------------*/
/* Delete a File or a Directory */
uint16 f_unlink (
const sint8 *path /* Pointer to the file or directory path */
)
{
uint16 res;
uint8 *dir, *sdir;
uint32 dclust, dsect;
DIR dirscan;
sint8 fn[8+3+1];
FATFS *fs = FatFs;
if ((res = check_mounted()) != FR_OK) return res;
if (disk_status() & STA_PROTECT) return FR_WRITE_PROTECTED;
res = trace_path(&dirscan, fn, path, &dir); /* Trace the file path */
if (res != FR_OK) return res; /* Trace failed */
if (dir == NULL) return FR_NO_FILE; /* It is a root directory */
if (*(dir+11) & AM_RDO) return FR_DENIED; /* It is a R/O item */
dsect = fs->winsect;
dclust = ((uint32)LDF_WORD(dir+20) << 16) | LDF_WORD(dir+26);
if (*(dir+11) & AM_DIR) { /* It is a sub-directory */
dirscan.clust = dclust; /* Check if the sub-dir is empty or not */
dirscan.sect = clust2sect(dclust);
dirscan.index = 0;
do {
if (!move_window(dirscan.sect)) return FR_RW_ERROR;
sdir = &(fs->win[(dirscan.index & 15) * 32]);
if (*sdir == 0) break;
if (!((*sdir == 0xE5) || (*sdir == '.')) && !(*(sdir+11) & AM_VOL))
return FR_DENIED; /* The directory is not empty */
} while (next_dir_entry(&dirscan));
}
if (!move_window(dsect)) return FR_RW_ERROR; /* Mark the directory entry 'deleted' */
*dir = 0xE5;
fs->winflag = 1;
if (!remove_chain(dclust)) return FR_RW_ERROR; /* Remove the cluster chain */
if (!move_window(0)) return FR_RW_ERROR;
return FR_OK;
}
/*--------------------*/
/* Create a Directory */
uint16 f_mkdir (
const sint8 *path /* Pointer to the directory path */
)
{
uint16 res;
uint8 *dir, *w, n;
uint32 sect, dsect, dclust, pclust, tim;
DIR dirscan;
sint8 fn[8+3+1];
FATFS *fs = FatFs;
if ((res = check_mounted()) != FR_OK) return res;
if (disk_status() & STA_PROTECT) return FR_WRITE_PROTECTED;
res = trace_path(&dirscan, fn, path, &dir); /* Trace the file path */
if (res == FR_OK) return FR_DENIED; /* Any file or directory is already existing */
if (res != FR_NO_FILE) return res;
dir = reserve_direntry(&dirscan); /* Reserve a directory entry */
if (dir == NULL) return FR_DENIED;
sect = fs->winsect;
dsect = clust2sect(dclust = create_chain(0)); /* Get a new cluster for new directory */
if (!dsect) return FR_DENIED;
if (!move_window(0)) return 0;
w = fs->win;
memset(w, 0, 512); /* Initialize the directory table */
for (n = fs->sects_clust - 1; n; n--) {
if (disk_write(w, dsect+n, 1) != RES_OK) return FR_RW_ERROR;
}
fs->winsect = dsect; /* Create dot directories */
memset(w, ' ', 8+3);
*w = '.';
*(w+11) = AM_DIR;
tim = get_fattime();
ST_DWORD(w+22, tim);
ST_WORD(w+26, dclust);
ST_WORD(w+20, dclust >> 16);
memcpy(w+32, w, 32); *(w+33) = '.';
pclust = dirscan.sclust;
if (fs->fs_type == FS_FAT32 && pclust == fs->dirbase) pclust = 0;
ST_WORD(w+32+26, pclust);
ST_WORD(w+32+20, pclust >> 16);
fs->winflag = 1;
if (!move_window(sect)) return FR_RW_ERROR;
memcpy(dir, fn, 8+3); /* Initialize the new entry */
*(dir+11) = AM_DIR;
*(dir+12) = fn[11];
memset(dir+13, 0, 32-13);
ST_DWORD(dir+22, tim); /* Crated time */
ST_WORD(dir+26, dclust); /* Table start cluster */
ST_WORD(dir+20, dclust >> 16);
fs->winflag = 1;
if (!move_window(0)) return FR_RW_ERROR;
return FR_OK;
}
/*-----------------------*/
/* Change File Attribute */
uint16 f_chmod (
const sint8 *path, /* Pointer to the file path */
uint8 value, /* Attribute bits */
uint8 mask /* Attribute mask to change */
)
{
uint16 res;
uint8 *dir;
DIR dirscan;
sint8 fn[8+3+1];
FATFS *fs = FatFs;
if ((res = check_mounted()) != FR_OK) return res;
if (disk_status() & STA_PROTECT) return FR_WRITE_PROTECTED;
res = trace_path(&dirscan, fn, path, &dir); /* Trace the file path */
if (res == FR_OK) { /* Trace completed */
if (dir == NULL) {
res = FR_NO_FILE;
} else {
mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */
*(dir+11) = (value & mask) | (*(dir+11) & ~mask); /* Apply attribute change */
fs->winflag = 1;
if (!move_window(0)) res = FR_RW_ERROR;
}
}
return res;
}
/*-----------------------*/
/* Rename File/Directory */
uint16 f_rename (
const sint8 *path_old, /* Pointer to the old name */
const sint8 *path_new /* Pointer to the new name */
)
{
uint16 res;
uint32 sect_old;
uint8 *dir_old, *dir_new, direntry[32-11];
DIR dirscan;
sint8 fn[8+3+1];
FATFS *fs = FatFs;
if ((res = check_mounted()) != FR_OK) return res;
if (disk_status() & STA_PROTECT) return FR_WRITE_PROTECTED;
res = trace_path(&dirscan, fn, path_old, &dir_old); /* Check old object */
if (res != FR_OK) return res; /* The old object is not found */
if (!dir_old) return FR_NO_FILE;
sect_old = fs->winsect; /* Save the object information */
memcpy(direntry, dir_old+11, 32-11);
res = trace_path(&dirscan, fn, path_new, &dir_new); /* Check new object */
if (res == FR_OK) return FR_DENIED; /* The new object name is already existing */
if (res != FR_NO_FILE) return res;
dir_new = reserve_direntry(&dirscan); /* Reserve a directory entry */
if (dir_new == NULL) return FR_DENIED;
memcpy(dir_new+11, direntry, 32-11); /* Create new entry */
memcpy(dir_new, fn, 8+3);
*(dir_new+12) = fn[11];
fs->winflag = 1;
if (!move_window(sect_old)) return FR_RW_ERROR; /* Remove old entry */
*dir_old = 0xE5;
fs->winflag = 1;
if (!move_window(0)) return FR_RW_ERROR;
return FR_OK;
}
/********************************************************************************
* @func f_format16
*
* @note format file system fat16
*
* @param NULL
*
* @return uint16 : return errer code
*******************************************************************************/
uint16 f_formatfat16(void)
{
FATFS *fs = FatFs;
uint16 ret = EC_SUCCESS;
sint8 fat;
uint32 offset;
uint16 i = 0;
//uint16 sectPclus;
uint16 sectPfat;
//uint32 isects;
uint32 diskSize;
uint8 *buffer;
uint16 clusPsects;
uint32 allSects;
uint16 rsvSects = 1;
if( disk_status() & STA_NOINIT )
{
if( disk_initialize() & STA_NOINIT )
{
return EC_SD_INIT_ERROR;
}
}
if (!fs) return FR_NOT_ENABLED;
/* Initialize file system object */
memset(fs, 0, sizeof(FATFS));
/* Search FAT partition */
fat = check_fs(offset = 0); /* Check sector 0 as an SFD format */
if (!fat) { /* Not a FAT boot record, it will be an FDISK format */
/* Check a partition listed in top of the partition table */
if (fs->win[0x1C2]) { /* Is the partition existing? */
offset = LDF_DWORD(&(fs->win[0x1C6])); /* Partition offset in LBA */
fat = check_fs(offset); /* Check the partition */
}
}
/*
if( (ret = disk_ioctl(GET_SECTORS,(uint8*)(&isects))) != EC_SUCCESS )
return ret;
*/
if( (ret = disk_ioctl(GET_SECTORS,(uint8*)(&allSects))) != EC_SUCCESS )
return ret;
diskSize = allSects / (2 * 1024);
// memset(fs->win,0,512);
buffer = fs->win;
/*
size clus/sects clus_szie
0 - 32 1 512B
33 - 64 2 1K
65 - 127 4 2K
128 - 255 8 4K
256 - 511 16 8K
512 - 1023 32 16K
1024- 2047 64 32K
2048-4095 128 64K
*/
if( FS_FAT16 != fat )
{
sectPfat = 0xF4;
/* 4G */
if( diskSize > 2048 && diskSize <= 4096 )
{
clusPsects = 128;
//sectPclus = 0xF4 * 4;
}
/* 2G */
else if( diskSize > 1024 && diskSize <= 2048 )
{
clusPsects = 64;
//sectPclus = 0xF4 * 2;
}
/* 1G */
else if( diskSize > 512 && diskSize <= 1024 )
{
clusPsects = 32;
//sectPclus = 0xF4;
}
/* 512M */
else if( diskSize > 256 && diskSize <= 512 )
{
clusPsects = 16;
//sectPclus = (uint16)(0xF4 / 2) ;
}
/* 256M */
else if( diskSize > 128 && diskSize <= 256 )
{
clusPsects = 8;
//sectPclus = (uint16)(0xF4 / 4) ;
}
/* 128M */
else if( diskSize > 64 && diskSize <= 128 )
{
clusPsects = 4;
//sectPclus = (uint16)(0xF4 / 8) ;
}
/* 64M */
else if( diskSize > 32 && diskSize <= 64 )
{
clusPsects = 2;
//sectPclus = (uint16)(0xF4 / 16) ;
}
/* 32M */
else if( diskSize > 16 && diskSize <= 32 )
{
clusPsects = 1;
//sectPclus = (uint16)(0xF4 / 32) ;
}
/* 偦偺懠 */
else
{
return EC_INVALID_SD_SIZE;
}
memset(buffer,0,512);
/* jump code */
buffer[0] = 0xEB;
buffer[1] = 0x00;
buffer[2] = 0x90;
/* 3 - 10 ( 8 byte ) OEM ID */
memcpy((uint8*)&buffer[3],"MSDOS5.0",sizeof(uint8) * 8);
/* 11 - 12 ( 2 byte ) sector bytes 512 */
buffer[11] = 0x00;
buffer[12] = 0x02;
/* 13 ( 1 byte) cluster / sector 32 */
//buffer[13] = 0x20;
buffer[13] = clusPsects;
/*14 -15 ( 2 byte) reserve sector */
*(uint16*)(&buffer[14]) = rsvSects;
/* 16 ( 1 byte) FATs */
buffer[16] = 0x02;
/* 17 -18 ( 2 byte) root items 512 */
buffer[17] = 0x00;
buffer[18] = 0x02;
/* 19 -20 ( 2 byte) small sectors 0 */
buffer[19] = 0x00;
buffer[20] = 0x00;
/* 21 ( 1 byte) */
buffer[21] = 0xF8;
/* 22 -23 ( 2 byte) fat/sector s (1G)0x00F4 (2G)0x01E8 */
// *(uint16*)(&buffer[22]) = sectPclus;
*(uint16*)(&buffer[22]) = sectPfat;
/*
buffer[22] = 0xF4;
buffer[23] = 0x00;
*/
/* 28 -31 ( 4 byte) reserve sectors */
*(uint32*)(&buffer[28]) = offset;
/*
buffer[28] = 0xF7;
buffer[29] = 0x00;
buffer[30] = 0x00;
buffer[31] = 0x00;
*/
/* big sectors (1G:0x001E7109 2G:0x003CE212) */
*(uint32*)(&buffer[32]) = allSects;
/*
buffer[32] = 0x09;
buffer[33] = 0x71;
buffer[34] = 0x1E;
buffer[35] = 0x00;
*/
/* 54 - 61 (8 byte) file system */
memcpy((uint8*)&buffer[54],"FAT16 ",8);
/* end flag */
buffer[510] = 0x55;
buffer[511] = 0xAA;
ret = disk_write(buffer,0 + offset,1);
if( ret != EC_SUCCESS )
{
return ret;
}
}
else
{
//sectPclus = *(uint16*)(&fs->win[22]);
sectPfat = *(uint16*)(&fs->win[22]);
rsvSects = *(uint16*)(&fs->win[14]);
}
memset(buffer,0,512);
/******************************** FAT1 */
buffer[0] = 0xF8;
buffer[1] = 0xFF;
buffer[2] = 0xFF;
buffer[3] = 0xFF;
ret = disk_write(buffer,rsvSects + offset,1);
if( ret != EC_SUCCESS )
{
return ret;
}
memset(buffer,0,512);
//for(i = 0 ; i < sectPclus-1 ; i++)
for(i = 0 ; i < sectPfat-1 ; i++)
{
ret = disk_write(buffer,i + rsvSects + 1 + offset,1);
if( ret != EC_SUCCESS )
{
return ret;
}
}
/****************************** End FAT1 */
/****************************** FAT2 */
buffer[0] = 0xF8;
buffer[1] = 0xFF;
buffer[2] = 0xFF;
buffer[3] = 0xFF;
//ret = disk_write(buffer,sectPclus + 1 + offset,1);
ret = disk_write(buffer,sectPfat + rsvSects + offset,1);
if( ret != EC_SUCCESS )
{
return ret;
}
memset(buffer,0,512);
//for(i = 0 ; i < sectPclus-1 ; i++)
for(i = 0 ; i < sectPfat-1 ; i++)
{
//ret = disk_write(buffer,i + sectPclus + 2 + offset,1);
ret = disk_write(buffer,i + sectPfat + rsvSects + 1 + offset,1);
if( ret != EC_SUCCESS )
{
return ret;
}
}
/****************************** End FAT2 */
/****************************** root */
memset(buffer,0,512);
for(i = 0 ; i < 32 ; i++)
{
//ret = disk_write(buffer,i + sectPclus * 2 + 1 + offset,1);
ret = disk_write(buffer,i + sectPfat * 2 + rsvSects + offset,1);
if( ret != EC_SUCCESS )
{
return ret;
}
}
/****************************** End root */
return ret;
}
#endif /* _FS_MINIMIZE == 0 */
#endif /* _FS_MINIMIZE <= 1 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -