📄 api.c
字号:
#include "host_811.h"
#include "string.h"
#include "math.h"
extern struct _FILE ApiFileControl;
extern struct _BPB SimpleBpb;
extern FAT_PARAMETER FatParameter;
extern UINT8 BuffFile[8*512];
extern UINT16 FatCache[2][256];
extern UINT8 buf1[1024],buf2[1024];
extern UINT8 buf[512];
extern UINT8 Cache[512];
extern UINT8 USB_FILE[];
//Function defined
UINT8 CreateFile(char* filename, UINT8 attribute);
UINT8 OpenFile( char* filename);
UINT8 ReadFile(void* buffer, /*UINT*/UINT16 bytes);
UINT8 WriteFile( char* buffer, /*UINT*/UINT16 bytes);
UINT8 AddWriteFile( char* buffer, /*UINT*/UINT16 bytes);
UINT8 ApiDemo(void);
UINT8 SetFileSector( char *filename,UINT32 fileSector,UINT32 offset);
UINT8 DisplayFile(void);
UINT8 DelFile(char * filename);
UINT8 CreateDir(char * dirname);
//**************************************************
extern UINT32 SeekSector(UINT32 Sector, char dirname[11],struct _FILE *file);
extern UINT16 LinkClusterList(UINT16 Cluster);
extern UINT16 SeekEmptyCluster(void);
extern UINT16 GetListCluster(UINT16 Cluster);
extern UINT32 ClusterToSec(UINT16 Cluster);
extern UINT16 SecToCluster(UINT32 Sector);
extern UINT8 CheckFileName(char * filename, UINT8 dirname[11]);
extern UINT8 LocateDir(struct _DIR* new_dir, struct _FILE * fp);
extern UINT32 LocateFile( char *filename, struct _FILE *file);
extern UINT8 Write(UINT32 dlba,UINT8 blen,UINT8 *pbBuffer);
extern UINT8 Read(UINT32 dlba,UINT8 blen,UINT8 *pbBuffer);
extern void DelayMs(UINT8 nFactor);
extern UINT16 WordSwap(UINT16 input);
extern UINT32 DWordSwap(UINT32 dData);
//********************************************************
UINT8 CreateFile(char* filename, UINT8 attribute)
{
struct _DIR dir,*pdir;
UINT8 name[11];
struct _FILE file;
// UINT16 NewCluster;
char NewFileName[12];
char * p=NewFileName;
////////////////////////////////////////////////////////////////////////
//*Get valid filen name
if(!CheckFileName(filename,p))
return FALSE;
//*核对该文件是否已经存在
if(LocateFile(filename, NULL)!=0xffffffff)
return FALSE;
strncpy(name, p, 11);
memset(&dir, 0, sizeof(dir));
memcpy(dir.Name, name, 11);
dir.Attr = attribute;
dir.CrtDate =0;
dir.CrtTime =0;
dir.CrtTimeTenth =0;
dir.FileSize =0;
DelayMs(10);
if(!LocateDir(&dir, &file))
return FALSE;
// NewCluster=SeekEmptyCluseter();
// if(NewCluster==0xffff)
// return FALSE;
DelayMs(15);
if(!Read(file.DirSectorNum,1,(UINT8 *)Cache))
return FALSE;
pdir = (struct _DIR *)Cache;
pdir += file.DirIndex;
pdir->FstClusLO =0x00;//WordSwap(NewCluster);
pdir->FileSize=0;
if(!Write(file.DirSectorNum,1,(UINT8 *)Cache))
if(!Write(file.DirSectorNum,1,(UINT8 *)Cache))
return FALSE;
return OpenFile(filename);
}
UINT8 WriteFile(char* buffer, /*UINT*/UINT16 bytes)
{
UINT8 *pCache;
UINT16 *p16;
/*UINT*/UINT16 write_bytes =0,flag=0;
/*UINT*/UINT16 max_write_bytes_in_sector;
UINT16 Cluster;
////////////////////////////////////////////////////////////////////////
//如果打开的文件是一个空文件,则进入下面
//为其寻找一个开始的数据蔟,标记为0xffff
//数据直接填在该簇对应的扇区内
if(ApiFileControl.StartSectorNum<FatParameter.FirstDataSector)
{
Cluster=SeekEmptyCluster();
if(!Read(FatParameter.FirstFatSecNum+(2*Cluster/SimpleBpb.BytsPerSec),1,(UINT8 *)Cache))
return FALSE;
p16 = (UINT16 *)Cache;
//Cache[Cluster%(SimpleBpb.BytsPerSec/2)]=0xffff;
*(p16+Cluster%(SimpleBpb.BytsPerSec/2))=0xffff;
if(!Write(FatParameter.FirstFatSecNum+(2*Cluster/SimpleBpb.BytsPerSec),1,(UINT8 *)Cache))
return FALSE;
ApiFileControl.dir.FstClusLO=/*WordSwap*/(Cluster);
ApiFileControl.StartSectorNum=ApiFileControl.CurrentSectorNum=ClusterToSec(Cluster);
flag=1;
}
///////////////////////////////////////////////////////////////////////////////
//
//如过前一个WriteFile函数的字节或者打开一个已经有为内容的文件的字节偏移刚好为
//SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus的整数倍,为了保持总的算法一致
//(都是先写好某簇为0xffff然后再写该簇的内容)则开始的时候必须先为其准备好
//一个未有内容的簇,标记好为0xffff,然后数据直接填在该簇对应的扇区内。
//
//////////////////////////////////////////////////////////////////////////////
if((ApiFileControl.SectorOffset==0)&&flag==0)
{
Cluster =LinkClusterList(SecToCluster(ApiFileControl.CurrentSectorNum));
if(Cluster == 0xffff)
return FALSE;
ApiFileControl.CurrentSectorNum = ClusterToSec(Cluster);
}
for(;;)
{
pCache=BuffFile;
pCache += ApiFileControl.SectorOffset;
if((SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus - ApiFileControl.SectorOffset) > (bytes - write_bytes))
max_write_bytes_in_sector = (bytes - write_bytes);
else
max_write_bytes_in_sector=(SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus - ApiFileControl.SectorOffset);
memcpy(pCache, buffer, max_write_bytes_in_sector);
ApiFileControl.SectorOffset += max_write_bytes_in_sector;
if(ApiFileControl.SectorOffset>=SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus)
{
if(!Write(ApiFileControl.CurrentSectorNum,SimpleBpb.SecPerClus,(UINT8*)BuffFile))
if(!Write(ApiFileControl.CurrentSectorNum,SimpleBpb.SecPerClus,(UINT8*)BuffFile))
return FALSE;
if((write_bytes+max_write_bytes_in_sector)<bytes)
{
Cluster =LinkClusterList(SecToCluster(ApiFileControl.CurrentSectorNum));
if(Cluster == 0xffff)
return FALSE;
ApiFileControl.CurrentSectorNum = ClusterToSec(Cluster);
}
ApiFileControl.SectorOffset = 0;
}
write_bytes += max_write_bytes_in_sector;
buffer = (char*)buffer + max_write_bytes_in_sector;
ApiFileControl.dir.FileSize += max_write_bytes_in_sector;
if(write_bytes >= bytes)
return TRUE;
}//end for cycle
return FALSE;
}
UINT8 AddWriteFile( char* buffer, /*UINT*/UINT16 bytes)
{
/*UINT*/UINT16 write_bytes =0;
/*UINT*/UINT16 max_write_bytes_in_sector;
////////////////////////////////////////////////////////////////////////
// UINT16 Cluster;
// UINT32 Sector;
UINT8 *pCache;
// UINT8 BuffFile[4*512];
/////////////////////////////////////////////////////////////////////////////
//
//****如果文件的大小不是SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus
//的整数倍,则进入下面的语句可以保证加写的东西精确到到字节
//
//////////////////////////////////////////////////////////////////////////////
if(0<ApiFileControl.SectorOffset<SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus)
{
pCache=BuffFile;
if((SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus - ApiFileControl.SectorOffset) > (bytes - write_bytes))
max_write_bytes_in_sector = (bytes - write_bytes);
else
max_write_bytes_in_sector=(SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus - ApiFileControl.SectorOffset);
// Cluster=SecToCluster(ApiFileControl.CurrentSectorNum);
// Sector=ClusterToSec(Cluster);
if(!Read(ApiFileControl.CurrentSectorNum,SimpleBpb.SecPerClus,(UINT8 *)BuffFile))
return FALSE;
pCache += ApiFileControl.SectorOffset;
memcpy(pCache, buffer, max_write_bytes_in_sector);
if(!Write(ApiFileControl.CurrentSectorNum,SimpleBpb.SecPerClus,(UINT8 *)BuffFile))
if(!Write(ApiFileControl.CurrentSectorNum,SimpleBpb.SecPerClus,(UINT8 *)BuffFile))
return FALSE;
write_bytes += max_write_bytes_in_sector;
buffer = (char*)buffer + max_write_bytes_in_sector;
ApiFileControl.dir.FileSize += max_write_bytes_in_sector;
if((bytes-max_write_bytes_in_sector)>0)
ApiFileControl.SectorOffset=0;
}
if(!WriteFile(buffer,(bytes -write_bytes)))
return FALSE;
return TRUE;
}
UINT8 OpenFile( char* filename)
{
UINT32 FileFirstSector;
UINT16 Cluster;
////////////////////////////////////////////////////////////////////////
FileFirstSector=LocateFile(filename, &ApiFileControl);
if(FileFirstSector==0xffffffff)
return FALSE;
ApiFileControl.StartSectorNum = FileFirstSector;
Cluster=/*WordSwap*/(ApiFileControl.dir.FstClusLO);
for(;;)
{
if((GetListCluster(Cluster)==0xffff)||(Cluster==0))
break;
Cluster=GetListCluster(Cluster);
}
//ApiFileControl.CurrentSectorNum为该簇对应的第一个扇区
ApiFileControl.CurrentSectorNum = ClusterToSec(Cluster);
ApiFileControl.SectorOffset=(DWordSwap(ApiFileControl.dir.FileSize)%(SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus));
ApiFileControl.dir.FileSize=DWordSwap(ApiFileControl.dir.FileSize);
return TRUE;
}
UINT8 ReadFile(void* buffer, /*UINT*/UINT16 bytes)
{
UINT8*pCache;
/*UINT*/UINT16 read_bytes =0;
/*UINT*/UINT16 max_copy_bytes_in_sector;
UINT16 Cluster,i;
UINT32 FileSize;
////////////////////////////////////////////////////////////////////////
FileSize = ApiFileControl.dir.FileSize;
if(bytes>=FileSize)
bytes=FileSize;
Cluster=SecToCluster(ApiFileControl.CurrentSectorNum);
// Sector=ClusterToSec(Cluster);
ApiFileControl.SectorOffset=ApiFileControl.SectorOffset%(SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus);
for(; ; )
{
pCache=BuffFile;
pCache+=ApiFileControl.SectorOffset;
if((SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus - ApiFileControl.SectorOffset) > (bytes - read_bytes))
max_copy_bytes_in_sector = (bytes - read_bytes);
else
max_copy_bytes_in_sector=(SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus - ApiFileControl.SectorOffset);
ApiFileControl.SectorOffset+=max_copy_bytes_in_sector;
if(!Read(ApiFileControl.CurrentSectorNum,SimpleBpb.SecPerClus,(UINT8 *)BuffFile))
return FALSE;
memcpy((char *)buffer, pCache, max_copy_bytes_in_sector);
// return TRUE;
read_bytes+=max_copy_bytes_in_sector;
if(read_bytes>=bytes)
return TRUE;
buffer = (char*)buffer + max_copy_bytes_in_sector;
Cluster=GetListCluster(Cluster);
ApiFileControl.SectorOffset=0;
ApiFileControl.CurrentSectorNum=ClusterToSec(Cluster);
}//---------end for cycle
return FALSE;
}
UINT8 CloseFile()
{
//UINT8 Cache[512];
struct _DIR *dir;
////////////////////////////////////////////////////////////////////////
if(ApiFileControl.SectorOffset!=0)
{
if(!Write(ApiFileControl.CurrentSectorNum,SimpleBpb.SecPerClus,(unsigned char *)BuffFile))
if(!Write(ApiFileControl.CurrentSectorNum,SimpleBpb.SecPerClus,(unsigned char *)BuffFile))
return FALSE;
}
DelayMs(50);
if(!Read(ApiFileControl.DirSectorNum,1,Cache))
if(!Read(ApiFileControl.DirSectorNum,1,Cache))
return FALSE;
dir = (struct _DIR *)Cache;
dir += ApiFileControl.DirIndex;
ApiFileControl.dir.FileSize=DWordSwap(ApiFileControl.dir.FileSize);
memcpy(dir, &ApiFileControl.dir, sizeof(struct _DIR));
DelayMs(50);
if(!Write(ApiFileControl.DirSectorNum,1,Cache))
if(!Write(ApiFileControl.DirSectorNum,1,Cache))
return FALSE;
if(FatCache[0][256]!=0)
{
if(!Write(FatCache[0][256],1,(UINT8 *)FatCache[0]))
if(!Write(FatCache[0][256],1,(UINT8 *)FatCache[0]))
return FALSE;
}
return TRUE;
}
UINT8 SetFileSector( char * filename,UINT32 fileSector,UINT32 offset)
{
UINT32 FileFirstSector;
UINT16 Cluster;
////////////////////////////////////////////////////////////////////////
FileFirstSector=LocateFile(filename, &ApiFileControl);
if(FileFirstSector==0xffffffff)
return FALSE;
ApiFileControl.StartSectorNum = FileFirstSector;
Cluster=WordSwap(ApiFileControl.dir.FstClusLO);
for(;;)
{
if((GetListCluster(Cluster)==0xffff)||(Cluster==0))
break;
Cluster=GetListCluster(Cluster);
}
//ApiFileControl.CurrentSectorNum为该簇对应的第一个扇区
//扇区号移到到了该文件最后一簇的第一个扇区
if((ClusterToSec(Cluster))>=fileSector>=0)
ApiFileControl.CurrentSectorNum =fileSector;
else
return FALSE;
ApiFileControl.SectorOffset=offset;
// ApiFileControl.SectorOffset=(DWordSwap(ApiFileControl.dir.FileSize)%(SimpleBpb.BytsPerSec*SimpleBpb.SecPerClus));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -