📄 fat.cpp
字号:
* update 2008/12/1
*
* ycdbox@126.com 1
*/
LOCAL int Open_ReadOnly(BYTE *pDir)
{
int hFile = 0;
DIR_ENTRY_T *pDirEntry = (DIR_ENTRY_T *)pDir;
FCB_T *pPCB;
pPCB = AlocalFCB();
if(pPCB){
//gFS_FCB[i].mDevName; //盘名:cdefg..z
memcpy(pPCB->mFileName,pDirEntry->name,11);//文件名
pPCB->mFileLen = pDirEntry->size; //文件长度
pPCB->mSequenceNum = 0; //块顺序号
pPCB->mOffset= 0; //偏移量
pPCB->mStartFatNo = pDirEntry->start; //文件起始块FAT号
pPCB->mCurFatNo = pDirEntry->start; //文件当前块FAT号
pPCB->mBlockSize = gFS_Device.mBlockSize;//块大小
//gFS_FCB[i].mBlockBuf; //块缓冲
pPCB->mState = 1; //使用状态
pPCB->mUpdate = 0; //待刷新
pPCB->mMode = eFILE_MODE_R; //打开模式
hFile = pPCB->mHandle; //文件句柄
FS_ReadBlock(pPCB->mStartFatNo,pPCB->mBlockBuf,NULL);
}
return( hFile );
}
/**
* LOCAL int Open_WriteOnly(BYTE *pDir)
*
* update 2008/12/1
*
* ycdbox@126.com 1
*/
LOCAL int Open_WriteOnly(BYTE *pDir)
{
int hFile = 0;
DIR_ENTRY_T *pDirEntry = (DIR_ENTRY_T *)pDir;
FCB_T *pPCB;
pPCB = AlocalFCB();
if( pPCB ){
pDirEntry->start = GetNULLFatNo();
if(0 != pDirEntry->start){
//(1)
SetNextFat(pDirEntry->start, FS_FAT_END);
//(2)
pDirEntry->size = 0;
//(3)
memcpy(pPCB->mFileName,pDirEntry->name,11);//文件名
pPCB->mFileLen = pDirEntry->size; //文件长度
pPCB->mSequenceNum = 0; //块顺序号
pPCB->mOffset = 0; //偏移量
pPCB->mStartFatNo = pDirEntry->start; //文件起始块FAT号
pPCB->mCurFatNo = pDirEntry->start; //文件当前块FAT号
pPCB->mBlockSize = gFS_Device.mBlockSize;//块大小
//gFS_FCB[i].mBlockBuf; //块缓冲
pPCB->mState = 1; //使用状态
pPCB->mUpdate = 1; //待刷新
pPCB->mMode = eFILE_MODE_W; //打开模式
hFile = pPCB->mHandle; //文件句柄
}
else{
pDir[0]=0;
}
}
else{
pDir[0]=0;
}
return( hFile );
}
/**
* LOCAL int FS_Read(BYTE *Buf,int size,int items,int hFile)
*
* 读数据
*
* upate 2009/1/18
*
* ycdbox@126.com 1
*/
LOCAL int FS_Read(BYTE *Buf,int size,int items,int hFile)
{
uint32 Len;
uint32 Point;
uint32 Offset;
uint32 Count = 0;
uint16 NextFat;
FCB_T *pFCB;
//不在该盘
if( !FS_IsIn( hFile ) ){
return( Count );
}
//文件未打开
pFCB = GetFileFCB( hFile );
if(0 == pFCB->mState){
return( Count );
}
//只写
if( eFILE_MODE_W == pFCB->mMode){
return( Count );
}
//文件尾
Point = pFCB->mSequenceNum*pFCB->mBlockSize+pFCB->mOffset;
if(Point >= pFCB->mFileLen){
return( Count );
}
//有效长度
Len = size * items;
if(Len > (pFCB->mFileLen-Point)){
Len = pFCB->mFileLen-Point;
}
//读数据
Offset = pFCB->mOffset;
while(Count < Len){
if(Offset >= pFCB->mBlockSize){
if(FS_FAT_END != pFCB->mCurFatNo){
NextFat = GetNextFat(pFCB->mCurFatNo);
FS_ReadBlock(NextFat,pFCB->mBlockBuf,NULL);
pFCB->mCurFatNo = NextFat;
pFCB->mSequenceNum++;
Offset = 0;
}
else{
break;
}
}
*Buf = pFCB->mBlockBuf[Offset];
Buf++;
Offset++;
Count++;
}
pFCB->mOffset = Offset;
return( Count );
}
/**
* LOCAL bool FS_WriteBlock(uint16 Fat,BYTE *Buf,BYTE *Info)
*
* 按FAT号写(相对地址)
*
* upate 2009/1/18
*
* ycdbox@126.com 1
*/
LOCAL bool FS_WriteBlock(uint16 Fat,BYTE *Buf,BYTE *Info)
{
uint32 BlockNo;
bool Result;
//转为Flash物理地址写(绝对地址)
BlockNo = Fat + gFS_Device.mFirstBockNo;
Result = NF_WriteBlock(BlockNo,Buf,Info);
return( Result );
}
/**
* LOCAL bool FS_ReadBlock(uint16 Fat,BYTE *Buf,BYTE *Info)
*
* 按FAT号写(相对地址)
*
* upate 2009/1/18
*
* ycdbox@126.com 1
*/
LOCAL bool FS_ReadBlock(uint16 Fat,BYTE *Buf,BYTE *Info)
{
uint32 BlockNo;
bool Result;
int i;
//转为Flash物理地址写(绝对地址)
BlockNo = Fat + gFS_Device.mFirstBockNo;
for(i=0; i<3; i++){
Result = NF_ReadBlock(BlockNo,Buf,Info);
if(true == Result){
break;
}
}
return( Result );
}
/**
* LOCAL int FS_Write(BYTE *Buf,int size,int items,int hFile)
*
* 一.
* (1)保存
* (2)Next
*
* 二.
*
* (1)mPrev.
* (2)mCur
*
*
* 三.
* (1)cur
* (2)Next
*
*
*
*1.(a)mPrev->Cur
* (b)mCur->0
* (c)Cur->Next
* (d)Next不变或fff8
*
*
*
*2.(a)mPrev = Cur
* (b)mCur = Next
*
*
*
*3.(a)Seq++.
* (b)office =0
*
*
*
*/
LOCAL int FS_Write(BYTE *Buf,int size,int items,int hFile)
{
uint32 Total;
uint32 Offset;
uint16 NextFAT;
uint32 Count=0;
uint32 FileSize;
FCB_T *pFCB;
//不在该盘
if( !FS_IsIn( hFile ) ){
return( Count );
}
//文件未打开
pFCB = GetFileFCB( hFile );
if(0 == pFCB->mState){
return( Count );
}
//只读保护
if(eFILE_MODE_R == pFCB->mMode){
return( Count );
}
Offset = pFCB->mOffset;
Total = size*items;
while(Count < Total){
if(Offset >= pFCB->mBlockSize){
FS_FileFlush( pFCB );
//Next(新的出来)
NextFAT = GetNextFat(pFCB->mCurFatNo);
if(FS_FAT_END == NextFAT){
NextFAT = GetNULLFatNo();
if(0 == NextFAT){
break;
}
SetNextFat(NextFAT,FS_FAT_END);
SetNextFat(pFCB->mCurFatNo,NextFAT);
}
else{
FS_ReadBlock(NextFAT,pFCB->mBlockBuf,NULL);
}
//mCur = Next新当前
pFCB->mCurFatNo = NextFAT;
//调整 Seq++ office =0
pFCB->mSequenceNum++;
Offset = 0;
}
pFCB->mBlockBuf[Offset] = *Buf;
Offset++;
Buf++;
Count++;
pFCB->mUpdate = 1;
}
pFCB->mOffset = Offset;
//文件长度
FileSize = pFCB->mSequenceNum*pFCB->mBlockSize + pFCB->mOffset;
if(FileSize > pFCB->mFileLen){
pFCB->mFileLen = FileSize;
}
return( Count );
}
/**
* LOCAL void FS_FileFlush(FCB_T* pFCB)
*
* 按FAT号写(相对地址)
*
* upate 2009/1/18
*
* ycdbox@126.com 1
*/
LOCAL void FS_FileFlush(FCB_T* pFCB)
{
BYTE SectorInfo[BLOCK_INFO_LEN];
uint16 Fat;
uint16 Next;
uint16 Prev;
FS_WriteBlock(pFCB->mCurFatNo,pFCB->mBlockBuf,NULL);
FS_ReadBlock(pFCB->mCurFatNo,NULL,SectorInfo);
if(0xff == SectorInfo[SECTOR_BAD_INDEX]){
return;
}
Next = GetNextFat(pFCB->mCurFatNo);
SetNextFat(pFCB->mCurFatNo,FS_FAT_BAD);
while( 1 ){
Fat = GetNULLFatNo();
if( !Fat ){//没有空块
return;
}
FS_WriteBlock(Fat,pFCB->mBlockBuf,NULL);
FS_ReadBlock(Fat,NULL,SectorInfo);
if(0xff == SectorInfo[SECTOR_BAD_INDEX]){
break;
}
SetNextFat(Fat,FS_FAT_BAD);
}
if(pFCB->mSequenceNum == 0){
pFCB->mStartFatNo = Fat;
pFCB->mCurFatNo = Fat;
SetNextFat(Fat,Next);
}
else{
SetNextFat(Fat,Next);
Prev = GetPrevFat(pFCB);
SetNextFat(Prev,Fat);
pFCB->mCurFatNo = Fat;
}
}
/**
* LOCAL void FS_RootFlush(void)
*
* update 2008/12/1
*
* ycdbox@126.com 1
*/
LOCAL void FS_RootFlush(void)
{
int Count;
int i,Index;
int Bad[2];
BYTE blkInfo[BLOCK_INFO_LEN];
if( !gFS_FATParam.mUpdate ){
return;
}
gFS_FATParam.mUpdate = 0;
Bad[0] = 0;
Bad[1] = 0;
Count = (gFS_FATParam.mCount>2) ? (2) : (gFS_FATParam.mCount);
for(i=0; i<Count; i++){
FS_WriteBlock(gFS_FATParam.mFatBlock[i], (BYTE*)gFS_FATBuf,NULL);
FS_ReadBlock(gFS_FATParam.mFatBlock[i],NULL,blkInfo);
if(0xff != blkInfo[SECTOR_BAD_INDEX]){
Bad[i] = 1;
}
}
//仅一个可用块不做了.
if(Count <2) {
return;
}
//两可用
if(0 == Bad[0] &&
(0 == Bad[1])){
return;
} //一个可用
else if((0 == Bad[0]) &&
(1 == Bad[1]) ){
Count = 1;
} //一个可用
else if((1 == Bad[0]) &&
(0 == Bad[1]) ){
gFS_FATParam.mFatBlock[0] = gFS_FATParam.mFatBlock[1];
Count = 1;
}//都坏了
else {
Count = 0;
}
//找到1到2个可以用的
Index = Count;
for(i=gFS_FATParam.mFatBlock[1]+1; i<FIRST_FILE_FAT; i++){
FS_ReadBlock(i,NULL,blkInfo);
if(0xff == blkInfo[SECTOR_BAD_INDEX]){
gFS_FATParam.mFatBlock[Index] = i;
Index++;
if(Index >= 2){
break;
}
}
}
//重写
for(i=Count; i<Index; i++){
FS_WriteBlock(gFS_FATParam.mFatBlock[i], (BYTE*)gFS_FATBuf,NULL);
}
//改数量
gFS_FATParam.mCount = Index;
}
/**
* LOCAL void FS_RootRead(void)
*
* update 2008/12/1
*
* ycdbox@126.com 1
*/
LOCAL void FS_RootRead(void)
{
int i;
int Count = 0;
bool Result;
BYTE blkInfo[BLOCK_INFO_LEN];
//找到1到2个好的块.
for(i=0; i<FIRST_FILE_FAT; i++){
if(0 == Count){
Result = FS_ReadBlock(i,(BYTE*)gFS_FATBuf,blkInfo);
}
else{
Result = FS_ReadBlock(i,NULL,blkInfo);
}
if(true == Result && 0xff == blkInfo[SECTOR_BAD_INDEX]){
gFS_FATParam.mFatBlock[Count] = i;
Count++;
if(Count >=2 ){
break;
}
}
}
gFS_FATParam.mCount = Count;
}
/**
* LOCAL int FS_Seek(int hFile,int offset,int set)
*
* update 2008/12/1
*
* ycdbox@126.com 0
*/
LOCAL int FS_Seek(int hFile,int offset,int set)
{
int Result = 0;
FCB_T *pFCB;
uint32 Point;
uint16 Seq;
uint16 n;
uint16 off;
uint16 Fat;
//不在该盘
if( !FS_IsIn( hFile ) ){
return( Result );
}
//文件未打开
pFCB = GetFileFCB( hFile );
if(0 == pFCB->mState){
return( Result );
}
switch( set ){
case SEEK_SET:
Point = offset;
break;
case SEEK_CUR:
Point = pFCB->mBlockSize*pFCB->mSequenceNum+pFCB->mOffset;
Point += offset;
break;
case SEEK_END:
Point = pFCB->mFileLen;
Point += offset;
break;
};
if(Point >= pFCB->mFileLen){
Point = pFCB->mFileLen;
Seq = Point / pFCB->mBlockSize;
off = Point % pFCB->mBlockSize;
//文件尾所在块为单一块
if(Seq>0 && off == 1){
Seq--;
off = pFCB->mBlockSize+1;
}
}
else{
Seq = Point / pFCB->mBlockSize;
off = Point % pFCB->mBlockSize;
}
if(Seq != pFCB->mSequenceNum){
//有写刷新
if( pFCB->mUpdate ){
FS_FileFlush( pFCB );
pFCB->mUpdate =0;
}
//小于从0找
if(Seq < pFCB->mSequenceNum){
n = 0;
Fat = pFCB->mStartFatNo;
}
else{ //大于从此找
n = pFCB->mSequenceNum;
Fat = pFCB->mCurFatNo;
}
while( n < Seq){
Fat = GetNextFat( Fat );
n++;
}
pFCB->mCurFatNo = Fat;
pFCB->mSequenceNum = Seq;
FS_ReadBlock(Fat,pFCB->mBlockBuf,NULL);
}
pFCB->mOffset = off;
Result = 1;
return( Result );
}
/**
* LOCAL uint32 FS_Ftell(int hFile)
*
* update 2008/12/1
*
* ycdbox@126.com 0
*/
LOCAL uint32 FS_Ftell(int hFile)
{
uint32 Point = 0;
FCB_T *pFCB;
//不在该盘
if( !FS_IsIn( hFile ) ){
return( Point );
}
//文件未打开
pFCB = GetFileFCB( hFile );
if(0 == pFCB->mState){
return( Point );
}
Point = pFCB->mBlockSize*pFCB->mSequenceNum + pFCB->mOffset;
return( Point );
}
/**
* LOCAL int FS_Del(char *Name)
*
* update 2008/12/1
*
* ycdbox@126.com 0
*/
LOCAL int FS_Del(char *Name)
{
int Result = 0;
int hFile = 0;
char c = toupper(Name[0]);
char File83Name[FILENAME_MAX_LEN];
DIR_ENTRY_T *pDir;
uint16 Fat,NextFat;
//解析文件名
ParseFileNameTo83(Name,File83Name);
//盘名
if(c != gFS_Device.mDeviceName){
return( Result );
}
//没文件名 c:
if(0 == File83Name[0]){
return( Result );
}
//已打开
if(IsOpened(File83Name)){
return( Result );
}
pDir = (DIR_ENTRY_T*)GetRootEntryAddr( File83Name );
if(NULL == pDir){
return( Result );
}
Fat = pDir->start;
while( 1 ){
NextFat = GetNextFat( Fat );
if(FS_FAT_BAD != NextFat){
SetNextFat(Fat, FS_FAT_NULL);
}
if( FS_FAT_END == NextFat){
break;
}
if(FS_FAT_BAD == NextFat){
break;
}
Fat = NextFat;
}
FS_RootFlush();
Result = 1;
return ( Result );
}
/**
* LOCAL int FS_IsFormat(void)
*
* update 2008/12/1
*
* ycdbox@126.com 0
*/
LOCAL int FS_IsFormat(void)
{
int Result = 0;
if(FS_FAT_FLAG == gFS_FATBuf[0]){
Result = 1;
}
return ( Result );
}
/**
* int FS_feof( int hFile)
*
* update 2008/12/1
*
* ycdbox@126.com 0
*/
LOCAL int FS_feof( int hFile)
{
int Result = 1;
uint32 Point = 0;
FCB_T *pFCB;
//不在该盘
if( !FS_IsIn( hFile ) ){
return( Result );
}
//文件未打开
pFCB = GetFileFCB( hFile );
if(0 == pFCB->mState){
return( Result );
}
Point = pFCB->mBlockSize*pFCB->mSequenceNum + pFCB->mOffset;
if(Point < pFCB->mFileLen ){
Result = 0;
}
return( Result );
}
LOCAL FILE_INTO_T gFlashDiskInfo={
FS_Open,//int (*mFopen)(char *Name,char*mode);
FS_Close,//int (*mFclose)(int hFile);
FS_Read,//int (*mFread)(BYTE *buf,int n,int t,int hFile);
FS_Write,//int (*mFwrite)(BYTE *buf,int n,int t,int hFile);
FS_Seek,//int (*mFseek)(int hFile,int offset,int begin);
FS_Ftell,//uint32 *mFtell(int hFile);
FS_Format,//int (*mFomat)(char DevName);
FS_Init,//int (*mFInit)(char DevName);
FS_IsIn,//int (*mFIsIn)(int hFile);
FS_Del,//int (*mFDel)(char *Name);
FS_IsFormat,//int (*mFIsFormat)(void);
FS_feof
};
/**
* int FS_AddFlashDisk( DISK_INFO_P *f)
*
* update 2008/12/1
*
* ycdbox@126.com 0
*/
int FS_AddFlashDisk( DISK_INFO_P *f)
{
*f = &gFlashDiskInfo;
return(1);
}
/*---------------------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -