⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 SD卡FAT文件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
		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 + -