📄 fat12.c
字号:
NAND_SpareRead(i<<14 | 2, &tempSectorSpare[2], 6);
if((tempSectorSpare[5] == 0xff) && (tempSectorSpare[7] == 0xff) && (tempSectorSpare[2] == 0xff))
{ //该块非坏块并且为空
newblocknum = i;
full = 0;
break; //找到好块,退出该循环
}
}
}
if((startPhblock >= (FAT_SIZEOFWORD-1)) || (full == 0xff)) //不能向后或向后没有找到新块,再从前找
{
for(i=0; i<startPhblock; i++)
{
NAND_SpareRead(i<<14 | 2, &tempSectorSpare[2], 6);
if((tempSectorSpare[5] == 0xff) && (tempSectorSpare[7] == 0xff) && (tempSectorSpare[2] == 0xff))
{ //该块非坏块并且为空
newblocknum = i;
full = 0;
break; //找到好块,退出该循环
}
}
}
if(full == 0xff) //FLASH满,没有空的块
{
i = 0;
do //清理一个垃圾块
{
newblocknum = GarbageProcess( );
if(newblocknum != 0xffff)
{ return newblocknum; } //找到一个,返回
}while((newblocknum== 0xffff) && (i++ < (FAT_SIZEOFWORD-1)));
}
return newblocknum;
}
/******************************* 函数 WORD Find_BlankLogicBlock( ) **********************************/
/* 功能:从逻辑块号0开始,在FAT表中寻找一个空逻辑块,找到之后返回新的逻辑块号 */
/* 寻找策略:逻辑映射表中如果某个逻辑块号对应的物理块号值是0xffff,说明该逻辑号还没有相应的物理块, */
/* 为空,此时即找到,返回该逻辑块号 */
/* 入口参数:无 */
/* 返回值:找到的空逻辑块号. 0xffff表示找不到空逻辑块,盘已满 */
/* 说明:非用户使用函数 */
/****************************************************************************************************/
WORD Find_BlankLogicBlock( )//OK
{
DWORD oldsector,newsector;
BYTE* psector;
BYTE* neednext;
WORD buff;
BYTE tempbuffer1[512],tempbuffer2[512];
WORD fatoffset;//逻辑簇号在整个FAT表中的字节偏移位置
WORD clusternum,clustervalue;
WORD offsetinsector;
oldsector = 0;
for(clusternum=2; clusternum<(DISK_48M<<6); clusternum++)
{
fatoffset = clusternum + clusternum/2;
offsetinsector = fatoffset % BytesPerSector;
newsector = fatoffset/BytesPerSector + FirstFATSector;
if(newsector != oldsector)
{
ReadLgSector(newsector,tempbuffer1);
oldsector = newsector;
}
if(offsetinsector != (BytesPerSector - 1)) //逻辑簇号未跨扇区,直接读取
{
psector = &tempbuffer1[offsetinsector];
buff = ((word)(*(psector+1))<<8) | *psector;
}
else if(newsector < (FirstFATSector+FATsectors-1)) //逻辑簇号跨了扇区并且不是最后一个FAT扇区,需要组合形成逻辑簇号
{
psector = &tempbuffer1[offsetinsector];
neednext= ReadLgSector(newsector+1,tempbuffer2);
buff = ((word)(*neednext)<<8) | *psector;
}
else //逻辑簇号是最后一个FAT扇区的最后一个字节并且需要跨扇区,说明到头
{ return 0xffff; }
if(clusternum&0x01) //簇号是奇数,取psector中的高12位
{ clustervalue = buff>>4; }
else //簇号是偶数,取psector中的低12位
{ clustervalue = buff & 0x0fff; }
if(clustervalue == 0)
{ return clusternum; } //返回找到的空逻辑簇
}
return 0xffff; //未找到空簇
}
/***************************** 函数 WORD Read_FAT(WORD LgClusterNum) ********************************/
/* 功能: 读取FAT表中对应输入逻辑块号下的值 */
/* 入口参数:WORD LgClusterNum----逻辑簇号 */
/* 返回值:FAT表中逻辑块号下的值. 0xffff表示输入的逻辑块号超出FAT表的逻辑块范围 */
/* 说明:非用户使用函数 */
/****************************************************************************************************/
WORD Read_FAT(WORD LgClusterNum)//OK
{
DWORD sectornum;
BYTE* psector;
BYTE* neednext;
WORD buff;
BYTE tempbuffer1[3],tempbuffer2[3];
WORD fatoffset;//逻辑簇号在整个FAT表中的字节偏移位置
WORD clustervalue;
WORD offsetinsector;
fatoffset = LgClusterNum + LgClusterNum/2;
offsetinsector = fatoffset % BytesPerSector;
sectornum = fatoffset/BytesPerSector + FirstFATSector;
if(ReadLgSectorFat(sectornum,tempbuffer1,offsetinsector)==NULL)
{ return 0xffff; }
if(offsetinsector != (BytesPerSector - 1)) //逻辑簇号未跨扇区,直接读取
{
psector = &tempbuffer1[0];
buff = ((word)(*(psector+1))<<8) | *psector;
}
else if(sectornum < (FirstFATSector+FATsectors-1)) //逻辑簇号跨了扇区并且不是最后一个FAT扇区,需要组合形成逻辑簇号
{
psector = &tempbuffer1[0];
neednext= ReadLgSectorFat(sectornum+1,tempbuffer2,0);
if(neednext==NULL)
{
return 0xffff;
}
buff = ((word)(*neednext)<<8) | *psector;
}
else //逻辑簇号是最后一个FAT扇区的最后一个字节并且需要跨扇区,说明到头
{ return 0xffff; }
if(LgClusterNum&0x01) //簇号是奇数,取psector中的高12位
{ clustervalue = buff>>4; }
else //簇号是偶数,取psector中的低12位
{ clustervalue = buff & 0xfff; }
return clustervalue; //返回逻辑簇号下的内容
}
/*WORD Read_FAT(WORD LgClusterNum)
{
DWORD sectornum;
BYTE* psector;
BYTE* neednext;
WORD buff;
BYTE tempbuffer1[512],tempbuffer2[512];
WORD fatoffset;
WORD clustervalue;
WORD offsetinsector;
fatoffset = LgClusterNum + LgClusterNum/2;
offsetinsector = fatoffset % BytesPerSector;
sectornum = fatoffset/BytesPerSector + FirstFATSector;
ReadLgSector(sectornum,tempbuffer1);
if(offsetinsector != (BytesPerSector - 1))
{
psector = &tempbuffer1[offsetinsector];
buff = ((word)(*(psector+1))<<8) | *psector;
}
else if(sectornum < (FirstFATSector+FATsectors-1))
{
psector = &tempbuffer1[offsetinsector];
neednext= ReadLgSector(sectornum+1,tempbuffer2);
buff = ((word)(*neednext)<<8) | *psector;
}
else
{ return 0xffff; }
if(LgClusterNum&0x01)
{ clustervalue = buff>>4; }
else
{ clustervalue = buff & 0xfff; }
return clustervalue;
}*/
/************************** 函数 void Write_FAT(WORD LgClusterNum,WORD Value) ***********************/
/* 功能: 将数值Value写入FAT表中对应输入逻辑块号LgSectorNum下 */
/* 入口参数:WORD LgClusterNum----逻辑簇号 */
/* WORD Value----准备写入的数值 */
/* 返回值: FAT表中逻辑块号下的值. 0xffff表示输入的逻辑块号超出FAT表的逻辑块范围 */
/* 说明: 非用户使用函数 */
/****************************************************************************************************/
void Write_FAT(WORD LgClusterNum,WORD Value)//OK
{
DWORD sectornum;
BYTE tempbuffer1[512],tempbuffer2[512];
WORD fatoffset;//逻辑簇号在整个FAT表中的字节偏移位置
WORD offsetinsector;
fatoffset = LgClusterNum + LgClusterNum/2;
offsetinsector = fatoffset % BytesPerSector;
sectornum = fatoffset/BytesPerSector + FirstFATSector;
ReadLgSector(sectornum,tempbuffer1);
if(offsetinsector != (BytesPerSector - 1)) //逻辑簇号未跨扇区,直接写入
{
if(LgClusterNum&0x01) //簇号是奇数,写入逻辑簇号中的高12位
{
tempbuffer1[offsetinsector] = (tempbuffer1[offsetinsector]&0x0f)|((Value&0x000f)<<4);
tempbuffer1[offsetinsector+1] = (BYTE)((Value&0x0ff0)>>4);
}
else //簇号是偶数,写入逻辑簇号中的低12位
{
tempbuffer1[offsetinsector] = (BYTE)(Value&0x00ff);
tempbuffer1[offsetinsector+1] = (tempbuffer1[offsetinsector+1]&0xf0)|((Value&0x0f00)>>8);
}
WriteLgSector(sectornum,tempbuffer1); //写入FAT1
WriteLgSector(sectornum+FATsectors,tempbuffer1);//写入FAT2
}
else if(sectornum < (FirstFATSector+FATsectors-1)) //逻辑簇号跨了扇区并且不是最后一个FAT扇区,需要分两次写入不同的扇区
{
ReadLgSector(sectornum+1,tempbuffer2);
if(LgClusterNum&0x01) //簇号是奇数,写入逻辑簇号中的高12位
{
tempbuffer1[offsetinsector] = (tempbuffer1[offsetinsector]&0x0f)|((Value&0x000f)<<4);
tempbuffer2[0] = (BYTE)((Value&0x0ff0)>>4);
}
else //簇号是偶数,写入逻辑簇号中的低12位
{
tempbuffer1[offsetinsector] = (BYTE)(Value&0x00ff);
tempbuffer2[0] = (tempbuffer2[0]&0xf0)|((Value&0x0f00)>>8);
}
WriteLgSector(sectornum,tempbuffer1); //写入FAT1
WriteLgSector(sectornum+FATsectors,tempbuffer1);//写入FAT2
WriteLgSector(sectornum+1,tempbuffer2); //写入FAT1
WriteLgSector(sectornum+1+FATsectors,tempbuffer2);//写入FAT2
}
return ;
}
/************************************ 函数unsigned char GetFatInfo(void) ****************************/
/*函数功能:该函数主要用于从已有的存储介质中获得文件系统信息 */
/*函数输出:得到以下变量的值: */
/* SectorsPerCluster */
/* BytesPerSector */
/* FirstFATSector */
/* FATsectors */
/* FirstDataSector */
/* RootDirCount */
/* RootDirSectors */
/* FirstDirSector */
/* 说明: 用户使用函数 */
/****************************************************************************************************/
void GetFatInfo(void)//OK
{
BOOTSECTOR50 *bootsector;
BPB50 *bpb;
EXTBOOT *ext;
BYTE tempbuffer[512];
NAND_PageRead(lgToph[0]<<14, tempbuffer, 512); //读引导扇区DBR
bootsector = (BOOTSECTOR50 *)tempbuffer;
bpb = (BPB50 *)(bootsector->Bs_BPB);
ext = (EXTBOOT *)(bootsector->Bs_Ext);
SectorsPerCluster = bpb->BPB_SecPerClust; //每cluster的sector数目32
if(SectorsPerCluster==0) return;
BytesPerSector = bpb->BPB_BytesPerSec; //每sector的字节数512
if(BytesPerSector==0) return;
RootDirCount = bpb->BPB_RootEntCnt; //根目录的目录项数496
RootDirSectors = (RootDirCount*sizeof(DIRENTRY))/BytesPerSector; //根目录区所占用的扇区数 = 31
FirstFATSector = bpb->BPB_RsvdSecCnt; //FAT区的起始地址 =1
FATsectors = bpb->BPB_FATSz16; //每个FAT表的扇区数,16
if(bpb->BPB_FATSz16)
{
//BPB_FATSz16 is non-zero and is therefore valid
FirstDirSector = FirstFATSector + bpb->BPB_NumFATs * FATsectors ; //=33
}
FirstDataSector = FirstDirSector + RootDirSectors; //第一个数据扇区的位置 =64
}
/************************ 函数 WORD AllocCluster(WORD PrevLgClusterNum) *****************************/
/* 功能:寻找并分配一个空逻辑镞和空物理块,将该物理块映射到逻辑块(更新逻辑映射表) */
/* 并在FAT表中将新的逻辑镞号链接到先前的逻辑镞号后,新逻辑簇号标记为0x0fff(文件最后一簇) */
/* 入口参数:先前的逻辑镞号,0表示没有先前的逻辑镞号 */
/* 返回值:新分配的镞号. 0xffff表示找不到空镞,盘已满 */
/* 说明:非用户使用函数 */
/****************************************************************************************************/
WORD AllocCluster(WORD PrevLgClusterNum)//OK
{
WORD newlogicClusternum;
WORD newphBlocknum;
BYTE tempSectorSpare[16];
/*********** 64M的NAND_FLASH共有4096个块,因此镞的最大编号是4095 ****************/
/* 首先在FAT表中寻空逻辑号*/
newlogicClusternum = Find_BlankLogicBlock( );
if(newlogicClusternum == 0xffff)
{ return 0xffff; }
newphBlocknum = Find_BlankPhBlock(lgToph[PrevLgClusterNum]+1);
if(newphBlocknum == 0xffff)
{ return 0xffff; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -