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

📄 fs.c

📁 使用ISP1362芯片的USB_OTG参考设计源代码比较新的版本
💻 C
📖 第 1 页 / 共 5 页
字号:
		}

		
		writing_size	= (vpp->bytes_per_cluster < (remaining_size + data_offset_in_cluster)) ? (vpp->bytes_per_cluster - data_offset_in_cluster) : remaining_size;

		fs_data_copy( (fp->cluster_buffer_pointer) + data_offset_in_cluster, buffer_ptr, writing_size );

		fp->current_file_data_position	+= writing_size;
		remaining_size					-= writing_size;
		buffer_ptr						+= writing_size;
		(fp->file_info).size			+= writing_size;
	}

	return ( length - remaining_size );
}


static void flush_FILE_write_buffer( fs_FILE *fp )
{
	volume_param			*vpp;

	vpp				= fp->volume_param_ptr;

	if ( fp->buffered_cluster )
		storage_write_sector( fp->cluster_buffer_pointer, cluster_to_sector( fp->buffered_cluster ), vpp->sector_per_cluster );
	
	flush_FAT_cache( vpp );
	update_directory_entry( fp );
}


//////////
//////////	"rm" remove file
//////////
#define		FLAG_LEAVE_CURR_DIR		0x01
#define		FLAG_REMOVE_RECURSIVE	0x02
#define		FLAG_REMOVE_SCAN_ONLY	0x04

unsigned char fs_rm( char *path, unsigned char recursive )
{
	directory_entry		*dp;
	unsigned short		base_cluster;
	unsigned short		index;
	unsigned char		flags	= 0;
	unsigned char		err		= no_error;
	volume_param		*vpp;
	
	vpp				= &g_volume_parameter;

	flags	|= recursive ? FLAG_REMOVE_RECURSIVE : 0;
	
	if ( NULL == (dp	= find_file_entry( path, &base_cluster, &index )) )
		return ( FS_RM_DIRECTORY_ACCESS_ERR );

#if BIG_ENDIAN

	if ( vpp->current_directory_cluster == swap16( dp->cluster ) )
		flags	|= FLAG_LEAVE_CURR_DIR;
#else

	if ( vpp->current_directory_cluster == dp->cluster )
		flags	|= FLAG_LEAVE_CURR_DIR;
		
#endif

	if ( !recursive )
	{
		remove_this_entry( base_cluster, index, flags | FLAG_REMOVE_SCAN_ONLY, &err, 0 );
		
		if ( err )
			return ( err );
	}
	
	remove_this_entry( base_cluster, index, flags, &err, 0 );

	return ( err );
}


//////////
//////////	"mv" move file
//////////
unsigned short fs_mv( char *from, char *to )
{
	fs_FILE				*fp;
	directory_entry		d;
	directory_entry		*dp;
	unsigned short		parent_cluster;
	unsigned short		index;
	unsigned short		i;
//	volume_param		*vpp;
	
//	vpp				= &g_volume_parameter;

	//	get source file entry information

	if ( NULL == (dp	= find_entry( from )) )
		return ( FS_MV_SOURCE_NOT_FOUND );

	fs_data_copy( (unsigned char *)(&d), (unsigned char *)dp, sizeof( directory_entry ) );

	//	make new file entry

	if ( NULL == (fp	= fs_fopen( to, P | W | D )) )
		return ( FS_MV_CANNOT_OPEN_TARGET );
	
	fs_fclose( fp );	//	Just made a directory entry

	if ( NULL == (dp	= find_entry( to )) )
		return ( FS_MV_SOURCE_NOT_FOUND );

	for ( i = 11; i < sizeof( directory_entry ); i++ )
		*((unsigned char *)dp + i)	= *((unsigned char *)(&d) + i);

	write_back_directory_entry();

	//	erase old file entry

	if ( NULL == (dp	= find_entry( from )) )
		return ( FS_MV_SOURCE_NOT_FOUND );

	*((unsigned char *)dp)		= 0xE5;
	
	write_back_directory_entry();

	return ( no_error );
}


//////////
//////////	"mkdir" make directory
//////////
unsigned char fs_mkdir( char *path )
{
	fs_FILE				*fp;
	directory_entry		*dp;
	directory_entry		cur_d		=	{ ".       ", "   ", 0x10, {0,0,0,0,0,0,0,0,0,0}, 0, 0, 0, 0 };
	directory_entry		par_d		=	{ "..      ", "   ", 0x10, {0,0,0,0,0,0,0,0,0,0}, 0, 0, 0, 0 };
	directory_entry		null_d		=	{ {0,0,0,0,0,0,0,0},{0,0,0},0, {0,0,0,0,0,0,0,0,0,0},0,0,0,0 };
	unsigned short		i;
	volume_param		*vpp;
	
	vpp				= &g_volume_parameter;

	//	open directory as writing data into file

	if ( NULL == (fp	= fs_fopen( path, W | D )) )
		return ( error );
	
	//	write directory contents
	
#if BIG_ENDIAN

	cur_d.cluster		= swap16( fp->start_cluster );
	par_d.cluster		= (fp->directory_entry_cluster == 1) ? 0 : fp->directory_entry_cluster;
	par_d.cluster		= swap16( par_d.cluster );

#else

	cur_d.cluster		= fp->start_cluster;
	par_d.cluster		= (fp->directory_entry_cluster == 1) ? 0 : fp->directory_entry_cluster;

#endif

	set_time_for_directory_entry( &cur_d );
	set_time_for_directory_entry( &par_d );
	
	fs_write( fp, (unsigned char *)(&cur_d), sizeof( directory_entry ) );
	fs_write( fp, (unsigned char *)(&par_d), sizeof( directory_entry ) );

	for ( i = 2; i < (vpp->bytes_per_cluster / sizeof( directory_entry )); i++ )
		fs_write( fp, (unsigned char *)(&null_d), sizeof( directory_entry ) );

	//	close written file

	fs_fclose( fp );
	
	
	//	modify file entry

	if ( NULL == (dp	= find_entry( path )) )
		return ( error );

	dp->attributes	= 0x10;
	dp->size		= 0;

	write_back_directory_entry();

	return ( no_error );
}


//////////
//////////	"df" free disk clusters
//////////
void fs_df( unsigned short *available, unsigned short *total, unsigned short *cluster_size )
{
	unsigned short	i;
	
	volume_param	*vpp;

	vpp		= &g_volume_parameter;
	
	*cluster_size	= vpp->bytes_per_cluster;
	*total			= vpp->number_of_clasters;
	*available		= 0;
	
	for ( i = 2; i < (*total) + 2; i++ )
		if ( !read_FAT( i ) )
			(*available)++;
}


#ifdef SUPPORT_DISK_FORMAT

//////////
//////////	"format" format disk
//////////
void fs_format( void )
{
#define		BOOT	0x20
#define		HIDDEN	0x20
#define		CLTSZ	8
#define		ROOTDIRENT	512
#define		RESERVEDSEC	1
#define		N_OF_FAT	2


	MasterBootRecord	*mbrt;
	PartitionEntry		*pet;
	PartitionBootRecord	*pbrt;
	BoisParameterBlock	*bpbt;
	unsigned long		disk_size;
	unsigned long		block_size;
	unsigned long		total_sector;
	unsigned long		available_sector;
	unsigned long		data_sector_size;
	unsigned long		start_sector;

	unsigned short		n_of_cluster;
	unsigned short		FAT_sector_size;
	unsigned char		b[ 512 ];
	unsigned char		blank_str[ 12 ]	= "           ";
	unsigned short		i;


	//	BASIC calc	///////////////////////////////////////////////////
	total_sector	= gp_drive_parameter.last_LBA + 1;
	block_size		= gp_drive_parameter.block_length;
	disk_size		= total_sector * block_size;
	
	available_sector	= total_sector - (BOOT + HIDDEN + RESERVEDSEC + ((sizeof( directory_entry ) * ROOTDIRENT) / block_size));
	n_of_cluster		= (available_sector / CLTSZ) + 2;
	FAT_sector_size		= (((unsigned long)n_of_cluster * 2) / block_size) + 1;	//	(* 2) means the entry has 2 bytes

	data_sector_size	= available_sector - (unsigned long)(FAT_sector_size * N_OF_FAT);
	n_of_cluster		= (data_sector_size / CLTSZ) + 2;
	FAT_sector_size		= (((unsigned long)n_of_cluster * 2) / block_size) + 1;	//	(* 2) means the entry has 2 bytes

#if 0
	mprintf( LIGHTGRAY, CONTINUE, "\r\n" );
	mprintf( LIGHTGRAY, CONTINUE, "total_sector     0x%08lX (%9lu)\r\n", total_sector, total_sector );
	mprintf( LIGHTGRAY, CONTINUE, "block_size       0x%08lX (%9lu)\r\n", block_size, block_size );
	mprintf( LIGHTGRAY, CONTINUE, "disk_size        0x%08lX (%9lu)\r\n", disk_size, disk_size );
	mprintf( LIGHTGRAY, CONTINUE, "available_sector 0x%08lX (%9lu)\r\n", available_sector, available_sector );

	mprintf( LIGHTGRAY, CONTINUE, "n_of_cluster     0x%08X (%9u)\r\n", n_of_cluster, n_of_cluster );
	mprintf( LIGHTGRAY, CONTINUE, "FAT_sector_size  0x%08X (%9u)\r\n", FAT_sector_size, FAT_sector_size );
	mprintf( LIGHTGRAY, CONTINUE, "data_sector_size 0x%08lX (%9lu)\r\n", data_sector_size, data_sector_size );
#endif

	//	MBR		////////////////////////////////////////////////////////

	for ( i = 0; i < 512; i++ )
		*(b + i)	= 0;
	
	mbrt	= (MasterBootRecord *)b;
	mbrt->Signature_Word	= 0xAA55;
	
	pet		= &((mbrt->partition)[ 0 ]);

	pet->DefaultBootPartition		= 0x80;
	pet->StartHead					= 1;
	pet->StartSector				= 1;
	pet->StartCylinder				= 0;				
	pet->PartitionType				= (disk_size >> 25) ? 6 : 4;
	pet->EndHead					= (total_sector >> 14) & 0xFF;
	pet->EndSector					= (total_sector >>  7) & 0x7F;
	pet->EndCylinder				= (total_sector >>  0) & 0x7F;
	pet->StartLBASector				= BOOT;
	pet->NumSectors					= total_sector;

	start_sector	= 0;
	storage_write_sector( b, start_sector, 1 );


	//	PBR		//////////////////////////////////////
	for ( i = 0; i < 512; i++ )
		*(b + i)	= 0;
	
	pbrt	= (PartitionBootRecord *)b;
	bpbt	= &(pbrt->BPB);
	
	(pbrt->JMP_instruction)[ 0 ]	= 0xE9;
	(pbrt->JMP_instruction)[ 1 ]	= 0;
	(pbrt->JMP_instruction)[ 2 ]	= 0;
	fs_data_copy( pbrt->OEM_name_version, blank_str, 8 );
	pbrt->DriveNumber				= 0;
	pbrt->Reserved					= 0;
	pbrt->ExtBootSignature			= 0;
	pbrt->Volume_ID					= 0;
	fs_data_copy( pbrt->VolumeLabel, blank_str, 11 );
	(pbrt->VolumeLabel)[ 0 ]		= 'W';
	(pbrt->VolumeLabel)[ 1 ]		= 'A';
	(pbrt->VolumeLabel)[ 2 ]		= 'S';
	(pbrt->VolumeLabel)[ 3 ]		= 'A';
	(pbrt->VolumeLabel)[ 4 ]		= 'B';
	(pbrt->VolumeLabel)[ 5 ]		= 'I';
	(pbrt->VolumeLabel)[ 6 ]		= '-';
	(pbrt->VolumeLabel)[ 7 ]		= 'D';
	(pbrt->VolumeLabel)[ 8 ]		= 'I';
	(pbrt->VolumeLabel)[ 9 ]		= 'S';
	(pbrt->VolumeLabel)[ 10]		= 'K';
	fs_data_copy( pbrt->FileSysType, blank_str,  8 );
	(pbrt->FileSysType)[ 0 ]		= 'F';
	(pbrt->FileSysType)[ 1 ]		= 'A';
	(pbrt->FileSysType)[ 2 ]		= 'T';
	(pbrt->FileSysType)[ 3 ]		= '1';
	(pbrt->FileSysType)[ 4 ]		= '6';
	*((unsigned short *)(b + 510))	= 0xAA55;

	bpbt->BytesPerSector			= block_size;
	bpbt->SectorsPerClustor			= CLTSZ;
	bpbt->ReservedSectors			= RESERVEDSEC;
	bpbt->NumFATs					= N_OF_FAT;
	bpbt->RootDirEntries			= ROOTDIRENT;
	
	if (disk_size >> 25)
	{
		bpbt->TotalSectors			= 0;
		bpbt->HugeSectors			= data_sector_size;
	}
	else
	{
		bpbt->TotalSectors			= (unsigned short)data_sector_size;
		bpbt->HugeSectors			= 0;
	}
	
	bpbt->MediaIDByte				= 0xF8;
	bpbt->NumFATSectors				= FAT_sector_size;
	bpbt->SectorsPerTrack			= pet->EndSector;
	bpbt->NumHeads					= pet->EndHead;
	bpbt->HiddenSectors				= HIDDEN;
	
	start_sector	= BOOT;
	storage_write_sector( b, start_sector, 1 );
	

	//	FAT1	//////////////////////////////////////
	for ( i = 0; i < 512; i++ )
		*(b + i)	= 0;
	
	start_sector	+= RESERVEDSEC;
	i	= 1;
	while ( i < FAT_sector_size )
	{
		storage_write_sector( b, start_sector + i, 1 );
		i++;
	}
	*(((unsigned short *)b) + 0)	= 0xFFF8;
	*(((unsigned short *)b) + 1)	= 0xFFFF;

	storage_write_sector( b, start_sector, 1 );


	//	FAT2	//////////////////////////////////////
	for ( i = 0; i < 512; i++ )
		*(b + i)	= 0;
	
	start_sector	+= FAT_sector_size;
	i	= 1;
	while ( i < FAT_sector_size )
	{
		storage_write_sector( b, start_sector + i, 1 );
		i++;
	}
	*(((unsigned short *)b) + 0)	= 0xFFF8;
	*(((unsigned short *)b) + 1)	= 0xFFFF;

	storage_write_sector( b, start_sector, 1 );


	//	ROOT DIR	//////////////////////////////////
	for ( i = 0; i < 512; i++ )
		*(b + i)	= 0;
	
	start_sector	+= FAT_sector_size;

	for ( i = 0; i < (ROOTDIRENT * sizeof( directory_entry )) / block_size; i++ )
		storage_write_sector( b, start_sector++, 1 );
}

#endif

unsigned long fs_cluster_to_sector( unsigned short c )
{
	return ( cluster_to_sector( c ) );
}


unsigned short fs_read_FAT( unsigned short current_cluster )
{
	return ( read_FAT( current_cluster ) );
}




/*
==============================================================================
==============================================================================
====	Public functions for file system access
====		Functions for DRIVER side
==============================================================================
==============================================================================
*/

volume_param *fs_volume_open( void )
{
	volume_param	*vpp;
	char			fs_name[ 9 ];
	unsigned char	*buffer_ptr;
	unsigned char	partition;		//	##	Version 1.2c
	unsigned char	fs_type;
	unsigned long	start_lba;
	unsigned char	i;

	//	Make volume instance
	//	In this version, it is allocated as static

	vpp				= &g_volume_parameter;


	//	Allocate a temporary buffer for sector size
	//	At this moment, the cluster size is unknown. So this temporary buffer will be freed 
	//	after getting cluster size information from boot block in the volume.

	if ( NULL == (buffer_ptr	= (unsigned char *)malloc( gp_drive_parameter.block_length )) )
	{
		mprintf( LIGHTGRAY, CONTINUE, "error : File system init (malloc) failed\r\n" );
		return ( NULL );
	}
	

	//	Read sector LBA=0 (MasterBootRecord : MBR) to get partition information (Partition entries).
	//	This version only support single partition.
	//	MBR : PC card standard section 3.2 and 3.2.4 (include "Partition entry" information)
	//	Also, see http://www.microsoft.com/hwdev/download/hardware/FATGEN103.doc
		
	storage_read_sector( buffer_ptr, 0, 1 );
	
	
	//	##	Version 1.2c (from here)
	//
	//		When the storage volume does not have partition table, it should be 
	//		handled as a volume without partition table. 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -