打印

znFAT移植与使用手册

[复制链接]
1236|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zheng522|  楼主 | 2015-4-23 23:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以前用守的的FAT32文件系统。

znFAT移植与使用手册.rar

274.64 KB

沙发
zheng522|  楼主 | 2015-4-23 23:30 | 只看该作者
后面有时间了,我在CY的单片机上移植下,给大家分享下。

使用特权

评论回复
板凳
zheng522|  楼主 | 2015-4-23 23:36 | 只看该作者
上传一个以前做的程序

znfat541.rar

282.53 KB

使用特权

评论回复
地板
波越| | 2015-4-25 10:37 | 只看该作者
关注下

使用特权

评论回复
5
zheng522|  楼主 | 2015-4-25 10:40 | 只看该作者
/**************************************************************************
- 功能描述:创建文件(支持任意层目录创建)
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:pfi:一个指向FileInfoStruct类型的结构体的指针,用来装载新创建的
             文件信息,因此新创建的文件不用再打开就可以直接来操作
             filepath:文件路径 比如 "\\dir1\\dir2\\dir3\\....\\dirn\\test.txt"
- 返回说明:0:成功 1:文件已存在 2:创建文件目录失败 3:创建文件失败
- 注:如果文件路径中某一个中间目录不存在,那么此函数会创建这个目录,再继续
       去创建更深层的目录,一直到最后把文件创建完成。
       创建文件失败有可能是因为存储设备空间不足,或是此文件已经存在
**************************************************************************/
#ifdef ZNFAT_CREATE_FILE

UINT8 znFAT_Create_File(struct FileInfoStruct *pfi,CONST INT8 *filepath,UINT8 *ptd)
{
    if (znFAT_Open_File(pfi,filepath,0,1))
    {
        if (!znFAT_Create_Dir(filepath,ptd))
        {
            if (znFAT_Create_Rec(pfi,temp_dir_cluster,temp_dir_name,0,ptd)==(UINT8)(-1))
            {
                return 3;
            }
        }
        else
        {
            return 2;
        }
    }
    else
    {
        return 1;
    }
    return 0;
}

#endif

使用特权

评论回复
6
zheng522|  楼主 | 2015-4-25 10:41 | 只看该作者
/**************************************************************************
- 功能描述:在存储设备中创建一个文件/目录项
- 隶属模块:znFAT文件系统模块
- 函数属性:内部
- 参数说明:pfi:指向FileInfoStruct类型的结构体,用于装载刚创建的文件的信息
                 也就是说,如果创建的是目录,则此结构体不会被更新
             cluster:在cluster这个簇中创建文件/目录项,用于实现在任意目录下
                 创建文件或目录,可以通过znFAT_Enter_Dir来获取某一个目录的开
                 始簇
             name:文件/目录的名称
             is_dir:指示要创建的是文件还是目录,文件与目录的创建方法是不同的
                 1表示创建目录 0表示创建文件
- 返回说明:成功返回1,失败返回-1
**************************************************************************/
#ifdef ZNFAT_CREATE_REC

UINT8 znFAT_Create_Rec(struct FileInfoStruct *pfi,UINT32 cluster,INT8 *name,UINT8 is_dir,UINT8 *ptd)
{
    UINT32 iSec,iRec,temp_sec,temp_clu,new_clu,i,old_clu;
    UINT8 flag=0;
    UINT16 temp_Rec;

    struct direntry *pRec;
    struct File_Dir_Items *pitems;

    Fill_Rec_Inf(&temp_rec,name,is_dir,ptd);

    do
    {
        old_clu=cluster;
        temp_sec=SOC(cluster);
        for (iSec=temp_sec;iSec<(temp_sec+pArg->SectorsPerClust);iSec++)
        {
            znFAT_ReadSector(iSec,znFAT_Buffer);
            pitems=(struct File_Dir_Items *)znFAT_Buffer;

            for (iRec=0;iRec<FILE_DIR_ITEM_NUM;iRec++)
            {
                pRec=&(pitems->file_dir_items[iRec]);

                if ((pRec->deName)[0]==0) //空目录项 //需求建新簇时清空簇
                {
                    flag=1;
                    if (is_dir) //如果是目录,需要给它建立新簇,为了写入.和..
                    {
                        if (!(new_clu=znFAT_Find_Free_Clust(0))) return (UINT8)(-1);         //减少一个空簇
                        znFAT_Modify_FAT(new_clu,0x0fffffff);

                        (temp_rec.deHighClust)[0]=(new_clu&0x00ff0000)>>16;
                        (temp_rec.deHighClust)[1]=(new_clu&0xff000000)>>24;
                        (temp_rec.deLowCluster)[0]=(new_clu&0x000000ff);
                        (temp_rec.deLowCluster)[1]=(new_clu&0x0000ff00)>>8;
                    }
                    znFAT_ReadSector(iSec,znFAT_Buffer);
                    for (i=0;i<FILE_DIR_ITEM_SIZE;i++) //把填充好的文件目录项写入扇区
                    {
                        ((UINT8 *)pRec)[i]=((UINT8 *)(&temp_rec))[i];
                    }
                    znFAT_WriteSector(iSec,znFAT_Buffer);
                    temp_sec=iSec;
                    temp_Rec=iRec;
                    iRec=FILE_DIR_ITEM_NUM; //这两句是为了跳出循环
                    //break;
                    iSec=temp_sec+pArg->SectorsPerClust;
                }
            }
        }
    }
    while (!flag && (cluster=znFAT_GetNextCluster(cluster))!=0x0fffffff);

    if (!flag)
    {
        if (!(temp_clu=znFAT_Find_Free_Clust(0))) return (UINT8)(-1);
        //printf("temp_clu:%d\n",temp_clu);
        znFAT_Modify_FAT(temp_clu,0x0fffffff);
        znFAT_Modify_FAT(old_clu,temp_clu);
        temp_sec=SOC(temp_clu);
        temp_Rec=0;
        znFAT_ReadSector(temp_sec,znFAT_Buffer);
        if (is_dir)
        {
            if (!(new_clu=znFAT_Find_Free_Clust(0))) return (UINT8)(-1);
            znFAT_Modify_FAT(new_clu,0x0fffffff);
            znFAT_ReadSector(temp_sec,znFAT_Buffer);
            (temp_rec.deHighClust)[0]=(new_clu&0x00ff0000)>>16;
            (temp_rec.deHighClust)[1]=(new_clu&0xff000000)>>24;
            (temp_rec.deLowCluster)[0]=(new_clu&0x000000ff);
            (temp_rec.deLowCluster)[1]=(new_clu&0x0000ff00)>>8;
        }
        for (i=0;i<FILE_DIR_ITEM_SIZE;i++)
        {
            znFAT_Buffer[i]=((UINT8 *)(&temp_rec))[i];
        }
        znFAT_WriteSector(temp_sec,znFAT_Buffer);
    }

    if (is_dir)
    {
        znFAT_Empty_Cluster(new_clu);
        //printf("cur_clu:%d\n",new_clu);

        Fill_Rec_Inf(&temp_rec,".",1,ptd);
        (temp_rec.deHighClust)[0]=(new_clu&0x00ff0000)>>16;
        (temp_rec.deHighClust)[1]=(new_clu&0xff000000)>>24;
        (temp_rec.deLowCluster)[0]=(new_clu&0x000000ff);
        (temp_rec.deLowCluster)[1]=(new_clu&0x0000ff00)>>8;
        for (i=0;i<FILE_DIR_ITEM_SIZE;i++)
        {
            znFAT_Buffer[i]=((UINT8 *)(&temp_rec))[i];
        }
        Fill_Rec_Inf(&temp_rec,"..",1,ptd);
        if (cluster==pArg->FirstDirClust)
        {
            (temp_rec.deHighClust)[0]=0;
            (temp_rec.deHighClust)[1]=0;
            (temp_rec.deLowCluster)[0]=0;
            (temp_rec.deLowCluster)[1]=0;
        }
        else
        {
            (temp_rec.deHighClust)[0]=(old_clu&0x00ff0000)>>16;
            (temp_rec.deHighClust)[1]=(old_clu&0xff000000)>>24;
            (temp_rec.deLowCluster)[0]=(old_clu&0x000000ff);
            (temp_rec.deLowCluster)[1]=(old_clu&0x0000ff00)>>8;
        }

        for (i=FILE_DIR_ITEM_SIZE;i<2*FILE_DIR_ITEM_SIZE;i++)
        {
            znFAT_Buffer[i]=((UINT8 *)(&temp_rec))[i-FILE_DIR_ITEM_SIZE];
        }
        //for(;i<pArg->BytesPerSector;i++) //再次清空,重复操作
        //{
        //znFAT_Buffer[i]=0;
        //}
        temp_sec=SOC(new_clu);
        znFAT_WriteSector(temp_sec,znFAT_Buffer);
    }
    else
    {
        StringCopy(pfi->FileName,name);
        pfi->FileStartCluster=0;
        pfi->FileCurCluster=0;
        pfi->FileSize=0;
        pfi->FileCurSector=0;
        pfi->FileCurPos=0;
        pfi->FileCurOffset=0;
        pfi->Rec_Sec=temp_sec;
        pfi->nRec=temp_Rec;

        pfi->FileAttr=temp_rec.deAttributes; //属性
    }
    znFAT_Find_Free_Clust(1);
    return 1;
}

#endif

使用特权

评论回复
7
zheng522|  楼主 | 2015-4-25 10:41 | 只看该作者
/**************************************************************************
- 功能描述:向某一个文件追加数据
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:pfi:指向FileInfoStruct类型的结构体,用于装载刚创建的文件的信息
             len:要追加的数据长度
             pbuf:指向数据缓冲区的指针
- 返回说明:成功返回实际写入的数据长度,失败返回0
- 注:追加数据失败很有可能是存储设备已经没有空间了,也就是找不到空闲簇了
**************************************************************************/
#ifdef ZNFAT_ADD_DAT

UINT32 znFAT_Add_Dat(struct FileInfoStruct *pfi,UINT32 len,UINT8 *pbuf)
{
    UINT32 i=0,counter=0,iSec,iClu;
    UINT32 temp_sub,temp_file_size,new_clu,temp_sec;

    struct direntry *prec;
    if (len>0)
    {
        znFAT_ReadSector(pfi->Rec_Sec,znFAT_Buffer);
        prec=((struct direntry *)(znFAT_Buffer))+pfi->nRec;

        temp_file_size=LE2BE((prec->deFileSize),4);

        if (!temp_file_size)
        {

            if (!(new_clu=znFAT_Find_Free_Clust(0))) return 0;

            znFAT_Modify_FAT(new_clu,0x0fffffff);

            pfi->FileStartCluster=new_clu;
            pfi->FileCurCluster=pfi->FileStartCluster;
            pfi->FileSize=0;
            pfi->FileCurSector=SOC(pfi->FileCurCluster);
            pfi->FileCurPos=0;
            pfi->FileCurOffset=0;
            znFAT_ReadSector(pfi->Rec_Sec,znFAT_Buffer);
            (prec->deHighClust)[0]=(new_clu&0x00ff0000)>>16;
            (prec->deHighClust)[1]=(new_clu&0xff000000)>>24;
            (prec->deLowCluster)[0]=(new_clu&0x000000ff);
            (prec->deLowCluster)[1]=(new_clu&0x0000ff00)>>8;
            znFAT_WriteSector(pfi->Rec_Sec,znFAT_Buffer);
        }
        else
        {
            if (!(temp_file_size%(pArg->SectorsPerClust*pArg->BytesPerSector))) //在簇的最末尾临界地方,需要寻找新簇
            {
                znFAT_Seek_File(pfi,pfi->FileSize-1); //@@@待优化
                if (!(new_clu=znFAT_Find_Free_Clust(0))) return 0;
                znFAT_Modify_FAT(pfi->FileCurCluster,new_clu);
                znFAT_Modify_FAT(new_clu,0x0fffffff);
            }
            znFAT_Seek_File(pfi,pfi->FileSize);
        }



        //iSec=pfi->FileCurSector;

        znFAT_ReadSector(pfi->FileCurSector,znFAT_Buffer);

        for (i=pfi->FileCurPos;i<pArg->BytesPerSector;i++)
        {
            znFAT_Buffer[i]=pbuf[counter];
            counter++;
            if (counter>=len)
            {
                iSec=pfi->FileCurSector;
                goto end;
            }
        }
        znFAT_WriteSector(pfi->FileCurSector,znFAT_Buffer); //数据接缝,把上次扇区剩余字节填充完

        //printf("here1\n");

        if ((pfi->FileCurSector-(SOC(pfi->FileCurCluster)))<(pArg->SectorsPerClust-1)) //判断是不是一个簇的最后一个扇区,先将当前簇所有扇区填满
        {
            for (iSec=pfi->FileCurSector+1;iSec<=(SOC(pfi->FileCurCluster)+pArg->SectorsPerClust-1);iSec++)
            {
                for (i=0;i<pArg->BytesPerSector;i++)
                {
                    znFAT_Buffer[i]=pbuf[counter];
                    counter++;
                    //printf("##-->%d\n$$-->%d\n",counter,pbuf[counter]);
                    if (counter>=len)
                    {
                        goto end;
                    }
                }
                znFAT_WriteSector(iSec,znFAT_Buffer);
            }
        }
        //printf("here2\n");

        temp_sub=len-counter;
        for (iClu=0;iClu<temp_sub/(pArg->SectorsPerClust*pArg->BytesPerSector);iClu++)
        {
            if (!(new_clu=znFAT_Find_Free_Clust(0))) return 0;
            znFAT_Modify_FAT(pfi->FileCurCluster,new_clu);
            znFAT_Modify_FAT(new_clu,0x0fffffff);
            pfi->FileCurCluster=new_clu;

            temp_sec=SOC(new_clu);
            for (iSec=temp_sec;iSec<temp_sec+pArg->SectorsPerClust;iSec++)
            {
                for (i=0;i<pArg->BytesPerSector;i++)
                {
                    znFAT_Buffer[i]=pbuf[counter];
                    counter++;
                }
                znFAT_WriteSector(iSec,znFAT_Buffer);
            }
        }

        temp_sub=len-counter;
        if (temp_sub)
        {
            if (!(new_clu=znFAT_Find_Free_Clust(0))) return 0;
            znFAT_Modify_FAT(pfi->FileCurCluster,new_clu);
            znFAT_Modify_FAT(new_clu,0x0fffffff);
            pfi->FileCurCluster=new_clu;
            temp_sec=SOC(new_clu);
            for (iSec=temp_sec;iSec<temp_sec+temp_sub/pArg->BytesPerSector;iSec++)
            {
                for (i=0;i<pArg->BytesPerSector;i++)
                {
                    znFAT_Buffer[i]=pbuf[counter];
                    counter++;
                }
                znFAT_WriteSector(iSec,znFAT_Buffer);
            }
        }

        temp_sub=len-counter;
        if (temp_sub)
        {
            for (i=0;i<pArg->BytesPerSector;i++)
            {
                znFAT_Buffer[i]=pbuf[counter];
                counter++;
            }
            znFAT_WriteSector(iSec,znFAT_Buffer);
        }

end:
        //printf("here!\n");
        znFAT_WriteSector(iSec,znFAT_Buffer);

        znFAT_ReadSector(pfi->Rec_Sec,znFAT_Buffer);
        ((((struct direntry *)(znFAT_Buffer))+pfi->nRec)->deFileSize)[0]=((temp_file_size+len)&0x000000ff);
        ((((struct direntry *)(znFAT_Buffer))+pfi->nRec)->deFileSize)[1]=((temp_file_size+len)&0x0000ff00)>>8;
        ((((struct direntry *)(znFAT_Buffer))+pfi->nRec)->deFileSize)[2]=((temp_file_size+len)&0x00ff0000)>>16;
        ((((struct direntry *)(znFAT_Buffer))+pfi->nRec)->deFileSize)[3]=((temp_file_size+len)&0xff000000)>>24;
        znFAT_WriteSector(pfi->Rec_Sec,znFAT_Buffer);

        //printf("here pass\n");
        pfi->FileSize=(temp_file_size+len);
        pfi->FileCurSector=(pfi->FileSize%pArg->BytesPerSector)?iSec:iSec+1;
        pfi->FileCurPos=pfi->FileSize%pArg->BytesPerSector;
        pfi->FileCurOffset=pfi->FileSize;

        //printf("==============================================\n");
        //printf("FileSize:%d\n",pfi->FileSize);
        //printf("FileCurSector:%d\n",pfi->FileCurSector);
       // printf("FileCurPos:%d\n",pfi->FileCurPos);
       // printf("FileCurOffset:%d\n",pfi->FileCurOffset);
        //printf("==============================================\n");
    }

    znFAT_Find_Free_Clust(1);
    //printf("here end\n");
    return len;
}

#endif

使用特权

评论回复
8
zheng522|  楼主 | 2015-4-25 10:41 | 只看该作者
/**************************************************************************
- 功能描述:创建目录(支持任意层目录创建)
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:pfi:无用
             dirpath:目录路径 比如 "\\dir1\\dir2\\dir3\\....\\dirn\\"
             最后必须是\\结束
- 返回说明:成功返回0,失败返回1
- 注:如果中间某一级目录不存在,比如上面的这个路径中dir3不存在,那么此函数会
       创建这个目录,然后再继续去创建更深层的目录
       创建目录失败有可能是因为存储设备空间不足
**************************************************************************/
#ifdef ZNFAT_CREATE_DIR

UINT8 znFAT_Create_Dir(CONST INT8 *dirpath,UINT8 *ptd)
{
    struct FileInfoStruct *pfi;
    while (!znFAT_Enter_Dir(dirpath))
    {
        if (znFAT_Create_Rec(pfi,temp_dir_cluster,temp_dir_name,1,ptd)==(UINT8)(-1))
        {
            return 1;
        }
    }
    return 0;
}

#endif

使用特权

评论回复
9
zheng522|  楼主 | 2015-4-25 10:42 | 只看该作者
/**************************************************************************
- 功能描述:删除文件(支持任意层目录)
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:filepath:文件路径 比如 "\\dir1\\dir2\\dir3\\....\\dirn\\test.txt"
- 返回说明:1:文件或目录路径不存在 0:成功
- 注:删除后的文件的FAT表中的簇链关系完全被破坏
**************************************************************************/
#ifdef ZNFAT_DEL_FILE

UINT8 znFAT_Del_File(CONST INT8 *filepath)
{
    UINT32 cur_clu,next_clu;
    struct FileInfoStruct fi;

    if (znFAT_Open_File(&fi,filepath,0,1))
    {
        return 1;
    }
    znFAT_ReadSector(fi.Rec_Sec,znFAT_Buffer);
    *(znFAT_Buffer+fi.nRec)=0xe5;
    znFAT_WriteSector(fi.Rec_Sec,znFAT_Buffer);

    if (cur_clu=fi.FileStartCluster)
    {
        if (cur_clu<Search_Last_Usable_Cluster())
            znFAT_Update_FSInfo_Last_Clu(cur_clu);
        znFAT_Update_FSInfo_Free_Clu(1);
        next_clu=znFAT_GetNextCluster(cur_clu);
        while (next_clu!=0x0fffffff)
        {
            znFAT_Update_FSInfo_Free_Clu(1);
            znFAT_Modify_FAT(cur_clu,0x00000000);
            cur_clu=next_clu;
            next_clu=znFAT_GetNextCluster(cur_clu);
        }
        znFAT_Modify_FAT(cur_clu,0x00000000);
    }
    return 0;
}

#endif

使用特权

评论回复
10
zheng522|  楼主 | 2015-4-25 10:42 | 只看该作者
/**************************************************************************
- 功能描述:文件拷贝(源文件路径与目标文件路径均支持任意深层目录,并且支持
             文件名通配)
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:pArg1:是源文件所在的存储设备的初始参数结构体的指针
             pArg2:是目标文件所在的存储设备的初始参数结构体的指针
             sfilename:源文件路径,也就是拷贝操作的数据源
             tfilename:目标文件路径,也就是数据最终到写入的文件
                       比如 "\\dir1\\dir2\\dir3\\....\\dirn\\test.txt"
             file_buf:拷贝过程中要用到的数据缓冲区,此缓冲区容量越大,
                      拷贝速度越快
             buf_size:数据缓冲区的大小
- 返回说明:1:目录文件创建失败 2:源文件打开打败 0:成功
- 注:此函数支持多设备之间的文件拷贝,pArg1与pArg2引入了源存储设备与目的
       存储设备的初始参数信息,从而可以同时对两个存储设备进行操作。
           znFAT 5.01版开始支持多设备,多设备间的相互数据拷贝是最典型的应用
**************************************************************************/
#ifdef ZNFAT_XCOPY_FILE

UINT8 znFAT_XCopy_File(struct znFAT_Init_Arg *pArg1,struct znFAT_Init_Arg *pArg2,CONST INT8 *sfilename,CONST INT8 *tfilename,UINT8 *file_buf,UINT32 buf_size,UINT8 *pt)
{
    struct FileInfoStruct FileInfo2,FileInfo1;
    struct znFAT_Init_Arg *pArg_temp;
    UINT32 i;

    pArg_temp=pArg; //把pArg原来的指向赋给中间变量

    pArg=pArg2;
    Dev_No=pArg->DEV_No; //标定目标存储设备
    if (znFAT_Create_File(&FileInfo1,tfilename,pt)) return 1; //在目标存储设备上创建目标文件

    pArg=pArg1;
    Dev_No=pArg->DEV_No; //标定源存储设备
    if (znFAT_Open_File(&FileInfo2,sfilename,0,1)) return 2; //在源存储设备上打开源文件

    for (i=0;i<FileInfo2.FileSize/buf_size;i++)
    {
        pArg=pArg1;
        Dev_No=pArg->DEV_No; //标定源存储设备
        znFAT_Read_File(&FileInfo2,i*buf_size,buf_size,file_buf);        //读源存储设备上的源文件数据到数据缓冲区

        pArg=pArg2;
        Dev_No=pArg->DEV_No;        //标定目标存储设备
        znFAT_Add_Dat(&FileInfo1,buf_size,file_buf); //将数据级冲区的数据写入到目标文件中
    }

    pArg=pArg1;
    Dev_No=pArg->DEV_No; //标定源存储设备
    znFAT_Read_File(&FileInfo2,i*buf_size,FileInfo2.FileSize%buf_size,file_buf);//读取最后的文件余量

    pArg=pArg2;
    Dev_No=pArg->DEV_No; //标定目标存储设备
    znFAT_Add_Dat(&FileInfo1,FileInfo2.FileSize%buf_size,file_buf); //将最后的余量数据写入到目标文件中

    pArg=pArg_temp; //将pArg恢复

    return 0;
}

#endif

使用特权

评论回复
11
zheng522|  楼主 | 2015-4-25 10:42 | 只看该作者
/**************************************************************************
- 功能描述:文件重命名
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:filename:将要重命名的源文件的路径 如\a.txt
             newfilename:目标文件名 如b.txt (注目标文件名是单纯的文件名,
                         不含路径)
- 返回说明:1:源文件打开打败 0:成功
- 注:无
**************************************************************************/
#ifdef ZNFAT_RENAME_FILE

UINT8 znFAT_Rename_File(CONST INT8 *filename,CONST INT8 *newfilename)
{
    struct FileInfoStruct fi;
    UINT8 i=0,j=0;
    if (znFAT_Open_File(&fi,filename,0,1)) return 1; //文件打开失败
    znFAT_ReadSector(fi.Rec_Sec,znFAT_Buffer);
    for (i=0;i<11;i++) (znFAT_Buffer+fi.nRec)[i]=0x20;
    i=0;
    while (newfilename[i]!='.')
    {
        (znFAT_Buffer+fi.nRec)[i]=L2U(newfilename[i]);
        i++;
    }
    i++;
    while (newfilename[i])
    {
        (znFAT_Buffer+fi.nRec+8)[j]=L2U(newfilename[i]);
        i++;
        j++;
    }
    znFAT_WriteSector(fi.Rec_Sec,znFAT_Buffer);
    return 0;
}

#endif

使用特权

评论回复
12
zheng522|  楼主 | 2015-4-25 10:42 | 只看该作者
/**************************************************************************
- 功能描述:文件关闭
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:pfi:指向当前打开的文件的文件信息结构
- 返回说明:0:成功
- 注:无
**************************************************************************/
#ifdef ZNFAT_FILE_CLOSE

UINT8 znFAT_File_Close(struct FileInfoStruct *pfi)
{
    UINT16 i=0;
    for (i=0;i<sizeof(struct FileInfoStruct);i++)
    {
        ((UINT8 *)pfi)[i]=0;
    }
    return 0;
}

#endif

使用特权

评论回复
13
zheng522|  楼主 | 2015-4-25 10:43 | 只看该作者
/***********waiting***************************************************************
- 功能描述:从文件某一位置读取一定长度的数据,由pfun所指向的函数来处理
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:pfi:FileInfoStruct类型的结构体指针,用于装载文件参数信息,文件
             读取的过程中,此结构体中的相关参数会更新,比如文件的当前偏移量、
             文件的当前扇区,文件的当前簇等等
             offset:要定位的偏移量,要小于文件的大小
             len:要读取的数据的长度,如果len+offset大于文件的大小,则实际读
             取的数据量是从offset开始到文件结束
             pfun:对读取的数据的处理函数,pfun指向处理函数,这样可以灵活的
             配置数据如何去处理,比如是放在缓冲区中,还是把数据通过串口发送
             出去,只需要pfun去指向相应的处理函数可以了
- 返回说明:读取到的实际的数据长度,如果读取失败,比如指定的偏移量大于了文件
             大小,则返回0
- 注:在读取一个文件的数据前,必须先将该文件用znFAT_Open_File打开
**************************************************************************/
#ifdef ZNFAT_READ_FILEX

