📄 osfile.c
字号:
*****************************************/
void DeleteFATList(unsigned int Cluster)
{
unsigned int NxtCluster;
switch(FAT_TYPE){
case FAT12:
while(((Cluster&0xfff)!=0xfff) && (Cluster!=0)){
NxtCluster=NextCluster(Cluster);
if(Cluster%2==0) {
FileSystemFAT[Cluster*3/2]=0;
FileSystemFAT[(Cluster*3/2)+1]&=0xf0; //清空FAT中高8位的低半字节
}
else {
FileSystemFAT[(Cluster*3/2)]&=0xf; //清空FAT中低8位的高半字节
FileSystemFAT[Cluster*3/2+1]=0;
}
Cluster=NxtCluster;
}
break;
}
}
/****************************************
读取根目录表到缓冲区中
*****************************************/
void ReadFileRoot2Mem()
{
int j;
//从根目录表的第一个扇区开始读取
int i=BootSector+RsdSector+2*SectorofFatSize;
unsigned char *p=(unsigned char*)FileSystemRoot;
for(j=0;j<RootEntry*32/BytesPerSec;j++,i++){
ReadPage(Begin_Cluster+i/PagePerClus,i%PagePerClus, p);
p+=512;
}
}
/****************************************
从根目录表到缓冲区写入到Flash中
*****************************************/
void WriteFileRootFromMem()
{
INT8U err;
unsigned char *pbuffer;
unsigned int StSector, nSector;
unsigned int block, lastrootSector;
unsigned char *p=(unsigned char*)FileSystemRoot;
//TODO:
//根目录表的第一个扇区
pbuffer=(unsigned char*)OSMemGet(pFileMem,&err);//由于需要缓冲区,故创建一个指针
StSector=BootSector+RsdSector+2*SectorofFatSize;
block=StSector/PagePerClus;
lastrootSector=RootEntry*32/BytesPerSec;
for(; lastrootSector>0; lastrootSector-=nSector){
//一个Page中,从i的起始到page结束,或者剩余的rootsector个数的Sector数目
nSector=min(PagePerClus-(StSector%PagePerClus), lastrootSector);
memcpy(pbuffer+StSector*512,p,512*nSector);
Write2Flash(Begin_Cluster+block, StSector, StSector+nSector, pbuffer);
block++;
p+=512*PagePerClus;
StSector=0; //以后的起始扇区始终为0
}
OSMemPut(pFileMem, pbuffer);
}
//以上代码完成文件分配表和根目录表在介质和内存之间的缓存
/*################################################################*/
/****************************************
转换8.3格式的文件名为
含有空格的11个字符的文件名
如果没有.字符(非8.3格式),则直接返回
*****************************************/
void FormatFileName(char outfilename[], char infilename[])
{
int i;
char *pch=infilename;
for(i=0;i<11 && *pch && *pch!='.'; i++){
outfilename[i]=*pch;
pch++;
}
if(i==11 && *pch!='.'){
memcpy(outfilename,infilename,11);
return;
}
//找到. 位置在i
if(i<8)
memset(outfilename+i,' ',8-i);
pch++;
for(i=0;i<3 && *pch ;i++){
*(outfilename+8+i)=*pch;
pch++;
}
if(i<3)
memset(outfilename+8+i,' ',3-i);
}
char mytoupper(char c)
{
if(c>='a' && c<='z')//小写字母则转换成大写
return c-0x20;
return c;
}
/****************************************
不区分大小写字母的比较
如果相同则返回0,如果m1>m2则返回值>0,如果m1<m2则返回值<0
*****************************************/
int MemcmpNoUpper(char* m1, char *m2, int n)
{
for(;mytoupper(*m1)==mytoupper(*m2);n--){
m1++;
m2++;
if(n==1) return 0;
}
return *m1-*m2;
}
//<-----------by threewater
/****************************************
按照扇区(Page)写入Flash,
参数:
block 表示Nand Flash中Block的位置
StSector 表示Nand Flash中写入的起始扇区
EnSector 表示Nand Flash中写入的结束扇区(写入数据包含该扇区)
ClusterBuf 表示写入数据,以Block的大小为单位对齐
*****************************************/
//add by threewater ------>
/****************************************
擦除文件系统的簇,根据分区表信息自动计算文件系统的
簇的大小,并擦除。
*****************************************/
void Erase_FileCluster(unsigned int filecluster)
{
//计算文件系统中的一个Cluster相当于几个实际的Nand Flash的Block,
//Nand Flash的Block大小为16KB
int n=SecPerClus*BytesPerSec/(PagePerClus*BytesPerPage);
int i;
for(i=0;i<n;i++)
Erase_Cluster(Begin_Cluster+(filecluster-1)*n+i);
}
/****************************************
向缓冲区中的FAT表写入数据
*****************************************/
void Write2MemFat(unsigned int Cluster, unsigned int data)
{
switch(FAT_TYPE){
case FAT12:
if(Cluster%2==0) {
FileSystemFAT[Cluster*3/2]=data;
data>>=8;
data&=0xf;
FileSystemFAT[(Cluster*3/2)+1]&=0xf0;
FileSystemFAT[(Cluster*3/2)+1]|=data; //写入FAT中高8位的低半字节
}
else {
FileSystemFAT[(Cluster*3/2)]&=0x0f;
FileSystemFAT[(Cluster*3/2)] |= ((data<<4)&0xf0); //写入FAT中低8位的高半字节
FileSystemFAT[Cluster*3/2+1] = (data>>4);
}
break;
}
}
//<------add by threewater
int initOSFile()
{
INT8U err;
pFileMem=OSMemCreate(FileMemPart,10, sizeof(OSFILE), &err);
if(pFileMem==NULL){
DPRINTK("Failed to Create OSFILE quote\n");
DPRINTK("Failed to Create OSFILE quote\n");
}
return Init_FAT_Info(FILESYSTEM_AUTOFORMAT);
}
OSFILE* OpenOSFile(char filename[], U32 OpenMode)
{
int i=0,j=0;
U32 Pre_Cluster;
unsigned int CurrentSector,nFileLength,SecNumOfClus;
// short int EmptyDIRSector,EmptyDIREntry;
OSFILE* pfile;
INT8U err;
char filename1[12]={0};
int emptyrootpos=-1; //空根目录处
FormatFileName(filename1,filename);
for(j=0; j<RootEntry;j++){ //每个扇区有多个目录项
if( (FileSystemRoot[j].filename[0]==0 || FileSystemRoot[j].filename[0]==OSFILE_DELETEMARK)
&& emptyrootpos==-1)
emptyrootpos=j; //记录空根目录处
if(!MemcmpNoUpper(filename1, FileSystemRoot[j].filename,11)){ //如果找到某项符合条件
DPRINTK("\nFile %s found!",filename1);
pfile=(OSFILE*)OSMemGet(pFileMem,&err);
pfile->fileCluster=FileSystemRoot[j].cluster;
pfile->filesize=nFileLength=FileSystemRoot[j].filelength;
pfile->filebufnum=0;
pfile->fileCurpos=0;
pfile->filemode=OpenMode;
pfile->rootpos=j;
switch(OpenMode){
case FILEMODE_READ:
while((pfile->fileCluster!=0xffff)&&((pfile->fileCluster&0xfff)!=0xfff)&&(pfile->fileCluster!=0xffffffff)){
CurrentSector=(pfile->fileCluster-2)*SecPerClus+FirstDataSec;
for(SecNumOfClus=0;
(SecNumOfClus<SecPerClus)&&(pfile->filesize>pfile->filebufnum);
SecNumOfClus++)
{//读完文件,如果大于一簇,则先读一簇
ReadPage(Begin_Cluster+(CurrentSector+SecNumOfClus)/PagePerClus,(CurrentSector+SecNumOfClus)%PagePerClus,databuff);
if(nFileLength>512) memcpy(pfile->Buffer+pfile->filebufnum, databuff,512);
else memcpy(pfile->Buffer+pfile->filebufnum, databuff,nFileLength);
nFileLength-=512;
pfile->filebufnum+=512;
}
if(pfile->filebufnum>=Block_Size)
{//读到1个Block后即中止
pfile->filebufnum=0;//缓冲区指针重新指向开头
break;//缓冲区慢时中止
}
else pfile->fileCluster=NextCluster(pfile->fileCluster);//如果缓冲区没满则继续读
}
printk("\nFile %s have been read!",filename1);
pfile->filebufnum=0;//缓冲区指针重新指向开头
break;
case FILEMODE_WRITE:
if(pfile->filesize>0){//读出原有内容by frank Sep 21
while((pfile->fileCluster!=0xffff)&&(pfile->fileCluster!=0xfff)&&(pfile->fileCluster!=0xffffffff)){
CurrentSector=(pfile->fileCluster-2)*SecPerClus+FirstDataSec;
for(SecNumOfClus=0;(SecNumOfClus<SecPerClus)&&(pfile->filesize>pfile->filebufnum);SecNumOfClus++){//读完文件,如果大于一簇,则先读一簇
ReadPage(Begin_Cluster+(CurrentSector+SecNumOfClus)/PagePerClus,(CurrentSector+SecNumOfClus)%PagePerClus,databuff);
if(nFileLength>512) memcpy(pfile->Buffer+pfile->filebufnum, databuff,512);
else memcpy(pfile->Buffer+pfile->filebufnum, databuff,nFileLength);
nFileLength-=512;
pfile->filebufnum+=512;
}
if(pfile->filebufnum>=Block_Size) {//读到1个Block后即中止
pfile->filebufnum=0;//缓冲区指针重新指向开头
break;//缓冲区慢时中止
}
else {
Pre_Cluster=pfile->fileCluster;
pfile->fileCluster=NextCluster(pfile->fileCluster);//如果缓冲区没满则继续读
}
}
pfile->fileCluster=Pre_Cluster;
}
pfile->filebufnum=pfile->filesize%Block_Size;//指针指向末尾
// pfile->filesize=0;
for(i=pfile->filebufnum;i<Block_Size;i++)
pfile->Buffer[i]=0xff;
break;
default:
return NULL; //可能是创建模式,不能重名
}
return pfile; //找到文件
}
}//
if(OpenMode== (FILEMODE_WRITE|FILEMODE_CREATE) ){ //创建文件
//如果没有找到同名文件则创建文件,
//创建的时候先建立root目录的数据,在最后,Close的时候
//把数据写入root,所以,创建文件以后如果掉电,因为
//没有Close,所以,文件对root目录没有影响。----by threewater
DPRINTK("\nCreating OSFILE %s !",filename1);
pfile=(OSFILE*)OSMemGet(pFileMem,&err);
if(pfile) {
pfile->fileCluster=AllocateCluster(0);
DPRINTK("\nThe new cluster is %d",pfile->fileCluster);
pfile->filebufnum=0;
pfile->fileCurpos=0;
pfile->filemode=OpenMode;
}
else
return NULL;
if(pfile->fileCluster){
//接下来在刚才找到的空根目录处创建文件项
//by threewater----------->
memcpy(FileSystemRoot[emptyrootpos].filename, filename1, 11);
FileSystemRoot[emptyrootpos].Attribute=0x20;//Attribute
FileSystemRoot[emptyrootpos].time=0x1612;//Create time
FileSystemRoot[emptyrootpos].date=0x2ea2;//Create date
FileSystemRoot[emptyrootpos].cluster=pfile->fileCluster;
FileSystemRoot[emptyrootpos].filelength=0;
/*
databuff[j*32+11]=0x20;//Attribute
databuff[j*32+22]=0x12;//d6;//Create time
databuff[j*32+23]=0x16;//da;//MSB
databuff[j*32+24]=0xa2;//ae;//Create date
databuff[j*32+25]=0x2e;
databuff[j*32+26]=(pfile->fileCluster&0x000000ff);//first cluster
databuff[j*32+27]=((pfile->fileCluster&0x0000ff00)>>8);
databuff[j*32+28]=0x00;//OSFILE length
databuff[j*32+29]=0x0; //by threewater
databuff[j*32+30]=0;
databuff[j*32+31]=0;*/
pfile->filesize=0;
pfile->rootpos=emptyrootpos;
printk("\nCreat OSFILE %s Succeed!",filename1);
return pfile;
}
else{
//磁盘满
return NULL;
}
}
//没找到文件
DPRINTK("\nFile %s is not found!",filename1);
return NULL;
}
//add by threewater-------->
U8 DeleteOSFile(char filename[])
{
int j;
char filename1[12]={0};
FormatFileName(filename1,filename);
for(j=0;j<RootEntry && (FileSystemRoot[j].filename[0]!=0x00);j++){
if(!MemcmpNoUpper(filename1, FileSystemRoot[j].filename,11)){ //如果找到某项符合条件
FileSystemRoot[j].filename[0]=OSFILE_DELETEMARK;
DeleteFATList(FileSystemRoot[j].cluster);
WriteFATFromMem();// write to Flash
WriteFileRootFromMem();
printk("\nFile %s have been Deleted!",filename1);
return TRUE;
}
}
printk("\nFile %s is not exist!\n",filename1);
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -