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

📄 file.c

📁 usb2.0驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
//****************************************************************************************
//** 文件名:File.c

//** Copyright (c) 2002 Hard&SoftMcuStudio

//** 创建人:Hard&SoftMcuStudio

//** 日期:2002.06.27

//** 描述:Flash file systems
//**
//** 版本:1.0
//**************************************************************************************
#include <string.h>
#include "file.h"
//INT8U aucHZK[267616];
//INT8U aucEK[4096];
//INT8U aucPYK[16676];

//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 *pucFileName,INT8U iNameNum,INT8U iDirFlag,INT32U ulBlockNum);
void close_file(INT32U ulBlockNum);
void write_file(INT8U ucEndFlag,INT8U *pucBlockBuf);
void WriteFileOneBlock(INT8U ucEndFlag,INT8U *pucBlockBuf);
INT32U find_file(INT8U *pucFileName, INT32U ulBlockNum);
INT32U comp_filename(INT8U *pucString1,INT8U *pucString2);
INT8U read_file(INT8U *pucBlockBuf,INT32 lByteNum);
static void LoadFont(void);
INT32U Dir(INT32U root_block_num, INT8U *file_count);
INT32U Dir_Path(INT8U *pathString, INT8U *file_count);

/*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];
INT8U file_inf_buf[32];             //当前文件信息缓存区    
INT32U pre_block;               //上次读写的block 
INT32U current_block;           //当前读写的block
INT32U next_block;               //下一次读写的block
INT32U pre_root;                 //上一层目录的block号
INT32U current_root;              //当前目录的block号
STRU_LongDIR_INFO DIR_Flash[100];   //当前目录信息
//INT32U	file_count;				//当前目录文件个数

//INT8U Block_1Page_Buf[528];	//Block首页Buffer
INT8U Page_Buf[528];
//STRU_LongDIR_INFO DIR_FlashFile;
INT32U used_byte_num;            //使用了flash空间(byte)
#define File_MaxNum (100);
//------------------------------------------------------------------
// 函数名:INT32U Seek_blank_block(void)-----------------------------------------------------modificated in 3.24
// 输 入: 开始Block号
// 输 出: 空的Block号
// 功能描述:寻找介于StartBlock与EndBlock之间的第一个Blank Block
// 全局变量:Block_1Page_Buf
//------------------------------------------------------------------
INT32U seek_blank_block(INT32U StartBlock)
{
	INT32U ulBlockNum;
	
	ulBlockNum=StartBlock;
	ReadPage(ulBlockNum,0,Page_Buf);
	while(Page_Buf[512]!=UNUSED_MARK)
           ReadPage(++ulBlockNum,0,Page_Buf);
	return(ulBlockNum);
}

//------------------------------------------------------------------
// 函数名:void creat_file(INT8U *pucFileName,INT8U iNameNum)---------------------------------modificated in 3.24
// 输 入: INT8U *pucFileName --含文件名, 短文件名的格式为8.3格式,即8byte名字(不足8位补零)+3byte扩展名
//       INT8U iNameNum--文件名长度,短文件名为8,长文件名大于8(不包括扩展名)   
//       INT8U iDirFlag-- 文件目录标志,是目录为1,文件则为0
// 输 出: Null
// 功能描述:将Root Directory数据读入当前目录current_root的root_buf[],并在root_buf中修改之
// 全局变量:root_buf,current_root
//------------------------------------------------------------------
void creat_file(INT8U *pucFileName,INT8U iNameNum,INT8U iDirFlag,INT32U ulBlockNum)
{

	INT32U ulPageNum,Pointer,i,ulSubDirBlockNum;
    INT8U  iInfNum,iNamePoint,chk_sum,temp; 
    struct LongDir_Entry Stru_Long_Entry_Buffer; 	
	for(ulPageNum=0;ulPageNum<32;ulPageNum++)
	{
		/*将Root information读到root_buf中*/
		ReadPage(ulBlockNum,ulPageNum,Page_Buf);
		for(Pointer=0;Pointer<512;Pointer++)
		{
			root_buf[ulPageNum*16+Pointer/32][Pointer%32]=Page_Buf[Pointer];
			//root_buf[文件条序号][文件目录信息],每页16个32byte结构(即每页16条文件信息)
		}
	}
		
	/*在root_buf寻找空表项*/
	Pointer=0;
	while(root_buf[Pointer][0]!=0x00)
	{
		Pointer++;
	}
	
	/*copy the file name and file size*/
	if(iNameNum<=8)   //短文件名
	{
		for(i=0;i<8;i++)
		root_buf[Pointer][i]= *pucFileName++;
		if(iDirFlag)    //文件夹
		root_buf[Pointer][11]=0x10;
		else          //文件
		{
			for(i=8;i<11;i++)
	        root_buf[Pointer][i]= *pucFileName++;
			root_buf[Pointer][11]=0x00;
		}	
	ulSubDirBlockNum=seek_blank_block(Start_Cluster);
	
	
	root_buf[Pointer][26]=(INT8U)(ulSubDirBlockNum%256);	//store LSB
	root_buf[Pointer][27]=(INT8U)(ulSubDirBlockNum/256);	//store MSB
	}

    else                 //长文件名
    {
    	iInfNum=iNameNum/13+1;
    	//---------------------------------------------------------长文件名的short entry部分
        Pointer+=iInfNum;
        for(i=0;i<8;i++)
		root_buf[Pointer][i]= *(pucFileName+i);
		if(iDirFlag)    //文件夹
		root_buf[Pointer][11]=0x10;
		else          //文件
		{   
		    pucFileName=pucFileName+iNameNum-3;
			for(i=8;i<11;i++)  root_buf[Pointer][i]= *pucFileName++;
			root_buf[Pointer][11]=0x00;
		}	

		ulSubDirBlockNum=seek_blank_block(Start_Cluster);
			
	    root_buf[Pointer][26]=(INT8U)(ulSubDirBlockNum%256);	//store LSB
	    root_buf[Pointer][27]=(INT8U)(ulSubDirBlockNum/256);	//store MSB

        for(i=0,chk_sum=0;i<11;i++)
        	chk_sum=((chk_sum&1)?0x80:0)+(chk_sum>>1)+root_buf[Pointer][i];
      //---------------------------------------------------------长文件名的long entry部分
        Pointer-=iInfNum;
      
        Stru_Long_Entry_Buffer.ucChk_Sum=chk_sum;
        Stru_Long_Entry_Buffer.ucDirAttr=0x0f;
        for(temp=iInfNum;temp>0;temp--,Pointer++)
		{
		  
		  if(temp==iInfNum)
		  	{
        		for(iNamePoint=0;iNamePoint<iNameNum-26*(iInfNum-1);iNamePoint++)
        		Stru_Long_Entry_Buffer.ucEntryFileName[iNamePoint]=*(pucFileName+iNamePoint+iInfNum*26-26);
        		if(iNamePoint<24) 
        		{
        	 		iNamePoint++;
        	 		Stru_Long_Entry_Buffer.ucEntryFileName[iNamePoint]=0;
        	 		iNamePoint++;
        	 		Stru_Long_Entry_Buffer.ucEntryFileName[iNamePoint]=0;
        		}
        		if(iNamePoint<24)
        			for(;iNamePoint<26;iNamePoint++)
        			Stru_Long_Entry_Buffer.ucEntryFileName[iNamePoint]=0xff;
		  	}
		  else
		  	for(iNamePoint=0;iNamePoint<26;iNamePoint++)
        		Stru_Long_Entry_Buffer.ucEntryFileName[iNamePoint]=*(pucFileName+iNamePoint+temp*26-26);
		i=0;	
        while(i<32)
        	{
              switch(i)
              	{
              	   case 0: root_buf[Pointer][0]=0x40|temp;
              	   		   if(temp==iInfNum) root_buf[Pointer][0]|=0x40; 	
              	              i++;
              	           break;
              	   case 1: for(iNamePoint=0,i=1;iNamePoint<11;iNamePoint++)
        							{
        								root_buf[Pointer][i]=Stru_Long_Entry_Buffer.ucEntryFileName[iNamePoint];
        								i++;
        							}
              	           i=11;
              	           break;
              	   case 11:root_buf[Pointer][i]=Stru_Long_Entry_Buffer.ucDirAttr;
              	   		   break;	
              	   case 12:root_buf[Pointer][i]=0;
              	   	       break;
              	   case 13:root_buf[Pointer][i]=Stru_Long_Entry_Buffer.ucChk_Sum;
              	   		   break;  	
              	   case 14:for(iNamePoint=10;iNamePoint<22;iNamePoint++)
        							{
        								root_buf[Pointer][i]=Stru_Long_Entry_Buffer.ucEntryFileName[iNamePoint];
        								i++;
        							}
              	           i=26;
              	           break;
              	   case 26:
              	   case 27:root_buf[Pointer][i]=0;
              	   		   i++;
              	   		   break;
              	   case 28:for(iNamePoint=22;iNamePoint<26;iNamePoint++)
        							{
        								root_buf[Pointer][i]=Stru_Long_Entry_Buffer.ucEntryFileName[iNamePoint];
        								i++;
        							}
              	           i=32;
              	           break;
              	   default: i=0;
              	           break;
              	   
              	}
        	}

    	}

    	}
    close_file(ulBlockNum);
    if (iDirFlag)       //若是文件夹则要添加.和..两个目录到文件夹内
    	{
                    for(i=0;i<512;i++)
			{	
                        for(temp=32;temp>0;temp--) root_buf[i][temp]=0;
			}
			pre_block=current_block;
			current_block=ulSubDirBlockNum;
			root_buf[0][0]=0x2e;              //添加子文件夹的.和..目录
			root_buf[0][11]=0x10;
			root_buf[0][26]=(INT8U)(current_block%256);	//store LSB
	        root_buf[0][27]=(INT8U)(current_block/256);	//store MSB

            root_buf[1][0]=0x2e;              //添加子文件夹的.和..目录
            root_buf[1][1]=0x2e;  
			root_buf[1][11]=0x10;
			root_buf[1][26]=(INT8U)(current_block%256);	//store LSB
	        root_buf[1][27]=(INT8U)(current_block/256);	//store MSB

			
			close_file(current_block);
				
    	}


}
//------------------------------------------------------------------
// 函数名:void close_file(void)--------------------------------------------------------------modificated in 3.24
// 输 入: INT32U ulBlockNum--当前文件信息所在的block号
// 输 出: Null
// 功能描述:将root_buf中的数据写回Root Directory所处的Block(即Block0)
// 全局变量:Page_Buf, current_block
//------------------------------------------------------------------
void close_file(INT32U ulBlockNum)
{

	INT32U ulPageNum,Pointer;
	
	/*Erase Root_information Cluster*/
	Erase_Block(ulBlockNum);
	
	/*将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(ulBlockNum,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;		
}
//------------------------------------------------------------------
// 函数名:void WriteFileOneBlock(INT8U ucEndFlag,INT8U *pucBlockBuf)---------------------------modificated in 3.24
// 输 入: INT8U ucEndFlag--1 End
//					   --0 Not End
//          INT8U *pucBlockBuf--块buffer
// 输 出: Null
// 功能描述:将pucBlockBuf中的数据写到1个Block中
// 全局变量:Page_Buf, pre_block, current_block
//------------------------------------------------------------------
void WriteFileOneBlock(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;
	Erase_Block(current_block);															
	for(ulPageNum=0;ulPageNum<32;ulPageNum++)
	{

⌨️ 快捷键说明

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