📄 file.c
字号:
//****************************************************************************************
//** 文件名: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 + -