UINT32 znFAT_Read_FileX(struct FileInfoStruct *pfi,UINT32 offset,UINT32 len,void (*pfun)(UINT8))
{
    UINT32 i,j,k,temp;
    UINT32 counter=0;
    if (offset<pfi->FileSize)
    {
        if (offset+len>pfi->FileSize) len=pfi->FileSize-offset;
        znFAT_Seek_File(pfi,offset);

        znFAT_ReadSector(pfi->FileCurSector,znFAT_Buffer);
        for (i=pfi->FileCurPos;i<pArg->BytesPerSector;i++)
        {
            if (counter>=len)
            {
                return len;
            }
            (*pfun)(znFAT_Buffer[i]);
            counter++;
            pfi->FileCurPos++;
            pfi->FileCurOffset++;
        }
        if (pfi->FileCurSector-(SOC(pfi->FileCurCluster))!=(pArg->SectorsPerClust-1))
        {
            for (j=pfi->FileCurSector+1;j<(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;j++)
            {
                znFAT_ReadSector(j,znFAT_Buffer);
                pfi->FileCurSector=j;
                for (i=0;i<pArg->BytesPerSector;i++)
                {
                    if (counter>=len)
                    {
                        return len;
                    }
                    (*pfun)(znFAT_Buffer[i]);
                    counter++;
                    pfi->FileCurPos++;
                    pfi->FileCurOffset++;
                }
            }
        }
        temp=(len-counter)/(pArg->BytesPerSector*pArg->SectorsPerClust);
        for (k=0;k<temp;k++)
        {
            pfi->FileCurCluster=znFAT_GetNextCluster(pfi->FileCurCluster);
            for (j=(SOC(pfi->FileCurCluster));j<(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;j++)
            {
                znFAT_ReadSector(j,znFAT_Buffer);
                pfi->FileCurSector=j;
                for (i=0;i<pArg->BytesPerSector;i++)
                {
                    if (counter>=len)
                    {
                        return len;
                    }
                    (*pfun)(znFAT_Buffer[i]);
                    counter++;
                    pfi->FileCurOffset++;
                    pfi->FileCurPos++;
                    pfi->FileCurPos%=pArg->BytesPerSector;
                }
            }
        }
        pfi->FileCurCluster=znFAT_GetNextCluster(pfi->FileCurCluster);
        temp=(SOC(pfi->FileCurCluster))+((len-counter)/pArg->BytesPerSector);
        pfi->FileCurSector=(SOC(pfi->FileCurCluster));
        for (j=(SOC(pfi->FileCurCluster));j<temp;j++)
        {
            znFAT_ReadSector(j,znFAT_Buffer);
            pfi->FileCurSector=j;
            for (i=0;i<pArg->BytesPerSector;i++)
            {
                if (counter>=len)
                {
                    return len;
                }
                (*pfun)(znFAT_Buffer[i]);
                counter++;
                pfi->FileCurPos++;
                pfi->FileCurPos%=pArg->BytesPerSector;
                pfi->FileCurOffset++;
            }
        }
        pfi->FileCurSector=j;
        znFAT_ReadSector(pfi->FileCurSector,znFAT_Buffer);
        temp=len-counter;
        for (i=0;i<temp;i++)
        {
            if (counter>=len)
            {
                return len;
            }
            (*pfun)(znFAT_Buffer[i]);
            counter++;
            pfi->FileCurPos++;
            pfi->FileCurPos%=pArg->BytesPerSector;
            pfi->FileCurOffset++;
        }
    }
    else
    {
        len=0;
    }
    return len;
}

#endif

使用特权

评论回复
14
zheng522|  楼主 | 2015-4-25 10:44 | 只看该作者
/**************************************************************************
- 功能描述:从文件的某一个位置处,读取一定长度的数据,放入数据缓冲区中
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:pfi:FileInfoStruct类型的结构体指针,用于装载文件参数信息,文件
             读取的过程中,此结构体中的相关参数会更新,比如文件的当前偏移量、
             文件的当前扇区,文件的当前簇等等
             offset:要定位的偏移量,要小于文件的大小
             len:要读取的数据的长度,如果len+offset大于文件的大小,则实际读
             取的数据量是从offset开始到文件结束
             pbuf:数据缓冲区
- 返回说明:读取到的实际的数据长度,如果读取失败,比如指定的偏移量大于了文件
             大小,则返回0
- 注:在读取一个文件的数据前,必须先将该文件用znFAT_Open_File打开
**************************************************************************/
#ifdef ZNFAT_READ_FILE

UINT32 znFAT_Read_File(struct FileInfoStruct *pfi,UINT32 offset,UINT32 len,UINT8 *pbuf)
{
    UINT32 j,k,temp;
    UINT32 counter=0;
    UINT16 i;

    if (offset<pfi->FileSize)
    {
        if (offset+len>pfi->FileSize) len=pfi->FileSize-offset;
        znFAT_Seek_File(pfi,offset);

        znFAT_ReadSector(pfi->FileCurSector,znFAT_Buffer);
        for (i=pfi->FileCurPos;i<pArg->BytesPerSector;i++) //扇区内数据余量
        {
            if (counter>=len)
            {
                return len;
            }
            pbuf[counter]=znFAT_Buffer[i];
            counter++;
            pfi->FileCurPos++;
            pfi->FileCurPos%=pArg->BytesPerSector;
            pfi->FileCurOffset++;
        }

        if (((pfi->FileCurSector)-(SOC(pfi->FileCurCluster)))!=(pArg->SectorsPerClust-1))
        {
            temp=(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;
            for (j=(pfi->FileCurSector+1);j<temp;j++) //簇内扇区数据余量
            {
                znFAT_ReadSector(j,znFAT_Buffer);
                pfi->FileCurSector=j;
                for (i=0;i<pArg->BytesPerSector;i++)
                {
                    if (counter>=len)
                    {
                        return len;
                    }
                    pbuf[counter]=znFAT_Buffer[i];
                    counter++;
                    pfi->FileCurPos++;
                    pfi->FileCurPos%=pArg->BytesPerSector;
                    pfi->FileCurOffset++;
                }
            }
        }
        temp=(len-counter)/(pArg->BytesPerSector*pArg->SectorsPerClust);
        for (k=0;k<temp;k++)
        {
            pfi->FileCurCluster=znFAT_GetNextCluster(pfi->FileCurCluster);
            for (j=(SOC(pfi->FileCurCluster));j<(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;j++)
            {
                znFAT_ReadSector(j,znFAT_Buffer);
                pfi->FileCurSector=j;
                for (i=0;i<pArg->BytesPerSector;i++)
                {
                    if (counter>=len)
                    {
                        return len;
                    }
                    pbuf[counter]=znFAT_Buffer[i];
                    counter++;
                    pfi->FileCurOffset++;
                    pfi->FileCurPos++;
                    pfi->FileCurPos%=pArg->BytesPerSector;
                }
            }
        }
        pfi->FileCurCluster=znFAT_GetNextCluster(pfi->FileCurCluster);
        temp=(SOC(pfi->FileCurCluster))+((len-counter)/pArg->BytesPerSector);
        pfi->FileCurSector=(SOC(pfi->FileCurCluster));
        for (j=(SOC(pfi->FileCurCluster));j<temp;j++)
        {
            znFAT_ReadSector(j,znFAT_Buffer);
            pfi->FileCurSector=j;
            for (i=0;i<pArg->BytesPerSector;i++)
            {
                if (counter>=len)
                {
                    return len;
                }
                pbuf[counter]=znFAT_Buffer[i];
                counter++;
                pfi->FileCurPos++;
                pfi->FileCurPos%=pArg->BytesPerSector;
                pfi->FileCurOffset++;
            }
        }
        pfi->FileCurSector=j;
        znFAT_ReadSector(pfi->FileCurSector,znFAT_Buffer);
        temp=len-counter;
        for (i=0;i<temp;i++)
        {
            if (counter>=len)
            {
                return len;
            }
            pbuf[counter]=znFAT_Buffer[i];
            counter++;
            pfi->FileCurPos++;
            pfi->FileCurPos%=pArg->BytesPerSector;
            pfi->FileCurOffset++;
        }
    }
    else
    {
        len=0;
    }
    return len;
}

#endif

使用特权

评论回复
15
zheng522|  楼主 | 2015-4-25 10:44 | 只看该作者
/**************************************************************************
- 功能描述:打开一个文件(支持文件名通配,如 A*.txt 或 *.*)
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:pfi: FileInfoStruct类型的结构体指针,用来装载文件的参数信息
              比如文件的大小、文件的名称、文件的开始簇等等,以备后面使用
             filepath: 文件的路径,支持任意层目录 比如
              "\\dir1\\dir2\\dir3\\....\\test.txt"
                         item:在文件名中有通配符*或?的情况下,实现与之匹配的文件并非
                         一个,item就是打开的文件的项数,比如符合通配条件的文件有6个,
                         如果item=3,那么此函数就会打开这6个文件中按顺序排号为3的那个
                         文件(item编号从0开始)
- 返回说明:0:成功 1:文件不存在 2:目录不存在
- 注:打开文件不成功有很多原因,比如文件不存在、文件的某一级目录不存在
       通配情况下满足条件的文件项数小于item的值等等
           通常情况下,文件名中没有通配符,item的值我们取0就可以了
**************************************************************************/
#ifdef ZNFAT_OPEN_FILE

UINT8 znFAT_Open_File(struct FileInfoStruct *pfi,CONST INT8 *filepath,UINT32 item,UINT8 is_file)
{
    UINT32 Cur_Clust,sec_temp,iSec,iFile,iItem=0;
    UINT8 flag=0,index=0;
    UINT8 i=0,start_pos=0,counter=0;

    struct direntry *pFile;
    struct File_Dir_Items *pitems;
    INT8 temp_file_name[30];

    while (filepath[i]!=0)
    {
        if (filepath[i]=='\\') index=i;
        i++;
    }
    if (Cur_Clust=znFAT_Enter_Dir(filepath))
    {
        do
        {
            sec_temp=SOC(Cur_Clust);
            for (iSec=sec_temp;iSec<sec_temp+pArg->SectorsPerClust;iSec++)
            {
                znFAT_ReadSector(iSec,znFAT_Buffer);

                pitems=(struct File_Dir_Items *)znFAT_Buffer;

                for (iFile=0;iFile<FILE_DIR_ITEM_NUM;iFile++)
                {
                    pFile=&(pitems->file_dir_items[iFile]);

                    if (en_longname)
                    {
                        if (((struct LongNameItem*)pFile)->mark==0x0f && (pFile->deName[0]!=0xe5))
                        {
                            if (((struct LongNameItem*)pFile)->n_item&0x40)
                            {
                                is_longname=1;
                            }
                            if (is_longname)
                            {
                                counter=0;
                                start_pos=((((struct LongNameItem*)pFile)->n_item&0xbf)-1)*26;
                                for (i=1;i<11;i++)
                                {
                                    longname_buf[start_pos+counter]=((UINT8 *)pFile)[i];
                                    counter++;
                                }
                                for (i=14;i<26;i++)
                                {
                                    longname_buf[start_pos+counter]=((UINT8 *)pFile)[i];
                                    counter++;
                                }
                                for (i=28;i<32;i++)
                                {
                                    longname_buf[start_pos+counter]=((UINT8 *)pFile)[i];
                                    counter++;
                                }
                            }
                        }
                    }
                    if (pFile->deAttributes & (is_file?0x20:0x10))
                    {
                        //if(!is_longname) is_longname=0;

                        znFAT_toFileName((INT8 *)(pFile->deName),temp_file_name);
                        //printf("time-> %d temp_file_name->%s\n",h++,temp_file_name);
                        //printf("temp_dir_name->%s\n",temp_dir_name);
                        //printf("cur_clust->%d sec->%d\n",Cur_Clust,iSec);



                        if (!is_file) //如果是目录,把点去掉
                        {
                            //i=0;
                            //while(temp_dir_name[i]!=0) {if(temp_dir_name[i++]=='.') h=1;}
                            //if(!h) {temp_dir_name[i]='.';temp_dir_name[i+1]=0;}  //补齐文件名 如果传进来的文件名没有扩展名,在后面加一个.
                            i=StrLen(temp_file_name);
                            temp_file_name[i-1]=0;
                        }

                        if ((FilenameMatch(temp_dir_name,temp_file_name)) && (pFile->deName[0]!=0xe5) && pFile->deAttributes & (is_file?0x20:0x10)) //匹配文件名,文件没有被删除,是文件或目录
                        {
                            if (item==iItem)
                            {
                                flag=1;
                                Cur_Clust=LE2BE(pFile->deLowCluster,2)+LE2BE(pFile->deHighClust,2)*65536;

                                pfi->FileSize=LE2BE(pFile->deFileSize,4);
                                if (pFile->deAttributes&0x10)
                                    temp_file_name[StrLen(temp_file_name)-1]=0;

                                StringCopy(pfi->FileName,temp_file_name);
                                pfi->FileStartCluster=LE2BE(pFile->deLowCluster,2)+LE2BE(pFile->deHighClust,2)*65536;
                                pfi->FileCurCluster=pfi->FileStartCluster;
                                pfi->FileCurSector=SOC(pfi->FileStartCluster);
                                pfi->FileCurPos=0;
                                pfi->FileCurOffset=0;
                                pfi->Rec_Sec=iSec;
                                pfi->nRec=iFile;

                                pfi->FileAttr=pFile->deAttributes;
                                sec_temp=LE2BE(pFile->deCTime,2);
                                (pfi->FileCreateTime).sec=(sec_temp&0x001f)*2;
                                (pfi->FileCreateTime).min=((sec_temp>>5)&0x003f);
                                (pfi->FileCreateTime).hour=((sec_temp>>11)&0x001f);
                                sec_temp=LE2BE(pFile->deCDate,2);
                                (pfi->FileCreateDate).day=((sec_temp)&0x001f);
                                (pfi->FileCreateDate).month=((sec_temp>>5)&0x000f);
                                (pfi->FileCreateDate).year=((sec_temp>>9)&0x007f)+1980;

                                sec_temp=LE2BE(pFile->deMTime,2);
                                (pfi->FileMTime).sec=(sec_temp&0x001f)*2;
                                (pfi->FileMTime).min=((sec_temp>>5)&0x003f);
                                (pfi->FileMTime).hour=((sec_temp>>11)&0x001f);
                                sec_temp=LE2BE(pFile->deMDate,2);
                                (pfi->FileMDate).day=((sec_temp)&0x001f);
                                (pfi->FileMDate).month=((sec_temp>>5)&0x000f);
                                (pfi->FileMDate).year=((sec_temp>>9)&0x007f)+1980;

                                sec_temp=LE2BE(pFile->deADate,2);
                                (pfi->FileADate).day=((sec_temp)&0x001f);
                                (pfi->FileADate).month=((sec_temp>>5)&0x000f);
                                (pfi->FileADate).year=((sec_temp>>9)&0x007f)+1980;

                                iFile=pArg->BytesPerSector;
                                iSec=sec_temp+pArg->SectorsPerClust;
                            }
                            else
                            {
                                iItem++;
                            }
                        }
                        else
                        {
                            is_longname=0;
                        }
                    }
                }
            }
        }
        while (!flag && (Cur_Clust=znFAT_GetNextCluster(Cur_Clust))!=0x0fffffff);

        if (!flag)
        {
            return 1;
        }
        return 0;
    }
    else
    {
        return 2;
    }
}

#endif

使用特权

评论回复
16
zheng522|  楼主 | 2015-4-25 10:45 | 只看该作者
/***********************************************************************
- 功能描述:znFAT文件系统初始化
- 隶属模块:znFAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:znFAT_Init_Arg类型的结构体指针,用于装载一些重要的参数信息,
             以备后面使用
- 返回说明:无
- 注:在使用znFAT前,这个函数是必须先被调用的,将很多参数信息装入到
       arg指向的结构体中,比如扇区大小、根目录的位置、FAT表大小等等。
       这些参数绝大部分是来自于DBR的BPB中,因此此函数主要在作对DBR的参数解析
***********************************************************************/

void znFAT_Init(void)
{
    struct znFAT_BPB *bpb;

    bpb=(struct znFAT_BPB *)(znFAT_Buffer);               //将数据缓冲区指针转为struct znFAT_BPB 型指针

    pArg->DEV_No=Dev_No; //装入设备号

    pArg->BPB_Sector_No   =znFAT_Find_DBR();               //znFAT_FindBPB()可以返回BPB所在的扇区号

    znFAT_ReadSector(pArg->BPB_Sector_No,znFAT_Buffer);

    pArg->FATsectors      =LE2BE((bpb->BPB_FATSz32)    ,4);//装入FAT表占用的扇区数到FATsectors中
    pArg->FirstDirClust   =LE2BE((bpb->BPB_RootClus)   ,4);//装入根目录簇号到FirstDirClust中
    pArg->BytesPerSector  =LE2BE((bpb->BPB_BytesPerSec),2);//装入每扇区字节数到BytesPerSector中
    pArg->SectorsPerClust =LE2BE((bpb->BPB_SecPerClus) ,1);//装入每簇扇区数到SectorsPerClust 中
    pArg->FirstFATSector  =LE2BE((bpb->BPB_RsvdSecCnt) ,2)+pArg->BPB_Sector_No;//装入第一个FAT表扇区号到FirstFATSector 中
    pArg->FirstDirSector  =(pArg->FirstFATSector)+(bpb->BPB_NumFATs[0])*(pArg->FATsectors); //装入第一个目录扇区到FirstDirSector中

    pArg->Total_Size      =LE2BE((bpb->BPB_TotSec32),4)*pArg->BytesPerSector;         //磁盘的总容量,单位是字节

    temp_last_cluster=Search_Last_Usable_Cluster();
}

使用特权

评论回复
17
zheng522|  楼主 | 2015-4-25 10:46 | 只看该作者
/******************************************************************
- 功能描述:znFAT的存储设备底层驱动接口,读取存储设备的addr扇区的
             512个字节的数据放入buf数据缓冲区中
- 隶属模块:znFAT文件系统模块
- 函数属性:内部(用于与存储设备的底层驱动对接)
- 参数说明:addr:扇区地址
             buf:指向数据缓冲区的指针
- 返回说明:0表示读取扇区成功,否则失败
- 注:这里加入了天狼星精华板上的三种存储设备,即SD卡(有效)、U盘、
       CF卡通过在程序中动态的切换不同的设备驱动,从而实现多设备(即同
           时对多种存储设备进行操作,比如从SD卡拷贝文件到U盘等等),不同
           驱动的切换,只需要在程序中改变Dev_No这个全局变量的值即可
******************************************************************/

UINT8 znFAT_ReadSector(UINT32 addr,UINT8 *buf)
{
    switch (Dev_No)        //由Dev_No来决定所使用的存储设备驱动
    {
    case SDCARD:
        return SD_Read_Sector(addr,buf);
        break;
    case UDISK:
        //return CH375_Read_Sector(addr,buf);
        break;
    case CFCARD:
        //return CF_Read_Sector(addr,buf);
        break;
    case OTHER:
        //return PCSECTOR_Read_Sector(addr,buf);
        break;
    }
}

使用特权

评论回复
18
zheng522|  楼主 | 2015-4-25 10:46 | 只看该作者
/******************************************************************
- 功能描述:znFAT的存储设备底层驱动接口,将buf数据缓冲区中的512个
             字节的数据写入到存储设备的addr扇区中
- 隶属模块:znFAT文件系统模块
- 函数属性:内部(用于与存储设备的底层驱动对接)
- 参数说明:addr:扇区地址
             buf:指向数据缓冲区
- 返回说明:0表示读取扇区成功,否则失败
- 注:略
******************************************************************/

UINT8 znFAT_WriteSector(UINT32 addr,UINT8 *buf)
{
    switch (Dev_No)        //由Dev_No来决定所使用的存储设备驱动
    {
    case SDCARD:
        return SD_Write_Sector(addr,buf);
        break;
    case UDISK:
        //return CH375_Write_Sector(addr,buf);
        break;
    case CFCARD:
        //return CF_WriteSector(addr,buf);
        break;
    case OTHER:
        //return PCSECTOR_Write_Sector(addr,buf);
        break;
    }
}

使用特权

评论回复
19
波越| | 2015-4-26 00:49 | 只看该作者
顶下,学习了

使用特权

评论回复
20
给力芯片| | 2015-4-26 01:16 | 只看该作者
学习了,文件系统,应该很强吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

73

主题

821

帖子

3

粉丝