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

📄 osfile.c

📁 ucos-II+移植到arm+s3c2410的全套代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*----------------------------------------------------------------------------------
    #说明: 王晓君写的文件系统,(Fat12格式)
    #接口函数
	----------------------------------  Bug  --------------------------------------
	2003-6-12	全局变量Pre_Block、Current_Block未作处理,应该替换成
				局部变量,防止多任务冲突;

	----------------------------------  TODO list  --------------------------------------

	----------------------------------修正--------------------------------------
	2004-1-8	修改了文件分区表的格式,格式化的时候需要新的bootloader配合

	2003-6-13	OpenOSFile函数中引入Create模式,对于文件的Write操作,如
				果没有Create标志则只能替换已有的同名文件,如果有
				Create标志,则只能创建新的文件,如果有同名文件,
				在返回NULL

	2003-6-13	DeleteOSFile函数通过测试

	2003-6-13	对于Root表缓冲处理,减少Flash的磨损,只有在Write模式
				写入文件、创建root入口以及删除文件的时候写入Flash,
				其他的操作都通过内存。

			###可能的问题:文件系统中Fat和root表都做缓冲处理,在写入
				Flash的一瞬间系统掉电,就会造成不可预测的结果,
				可能导致整个文件系统的破坏。

	2003-6-13	对于文件名不区分大小写,存入的时候按照用户
				给定的名字保存,查找和比较的时候,不区分大小写
				
	2003-6-13	支持8.3格式的文件,同时兼容以前的11字符模式的 
				文件名输入

	2003-6-12	列出文件

	2003-6-12	可以写入大于一个Cluster的文件;DeleteOSFile函数未测试;
				把FTA分配表在内存中专门建立一个缓冲区,在
				CloseOSFile、DeleteOSFIle的时候对Flash进行同步
				
																			by threewater
	2003-6-11	修正CloseOSFile的时候更新分区表,写入文件长度 by threewater
	------------------------------------------------------------------------------
	
-----------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------
//王晓君进行第二次修订所做修改,修改后版本号2.0
	2003-9-16
*/

#include "../ucos-ii/includes.h"               /* uC/OS interface */
#include "../inc/sys/lib.h"
#include "../inc/drivers.h"
#include "OSFile.h"
#include <stdio.h>
#include <string.h>


#undef DPRINTK

#undef DEBUG
//#define DEBUG
#ifdef DEBUG
#define DPRINTK			LCD_printf
#else
#define DPRINTK			printfNULL
#endif

#if (USE_YAFFS==0)

#define Erase_Cluster(n)		Erase_Block(n)

//文件分配表的大小(byte)
#define FAT_TABLE_SIZE	(TotalSector*3/2/SecPerClus-3)

static unsigned int TotalCluster,BootSector,RsdSector,SectorofFatSize,TotalCapacity,RootEntry,SecPerClus,TotalSector,BytesPerSec,FirstDataSec;
static unsigned char FAT_TYPE;

__align(4) static unsigned char databuff[0x200];
//unsigned char Buffer[Block_Size];


//U32 Pre_Block,Current_Block;


//unsigned char FileSystemFAT[16*1024]={0,};
__align(4) static unsigned char FileSystemFAT[1024]={0,};


typedef struct _FileRoot{
	char filename[11];	//0-10
	char Attribute;		//11		Attribute
	char pad[10];			//12-21
	U16 time;			//22,23	MSB??
	U16 date;			//24,25	MSB??
	U16 cluster;			//26,27	first cluster	LSB
	U32 filelength;		//28-31	file length 		LSB
}FileRoot,*PFileRoot;

__align(4) static FileRoot FileSystemRoot[FILESYS_MAX_BUFFER_FILEROOT]={0};

static OS_MEM *pFileMem;
__align(4) static INT8U FileMemPart[10][sizeof(OSFILE)];

static U8 BPB_Data [512]={
				0xeb,0x3c,0x90,//	Offset_U8_BS_jmpBoot		0
				'U','P','-','T','E','C','H',' ',// Offset_U8_BS_OEMName		3
				LOWBYTE(BytesPerSector),HIGHBYTE(BytesPerSector),	// Offset_U16_BPB_BytsPerSec	11	//Count of bytes per sector. This value may take on only the  //
				//512									//following values: 512, 1024, 2048 or 4096. If maximum       //
														//compatibility is desired, only the value 512 should be used.//
				64,// Offset_U8_BPB_SecPerClus	13	//Number of sectors per allocation unit. This value must be a //
														//power of 2 that is greater than 0. The legal values are 1,  //
														//	2, 4, 8, 16, 32, 64,and 128.                                //
				LOWBYTE(RSD_Sector),HIGHBYTE(RSD_Sector),// Offset_U16_BPB_RsvdSecCnt	14	//Number of reserved sectors in the Reserved region of the    //
														//volume starting at the first sector of the volume.For FAT32 //
														//volumes, this value is typically 32.                        //
				0x02,// Offset_U8_BPB_NumFATs		16	//The count of FAT data structures on the volume.             //
				LOWBYTE(Directory_Number),HIGHBYTE(Directory_Number),// Offset_U16_BPB_RootEntCnt	17	//Is only useful for FAT12 and FAT16 volumes.                 //
				//										//For FAT32 volumes,this field must be set to 0.              //
				//通过调整文件项为03b0,从而使数据扇区刚好从Block2Sector0开始
				LOWBYTE(Total_Sector),HIGHBYTE(Total_Sector),// Offset_U16_BPB_TotSec16		19	//For FAT12 and FAT16 volumes, this field contains the sector //
														//count, and BPB_TotSec32 is 0 if the total sector count fits //
														//(is less than 0x10000).                                     //
				0xf8,// Offset_U8_BPB_Media			21	//0xF8 is the standard value for fixed(non-removable) media.  //
														//For removable media, 0xF0 is frequently used.               //
				LOWBYTE(FAT_NUM),HIGHBYTE(FAT_NUM),// Offset_U16_BPB_FATSz16		22	//number of sectors in FAT

				0x00,0x00,// Offset_U16_BPB_SecPerTrk	24	//Sectors per track for interrupt 0x13. This field is only    //
														//relevant for media that have a geometry (volume is broken   //
														//down into tracks by multiple heads and cylinders) and are   //
														//visible on interrupt 0x13.This field contains the           //
														//"sectors per track" geometry value.                         //
				0x00,0x00,// Offset_U16_BPB_NumHeads		26	//Number of heads for interrupt 0x13. This field is relevant  //
														//as discussed earlier for BPB_SecPerTrk.                     //
				0x01,0x00,0x00,0x00,// Offset_U32_BPB_HiddSec		28	//Count of hidden sectors preceding the partition that        //
														//contains this FAT volume.                                   //
				0x00,0x00,0x00,0x00,// Offset_U32_BPB_TotSec32		32	//This field is the new 32-bit total count of sectors on the  //
														//volume. This count includes the count of all sectors in all //
														//four regions of the volume. This field can be 0; if it is 0,//
														//then BPB_TotSec16 must be non-zero. For FAT32 volumes, this //
														//field must be non-zero. For FAT12/FAT16 volumes, this field //
														//contains the sector count if BPB_TotSec16 is 0 (count is    //
														//greater than or equal to 0x10000).//
				0x00,// Offset_U8_BS_DrvNum		36	//This field is the FAT32 32-bit count of sectors occupied by //
					//根据该值得到FAT的大小//				//ONE FAT. BPB_FATSz16 must be 0.                             //
					
				0x00,// Offset_U8_BS_Reserved		37	//    Bits 0-3 -- Zero-based number of active FAT.Only valid  //
														//                if mirroring is disabled.                   //
														//    Bits 4-6 -- Reserved.                                   //
														//    Bit 7    -- 0 means the FAT is mirrored at runtime into //
														//                  all FATs.                                 //
														//             -- 1 means only one FAT is active;it is the one//
														//                  referenced in bits 0-3.                   //
														//    Bits 8-15 -- Reserved.                                  //
				0x29,// Offset_U8_BS_BootSig		38	//High byte is major revision number.                         //
														//Low byte is minor revision number.                          //
				'N','A','M','E',// Offset_U32_BS_VolID		39	//This is set to the cluster number of the first cluster of   //
					//根据该值得到ROOT的地址//				//the root directory, usually 2 but not required to be 2.     //
					
				'N','O',' ','N','A','M','E',' ',' ',' ',' ',// Offset_U2048_BS_VolLab		43	//Sector number of FSINFO structure in the reserved area of   //
														//the FAT32 volume.Usually 1.                                 //
				'F','A','T','1','2',' ',' ',' ',// Offset_U256_BS_FilSysType	54	//If non-zero, indicates the sector number in the reserved    //
														//area of the volume of a copy of the boot record.            //
				//Executable Code
				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,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,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,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,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,		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,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,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,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,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,		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,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,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,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,0,		0,0,0,0,0,		0,0,0,0,0,		0,0,0,0,0,		0,0,0,0,

				0x00,//active partion
				0x00,//head
				0x00,//partion begin
				0x00,//cylinder
				0x06,//is partion used
				0x00,//end head
				0x00,//partion end 
				0x00,//end cylinder
				0x00,0x00,0x00,0x00,
				0x00,0x80,0x00,0x00,//fist partion

				0,0,0,0,0,		0,0,0,0,0,		0,0,0,0,0,		0,//second partion
				0,0,0,0,0,		0,0,0,0,0,		0,0,0,0,0,		0,//third partion
				0,0,0,0,0,		0,0,0,0,0,		0,0,0,0,0,		0,//forth partion

				0x55,0xAA	// Offset_U16_Signature		510	//0x55AA           

				};
//////////////////////////////////////////////////////////////////////////////////////////
int initOSFile(void);
OSFILE* OpenOSFile(char filename[], U32 OpenMode);
U32 ReadOSFile(OSFILE* pfile,U8* ReadBuffer, U32 nReadbyte);
U32 LineReadOSFile(OSFILE* pfile, char str[]);	//读取指定文件的一行
U32 SeekOSFile(OSFILE* pfile ,U32 nCurPos);
U32 GetPosOSFile(OSFILE* pfile);
U8 DeleteOSFile(char filename[]);
U8 RenameOSFile(char fromname[], char toname[]);
U8 CopyOSFile(char srcfile[], char decfile[]);
int FindOSFile(char filename [ ]);
U8 WriteOSFile(OSFILE* pfile,U8* WriteBuffer, U32 nWriteyte);
int CloseOSFile(OSFILE* pfile);
//得到指定位置的文件名(包括扩展名),文件位置自动下移
U8 GetNextFileName(U32 *filepos,char filename[]);
//列出当前位置开始第一个指定扩展名的文件,如果没有,则返回FALSE
U8 ListNextFileName(U32 *filepos, char FileExName[],char filename[]);

void  Write2Flash(unsigned int block,unsigned int StSector,unsigned int EnSector,unsigned char* ClusterBuf);

int Init_FAT_Info(int AutoFormat);

unsigned int NextCluster(unsigned int CurrentCluster);
unsigned int AllocateCluster(unsigned int CurrentCluster);

void ReadFAT2Mem(void);
void ReadFileRoot2Mem(void);

/********************************************************************/
/*如果Flash的MBR和Fat16结构受损,则调用此函数可以恢*/	
/*复																*/
/********************************************************************/
int Format_Fat12Media(void);
void WriteMBR2Flash(void);
void CreatFAT16(void);
void CreatDirectoryEntry(void);


/********************************************************************/
/*测试文件系统功能时,使用以下几个函数进行		*/	
/********************************************************************/

void TestFAT_COPY(char filename1[],char filename2[]);
void TestFAT_CREATE(char filename[]);
void TestFAT_DELETE(char filename[]);
void TestFAT_READ(char filename[]);


/*################################################################*/
//以下代码完成介质的格式化,当介质出现读取故障时,可调用
//Format_Fat12Media函数实现对16M介质的格式化

//数据结构与全局变量定义

//写入BPB
void WriteMBR2Flash(void)
{
	WritePage(Begin_Cluster, BPB_Sector, BPB_Data);
}
//创建FAT16
void CreatFAT12(void)
{
	U8 FAT[512]={0,};

	memset(FAT,0,sizeof(FAT));
	
	//disk type lower byte is equal to Offset_U8_BPB_Media
	FAT[0] = 0xf8;
	FAT[1] = 0xff;//system occupied the first cluster
	FAT[2] = 0xff;
	FAT[3] = 0x7f;
	
	if(NandFlashOK()){
		WritePage(Begin_Cluster,Fat_Sector,FAT);	//Sector 1 of Fat16
		WritePage(Begin_Cluster,Fat_Sector+2,FAT);	//Sector 1 of Fat16
		FAT[0]=FAT[1]=FAT[2]=FAT[3]=0x00;
		WritePage(Begin_Cluster,Fat_Sector+1,FAT);	//Sector 2 of Fat16
		WritePage(Begin_Cluster,Fat_Sector+3,FAT);	//Sector 2 of Fat16
		}
	else
		DPRINTK("No Flash Found\n");

	ReadFAT2Mem();
}

//创建目录项
void CreatDirectoryEntry(void)
{
	static U8 Directory_Enties[512]={0,};
	U32 i;

	for(i=0;i<0x3b;i++) {//总共支持3b0个根目录项,共占用0x3b个扇区
		WritePage(Begin_Cluster+(i+Directory_BeginSector)/32,(Directory_BeginSector+i)%32,Directory_Enties);
	}	

	ReadFileRoot2Mem();
}


/***************************************************************************\
*	介质的格式化,当介质出现读取故障时,可调用			*
*	Format_Fat12Media函数实现对16M介质的格式化					*
\***************************************************************************/
int Format_Fat12Media(void)
{	

	printk("\nFormat the Media to FAT,Please Waiting...\n");

	Erase_Cluster(Begin_Cluster);
	Erase_Cluster(Begin_Cluster+1);
	
	WriteMBR2Flash();
	Init_FAT_Info(FALSE);
	
	CreatFAT12();
	CreatDirectoryEntry();
	
	printk ("Format Finished!\n");

	return TRUE;
}

/****************************************
	按照扇区(Page)写入Flash,
	参数:
			block 表示Nand Flash中Block的位置
			StSector 表示Nand Flash中写入的起始扇区
			EnSector 表示Nand Flash中写入的结束扇区(写入数据包含该扇区)
			ClusterBuf 表示写入数据,以Block的大小为单位对齐
			
*****************************************/

void  Write2Flash(unsigned int block,unsigned int StSector,unsigned int EnSector,unsigned char* ClusterBuf)
{
	unsigned int i;
	for(i=0;i<StSector;i++){
		ReadPage(block,i,ClusterBuf+i*NandPageSize);	//前前面的扇区读出
	}
	for(i=EnSector+1;i<32;i++){
		ReadPage(block,i,ClusterBuf+i*NandPageSize);	//前前面的扇区读出
	}
	Erase_Cluster(block);
	for(i=0;i<32;i++){
		WritePage(block,i,ClusterBuf+i*NandPageSize);	//前前面的扇区读出
	}
}


//add by threewater ------>
/****************************************
	读取FAT分区表到内存的缓冲区中
*****************************************/
void ReadFAT2Mem()
{
	int i;

	for(i=0;i<SectorofFatSize;i++)
//	for(i=0;i<2;i++)//16M的介质只有两个扇区1024字节的分区表空间-->by frank
		ReadPage(Begin_Cluster+(BootSector+RsdSector+i)/SecPerClus,
							(BootSector+RsdSector+i)%SecPerClus,FileSystemFAT+i*512);
	
}

/****************************************
	写入FAT分区表到内存的缓冲区中
*****************************************/
static void WriteFATFromMem()
{
	INT8U err;
	OSFILE *pfile;
	unsigned int StSector=(BootSector+RsdSector)%SecPerClus;//StSector并未得到引用

	pfile=(OSFILE*)OSMemGet(pFileMem,&err);//由于需要缓冲区,故创建一个指针

	memcpy(pfile->Buffer+StSector*512,FileSystemFAT,512*SectorofFatSize);
	Write2Flash(Begin_Cluster+(BootSector+RsdSector)/SecPerClus, 
				StSector, StSector+SectorofFatSize-1, pfile->Buffer);

	OSMemPut(pFileMem, pfile);

}

/****************************************
	从FAT分区表缓冲区中删除一个文件的链表
	参数Cluster表示文件的起始位置(Cluster)

⌨️ 快捷键说明

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