📄 file.c
字号:
/*-----------------------------------------------------------
*文 件 名: file.c
*功能描述: 完成文件系统的基本操作,创建文件,打开文件,读写文件等操作
*作 者:
*----------------------------------------------------------*/
//--------------------------------------------------------
//INCLUDES
//--------------------------------------------------------
#include "file.h"
//------------------------------------------------------------
//*函数名称:init_FileSystem()
//*功能描述:读取文件系统的BPB,获得磁盘的基本参数
//*形式参数:void
//*返 回 值:unsigned char,若为FAT16则返回1,若不是则返回其他值
//-------------------------------------------------------------
unsigned char init_FileSystem()
{
unsigned char file_type=0;
read_partition(); //读取分区表中的信息
BootStartSector = partitionTable1.SectorsPrecedingPartition;
//喂狗
WDTCN=0xa5;
read_BPB(); //获取BPB中的基本参数
compute_BPB(); //计算BPB中的基本参数
if(RootDirSectors == 0)
file_type = 2; //文件系统为FAT32
if((CountofClusters>0) && (CountofClusters<=4085))
file_type = 3; //文件系统为FAT12
if((CountofClusters>4085) && (CountofClusters<=65525))
file_type = 1; //文件系统为FAT16
return file_type;
}
/*------------------------------------------------------------
*函数名称:create_file()
*功能描述:创建新文件
*形式参数:unsigned char * name;要创建的文件的名称
*返 回 值:void
*---------------------------------------------------------------*/
void create_file(unsigned char * file_name,unsigned char * type)
{
unsigned char flag=0;
unsigned int xdata i;
unsigned int xdata j;
unsigned int xdata k;
unsigned char xdata *p;
unsigned int xdata *pcluster;
unsigned char xdata name[8];
unsigned char xdata file_type[3];
//对文件名的整理
for(i=0;i<strlen(file_name);i++)
name[i]=*(file_name+i);
for(i=strlen(file_name);i<8;i++)
name[i]=0x20;
//对文件类型的整理
for(i=0;i<strlen(type);i++)
file_type[i]=*(type+i);
for(i=strlen(type);i<3;i++)
file_type[i]=0x20;
//喂狗
WDTCN=0xa5;
//*********在FAT1中查找是否有闲置的单元存在,有则分配给所要创建的文件。FAT1占BPB.BPB_FATSz16
for(i=0;i<BPB.BPB_FATSz16;i++) //BPB.BPB_FATSz16:一个FAT表所占的扇区数
{
mmc_readblock(FAT1_FirstSector+i,buffer); //读出FAT表中第i个扇区的内容
pcluster=(unsigned int xdata *)buffer; //转换为整型指针给pcluster
for(j=0;j<256;j++) //在FAT表的第i个扇区找是否有空闲的簇存在,16位表示一个扇区是否被占用
if(*(pcluster+j) == 0)
{
flag =1;
break;
}
if(flag ==1)
{
flag =0;
break;
}
}
//喂狗
WDTCN=0xa5;
if(i<BPB.BPB_FATSz16) //有空闲的簇分配给新文件
{
strcpy(FileIndex.FileName.NAME,name); //将要创建的文件名放入文件索引中
strcpy(FileIndex.FileName.TYPE,file_type); //要要创建的文件的类型放入文件索引中
FileIndex.FileAttrib=0x20; //文件属性值
FileIndex.FilePosit.Size=0x00; //新创建的为空文件
fileSize=0x00000000; //更新文件大小,新建文件大小为0
FileIndex.FilePosit.Start=0x0000; //文件的起始簇号
FAT_writeFlag =1; //允许在写时将FAT表对应的项写入值
//文件位置信息
filePosition.ClusID = (i*256)+j; //文件地址的基本信息
filePosition.SecOfClus = 0;
filePosition.ByteOfSec = 0;
//喂狗
WDTCN=0xa5;
//**************************文件时间值的填充************
file_time(0); //填充文件的创建时间值
//在root 中寻找空的目录项
for(i=0;i<RootDirSectors;i++)
{
mmc_readblock(FDT_FirstSector+i,buffer); //读出root中第i个扇区的内容
// if(i==0) //当为根目录的第一个扇区时,从offset =64开始查找
// j=64;
// else
j=0;
while(j<512)
{
//喂狗
WDTCN=0xa5;
if((buffer[j]==0x00)||(buffer[j]==0xe5))
{
flag=1;
break;
}
j +=32;
}
if(flag==1)
{
flag=0;
break;
}
}
p=(unsigned char xdata *)(FileIndex.FileName.NAME);
mmc_readblock(FDT_FirstSector+i,buffer);
for(k=j;k<j+32;k++)
buffer[k]=*(p++);
mmc_writeblock(FDT_FirstSector,buffer); //写入将要创建的文件索引
FileIndex.FilePosit.Start=filePosition.ClusID; //文件的起始簇号
//转换为大端模式,unsigned int
p=(unsigned char xdata *)(&FileIndex.FilePosit.Start);
{
unsigned char temp;
temp=*p;
*p=*(p+1);
*(p+1)=temp;
}
fileIndexPosition.secotor =FDT_FirstSector+i;
fileIndexPosition.ByteOfSec=j;
}
}
/*------------------------------------------------------------
*函数名称:write_file(unsigned char xdata *buffer)
*功能描述:向打开的文件中写入数据
*形式参数:void
*返 回 值:void
*---------------------------------------------------------------*/
void write_file(unsigned char xdata *dataBuffer)
{
unsigned char xdata *p;
unsigned int xdata *pcluster;
unsigned int xdata offset;
unsigned long xdata currentCluster; //当前要写入的簇号
unsigned int xdata nextCluster; //下一个簇号
unsigned long xdata currentSector; //当前要写入的扇区数
currentCluster = filePosition.ClusID;
//喂狗
WDTCN=0xa5;
if(FAT_writeFlag == 1)
{
FAT_writeFlag = 0;
//初始化FAT表
offset = currentCluster/256;
mmc_readblock(FAT1_FirstSector+offset,buffer);
pcluster=(unsigned int xdata *)buffer; //转换为整型指针给pcluster
*(pcluster+currentCluster%256)=0xffff;
mmc_writeblock(FAT1_FirstSector+offset,buffer); //更新FAT表
mmc_readblock(FAT2_FirstSector+offset,buffer);
pcluster=(unsigned int xdata *)buffer; //转换为整型指针给pcluster
*(pcluster+currentCluster%256)=0xffff;
mmc_writeblock(FAT2_FirstSector+offset,buffer); //更新FAT表
}
//--------------------------------------------------------------------------------
currentSector = FirstDataSector + (currentCluster -2)*BPB.BPB_SecPerClus + filePosition.SecOfClus;
mmc_writeblock(currentSector,dataBuffer); //将数据写入相应的扇区
fileSize +=BPB.BPB_BytsPerSec; //更新文件大小
filePosition.SecOfClus++;
//还需要考虑簇数要符合要求
if(filePosition.SecOfClus>BPB.BPB_SecPerClus-1)
{
filePosition.SecOfClus=0;
nextCluster=get_freeClusterID(currentCluster); //或许下一个簇号
if(nextCluster>0)
{
filePosition.ClusID =nextCluster; //将当前指向的簇号更新
FAT_writeFlag = 1;
//转换为大端模式,unsigned int
p=(unsigned char xdata *)(&nextCluster);
{
unsigned char temp;
temp=*p;
*p=*(p+1);
*(p+1)=temp;
}
//喂狗
WDTCN=0xa5;
offset = currentCluster/256;
mmc_readblock(FAT1_FirstSector+offset,buffer);
pcluster=(unsigned int xdata *)buffer; //转换为整型指针给pcluster
*(pcluster+currentCluster%256)=nextCluster; //大小端可能会需要变化
mmc_writeblock(FAT1_FirstSector+offset,buffer); //更新FAT表
mmc_readblock(FAT2_FirstSector+offset,buffer);
pcluster=(unsigned int xdata *)buffer; //转换为整型指针给pcluster
*(pcluster+currentCluster%256)=nextCluster; //大小端可能会需要变化
mmc_writeblock(FAT2_FirstSector+offset,buffer); //更新FAT表
//保存文件
close_file();
}
}
}
/*------------------------------------------------------------
*函数名称:close_file()
*功能描述:保存文件,更新文件索引表
*形式参数:void
*返 回 值:void
*---------------------------------------------------------------*/
void close_file()
{
unsigned int i;
unsigned char xdata *p;
//更新文件索引表
//更新文件大小
FileIndex.FilePosit.Size = fileSize; //注意大端小端的问题
//转换为大端模式 ,unsigned long
p=(unsigned char xdata *)(&FileIndex.FilePosit.Size);
for(i=0;i<2;i++)
{
unsigned char temp;
temp=*(p+(3-i));
*(p+(3-i))=*(p+i);
*(p+i)=temp;
}
//喂狗
WDTCN=0xa5;
mmc_readblock(fileIndexPosition.secotor,buffer);
file_time(1); //填充文件的更新时间值
p=(unsigned char xdata *)(FileIndex.FileName.NAME);
for(i=fileIndexPosition.ByteOfSec;i<fileIndexPosition.ByteOfSec+32;i++)
buffer[i]=*(p++);
mmc_writeblock(fileIndexPosition.secotor,buffer); //更新文件索引
}
/*------------------------------------------------------------
*函数名称:unsigned int get_clusterID(unsigned int currentCluster)
*功能描述: 从形式参数开始,找一个未用的簇,然后返回簇号
*形式参数:unsigned int
*返 回 值:unsigned int :簇号
*---------------------------------------------------------------*/
unsigned int get_freeClusterID(unsigned int currentCluster)
{
unsigned char xdata flag=0;
unsigned int xdata i;
unsigned int xdata j;
unsigned int xdata offset;
unsigned int xdata *pcluster;
unsigned int clusterID=0;
offset = currentCluster/256;
for(i=offset;i< BPB.BPB_FATSz16;i++)
{
//喂狗
WDTCN=0xa5;
mmc_readblock(FAT1_FirstSector+i,buffer);
pcluster=(unsigned int xdata *)buffer; //转换为整型指针给pcluster
if(i== offset)
j=currentCluster%256;
else
j=0;
while(j<256)
{
//喂狗
WDTCN=0xa5;
if(*(pcluster+j) == 0)
{
flag=1;
break;
}
else
j++;
}
if(flag==1)
{
flag=0;
break;
}
}
clusterID=256*i+j;
return clusterID;
}
/*------------------------------------------------------------
*函数名称:unsigned int get_freeRom()
*功能描述:由基本参数,计算MMC卡中剩余的空间,返回值以M为单位
*形式参数:void
*返 回 值:空闲的空间,单位为M
*---------------------------------------------------------------*/
unsigned int get_freeRom()
{
unsigned int rom=0; //空闲的空间
unsigned long value=0; //注意数值间的转换运算
//喂狗
WDTCN=0xa5;
value =get_freeCluster();
//喂狗
WDTCN=0xa5;
value *= (BPB.BPB_SecPerClus*BPB.BPB_BytsPerSec);
//喂狗
WDTCN=0xa5;
rom = (int)(value/1000000);
return rom;
}
/*------------------------------------------------------------
*函数名称:unsigned int get_freeCluster()
*功能描述:在FAT1表中查找空闲的簇,并返回空闲簇的簇数
*形式参数:void
*返 回 值:空闲簇的簇数
*---------------------------------------------------------------*/
unsigned int get_freeCluster()
{
unsigned int xdata i;
unsigned int xdata j;
unsigned int freeClusterNum = 0; //空闲簇计数
unsigned int value = 0; //提取FAT中对应簇的值
for(i=0;i<BPB.BPB_FATSz16;i++)
{
mmc_readblock(FAT1_FirstSector+i,buffer);
//喂狗
WDTCN=0xa5;
for(j=0;j<256;j++)
{
//喂狗
WDTCN=0xa5;
value = *(int *)(buffer+2*j);
if(value == 0)
freeClusterNum++;
}
}
return freeClusterNum;
}
/*------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -