www.pudn.com > GOS.rar > FILE.C


//**************************************************************************************** 
//** 文件名:File.c 
 
//** Copyright (c) 2002 Hard&SoftMcuStudio 
 
//** 创建人:Hard&SoftMcuStudio 
 
//** 日期:2002.06.27 
 
//** 描述:Flash file systems 
//** 
//** 版本:1.0 
//************************************************************************************** 
#include  
#include "file.h" 
INT8U aucHZK[267616]; 
INT8U aucEK[4096]; 
 
 
//Nand Flash Operation Routine 
INT8U Erase_Block(INT32U ulBlock); 
void ReadPage(INT32U ulBlock,INT32U ulPage,INT8U *pucPageBuf); 
INT8U WritePage(INT32U ulBlock,INT32U ulPage,INT8U *pucPageBuf); 
INT32U seek_blank_block(INT32U StartBlock); 
void creat_file(INT8U *pucFileInfo); 
void close_file(void); 
void write_file(INT8U ucEndFlag,INT8U *pucBlockBuf); 
INT32U find_file(INT8U *pucFileInfo); 
INT32U comp_filename(INT8U *pucString1,INT8U *pucString2); 
INT8U read_file(INT8U *pucBlockBuf,INT32 lByteNum); 
static void LoadFont(void); 
 
/*Download and format is OK!*/ 
/***************************************************************/ 
/*                       FAT表说明                             */ 
/*(1)KM29U128T 共有1024个Block/Cluster,1Block=32Page           */ 
/*                                  或 1Cluster=32Sector       */ 
/*(2)1Page/Sector=512B,1Block/Cluster=16KB                     */ 
/*                                 因此共有空间1024*16KB=16MB  */ 
/*(3)RootDir信息占用Block0,用户数据存放于Block1~1023          */ 
/*                    可用空间共为1023*32=32736Sector=15.98MB  */ 
/*(4)FAT信息存放在每个Block的首页(Page)的独立区,该区共有16Bytes*/ 
/*   这16Bytes的含义如下:                                     */ 
/*   Offset[0]->该Block的使用情况                              */ 
/*              0xFF     :unused Block                         */ 
/*              0x00     :bad Block                            */ 
/*              0x01~0xFE:used Block                           */ 
/*   Offset[ 1~ 7]->保留字节(对其中的数据无任何要求)           */ 
/*   Offset[ 8~11]->Pre Block(MSB)                             */ 
/*                  若当前Block是FirstBlock,则该值为其本身     */ 
/*   Offset[12~15]->Next Block(MSB)                            */ 
/*                  若当前块为LastBlock,则该值为0xFFFF        */ 
/***************************************************************/ 
/*                     Root Directory 记录格式                   */ 
/*                     Offset[ 0~10]->file name                   */ 
/*                     Offset[11~25]->file attribute              */ 
/*                     Offset[26~27]->file starting cluster(LSB)  */ 
/*                     Offset[28~31]->file size in byte(LSB)      */ 
/*暂存Root Directory数据,每条记录为32Byte,因此共可有512条记录*/ 
INT8U root_buf[512][32]; 
INT32U pre_block; 
INT32U current_block; 
INT8U Block_1Page_Buf[528];	//Block首页Buffer 
INT8U Page_Buf[528]; 
 
//------------------------------------------------------------------ 
// 函数名:INT32U Seek_blank_block(void) 
// 输 入: 开始Block号 
// 输 出: 空的Block号 
// 功能描述:寻找介于StartBlock与EndBlock之间的第一个Blank Block 
// 全局变量:Block_1Page_Buf 
//------------------------------------------------------------------ 
INT32U seek_blank_block(INT32U StartBlock) 
{ 
	INT32U ulBlockNum; 
	 
	ulBlockNum=StartBlock; 
	ReadPage(ulBlockNum,0,Block_1Page_Buf); 
	while(Block_1Page_Buf[512]!=UNUSED_MARK) 
           ReadPage(++ulBlockNum,0,Block_1Page_Buf); 
	return(ulBlockNum); 
} 
//------------------------------------------------------------------ 
// 函数名:void creat_file(INT8U *pucFileInfo) 
// 输 入: INT8U *pucFileInfo --包含文件名和文件长度 
// 输 出: Null 
// 功能描述:将Root Directory数据读入root_buf[],并在root_buf中修改之 
// 全局变量:root_buf 
//------------------------------------------------------------------ 
void creat_file(INT8U *pucFileInfo) 
{ 
 
	INT32U ulPageNum,Pointer,i; 
 
	for(ulPageNum=0;ulPageNum<32;ulPageNum++) 
	{ 
		/*将Root information读到root_buf中*/ 
		ReadPage(Root_Cluster,ulPageNum,Page_Buf); 
		for(Pointer=0;Pointer<512;Pointer++) 
		{ 
			root_buf[ulPageNum*16+Pointer/32][Pointer%32]=Page_Buf[Pointer]; 
		} 
	} 
		 
	/*在root_buf寻找空表项*/ 
	Pointer=0; 
	while(root_buf[Pointer][0]!=0x00) 
	{ 
		Pointer++; 
	} 
	 
	/*copy the file name and file size*/ 
	for(i=0;i<32;i++) 
		root_buf[Pointer][i]= *pucFileInfo++; 
	 
	current_block=seek_blank_block(Start_Cluster); 
	pre_block=current_block; 
	 
	root_buf[Pointer][26]=(INT8U)(current_block%256);	//store LSB 
	root_buf[Pointer][27]=(INT8U)(current_block/256);	//store MSB 
//	disp_root();	 
} 
//------------------------------------------------------------------ 
// 函数名:void close_file(void) 
// 输 入: Null 
// 输 出: Null 
// 功能描述:将root_buf中的数据写回Root Directory所处的Block(即Block0) 
// 全局变量:Page_Buf 
//------------------------------------------------------------------ 
void close_file(void) 
{ 
 
	INT32U ulPageNum,Pointer; 
	 
	/*Erase Root_information Cluster*/ 
	Erase_Block(0); 
	 
	/*将root_buf中的数据逐页写入*/ 
	for(ulPageNum=0;ulPageNum<32;ulPageNum++) 
	{ 
		for(Pointer=0;Pointer<512;Pointer++) 
		{ 
			Page_Buf[Pointer]=root_buf[ulPageNum*16+Pointer/32][Pointer%32]; 
		} 
		/*独立区以0xFF填充*/ 
		for(Pointer=512;Pointer<(512+16);Pointer++) 
		{ 
			Page_Buf[Pointer]=0xFF; 
		} 
		WritePage(Root_Cluster,ulPageNum,&(Page_Buf[0])); 
	} 
} 
//------------------------------------------------------------------ 
// 函数名:void write_file(INT8U ucEndFlag,INT8U *pucBlockBuf) 
// 输 入: INT8U ucEndFlag--1 End 
//					   --0 Not End 
//          INT8U *pucBlockBuf--块buffer 
// 输 出: Null 
// 功能描述:将pucBlockBuf中的数据写到1个Block中 
// 全局变量:Page_Buf, pre_block, current_block 
//------------------------------------------------------------------ 
void write_file(INT8U ucEndFlag,INT8U *pucBlockBuf) 
{ 
	INT32U ulNextBlock,ulPageNum,Pointer; 
 
//Uart_Printf("\nWrite data,Current block is:%d",current_block); 
	if(ucEndFlag)	//若为文件的最后一个Block,则LastBlock=0xFFFF 
		ulNextBlock=LAST_BLOCK; 
	else 
		ulNextBlock=seek_blank_block(current_block+1); 
 
	//write USED mark// 
	Page_Buf[512+0]=0x01; 
 
	//write pre_block// 
	Page_Buf[512+8]=0x00; 
	Page_Buf[512+9]=0x00; 
	Page_Buf[512+10]=pre_block/256; 
	Page_Buf[512+11]=pre_block%256; 
 
	//write ulNextBlock// 
	Page_Buf[512+12]=0x00; 
	Page_Buf[512+13]=0x00; 
	Page_Buf[512+14]=ulNextBlock/256; 
	Page_Buf[512+15]=ulNextBlock%256; 
																 
	for(ulPageNum=0;ulPageNum<32;ulPageNum++) 
	{ 
		for(Pointer=0;Pointer<512;Pointer++) 
		{ 
			Page_Buf[Pointer]=*pucBlockBuf; 
			//*pucBlockBuf=0xff; 
			pucBlockBuf++; 
		} 
		WritePage(current_block,ulPageNum,Page_Buf);					 
	} 
	pre_block=current_block; 
	current_block=ulNextBlock;		 
} 
//------------------------------------------------------------------ 
// 函数名:INT8U read_file(INT8U *pucBlockBuf,INT32 lByteNum) 
// 输 入: INT8U *pucBlockBuf	--	Block Buffer 
//          INT32U lByteNum --块buffer 
// 输 出: Null 
// 功能描述:从当前块读取lByteNum个块到pucBlockBuf 
// 全局变量:Page_Buf 
//------------------------------------------------------------------ 
INT8U read_file(INT8U *pucBlockBuf,INT32 lByteNum) 
{	 
	INT32U ulPageNum,Pointer; 
//Uart_Printf("\nRead data,Current block is:%d",current_block); 
	for(ulPageNum=0;ulPageNum<32;ulPageNum++) 
	{ 
		ReadPage(current_block,ulPageNum,Page_Buf);		 
		for(Pointer=0;Pointer<512;Pointer++) 
		{ 
			*pucBlockBuf=Page_Buf[Pointer]; 
			pucBlockBuf++; 
			lByteNum--; 
			if(lByteNum==0) 
			{ 
				current_block=Page_Buf[512+14]*256+Page_Buf[512+15]; 
				return 1; 
			} 
		} 
	} 
	current_block=Page_Buf[512+14]*256+Page_Buf[512+15]; 
	return 1; 
} 
//------------------------------------------------------------------ 
// 函数名:INT32U comp_filename(INT8U *pucString1,INT8U *pucString2) 
// 输 入: INT8U *pucString1 
//          INT8U *pucString2 
// 输 出: 0--相同 
//		1--不相同 
// 功能描述:比较两个文件名 
// 全局变量:Null 
//------------------------------------------------------------------ 
INT32U comp_filename(INT8U *pucString1,INT8U *pucString2) 
{ 
	INT32U ulDiffNum=0; 
	INT32U ulNamePointer; 
 
	for(ulNamePointer=0;ulNamePointer<11;ulNamePointer++) 
	{ 
		if(pucString1[ulNamePointer]!=pucString2[ulNamePointer]) 
			ulDiffNum++; 
	} 
	return (ulDiffNum); 
} 
//------------------------------------------------------------------ 
// 函数名:INT32U find_file(INT8U *pucFileName) 
// 输 入: INT8U *pucFileName --文件名 
// 输 出: 该文件在Root information区中的位置,即第几条记录 
// 功能描述:查找文件在root表的位置 
// 全局变量:root_buf 
//------------------------------------------------------------------ 
INT32U find_file(INT8U *pucFileName) 
{ 
	INT32U ulPageNum,Pointer; 
 
	//read the root information// 
	for(ulPageNum=0;ulPageNum<32;ulPageNum++) 
	{ 
		//将Root information读到root_buf中// 
		ReadPage(Root_Cluster,ulPageNum,Page_Buf); 
		for(Pointer=0;Pointer<512;Pointer++) 
		{ 
			root_buf[ulPageNum*16+Pointer/32][Pointer%32]=Page_Buf[Pointer]; 
		} 
	} 
 
	for(Pointer=0;Pointer<512;Pointer++) 
	{ 
		if(comp_filename(&root_buf[Pointer][0],pucFileName)==0) 
		break; 
	} 
	return(Pointer); 
 
} 
//------------------------------------------------------------------ 
// 函数名:INT32U FlashWriteFile(INT8U *pucFileName, INT8U *pucFileBuf, INT32U ulFileLen, INT32U ulFlag) 
// 输 入: INT8U *pucFileName --文件名 
//		INT8U *pucFileBuf--缓冲区指针 
//		INT32U ulFileLen--长度 
//		INT32U ulFlag--Not really used now 
// 输 出: 1--成功 
//		0--失败,该文件已经存在 
// 功能描述:将缓冲区ulFileLen长的一段写入文件 
// 全局变量:Null 
//------------------------------------------------------------------ 
INT32U FlashWriteFile(INT8U *pucFileName, INT8U *pucFileBuf, INT32U ulFileLen, INT32U ulFlag) 
{ 
	INT32U i,ulBlockNum,ulRootLocation; 
	INT8U pucFileInfo[32]; 
	ulRootLocation=find_file(pucFileName); 
	if(ulRootLocation!=FILE_NO_FOUND) 
		return 0;				//This file is already exist! 
	else 
	{ 
		ulBlockNum=ulFileLen/(16*1024); 
		if((ulFileLen%(16*1024))!=0) 
			ulBlockNum++; 
		for(i=0;i<32;i++)	//copy the file name 
		{ 
			pucFileInfo[i]=*pucFileName++; 
		} 
		pucFileInfo[31]=ulFileLen/16777216;	ulFileLen%=16777216; 
		pucFileInfo[30]=ulFileLen/65536;	ulFileLen%=65536; 
		pucFileInfo[29]=ulFileLen/256;		ulFileLen%=256; 
		pucFileInfo[28]=ulFileLen; 
		creat_file(pucFileInfo);	//将文件信息添加到Root information 
		for(i=0;i