📄 fatprocess.c
字号:
/****************************************Copyright (c)**************************************************
** CH374做主机操作U盘读写程序
** FAT16文件系统层
** 接口函数
**
** VBeat 0.5
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: FATProcess.C
**创 建 人: 徐亦朱
**最后修改日期: 2007年9月27日
**描 述: FAT文件系统层接口函数
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 徐亦朱
** 版 本: VBeat 0.3
** 日 期: 2007年9月21日
** 描 述: 完善程序风格
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007年9月27日
** 描 述: 优化数据结构及算法
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include <stdio.h>
#include <string.h>
#include "HAL.H"
#include "HAL_BASE2.C"
#include "PARA_HW2.C"
#include "FAT.H"
#include "FATProcess.H"
/*********************************************************************************************************
** 函数名称: FATInit
** 功能描述: FAT文件系统参数初始化
**
** 输 入: 无
** 输 出: FAT文件系统各项参数初始化
** A.返回ERR_Init报告异常传输错误
** B.返回InitSuccess表示初始化成功完成
**
** 全局变量: FAT.SecPerClus, FAT.BytesPerSec, FAT.RsvdSecCnt, FAT.shift, FAT.RootDirSectors
** FAT.FirstRootSector, FAT.FirstDataSector, DiskNums, FileNums
** 调用模块: mReadSector
** 调试码: DEBUG_Init
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8 FATInit( void )
{
UINT8 s ;
UINT8 NumFATs ;
UINT16 RootEntCnt ;
UINT16 TotSec16 ; //该卷总扇区数( FAT16 )
UINT32 TotSec32 ; //该卷总扇区数( FAT32 )
UINT16 FATSz16 ; //FAT16表所占扇区数
UINT32 FATSz32 ; //FAT32表所占扇区数
UINT32 TotSec ;
UINT32 FATSz ;
UINT32 DataSec ;
UINT32 RootClus ;
UINT32 Count_of_Cluster ;
//读取DBR扇区
s = mReadSector( 0x00000000, 1, DISKBUF);
if ( s != USB_INT_SUCCESS )
return( ERR_Init ) ;
//DISK每簇扇区数
FAT.SecPerClus = ( ( ( PUSB_BPB )DISKBUF ) ) -> base.SecPerClus ;
//DISKFAT表数目
NumFATs = ( ( ( PUSB_BPB )DISKBUF ) ) -> base.NumFATs ;
//DISK每扇区字节数
FAT.BytesPerSec = ( UINT16 )( ( ( ( PUSB_BPB )DISKBUF ) ) -> base.BytesPerSec[ 0 ] ) | ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.BytesPerSec[ 1 ] ) << 8 ;
//DISK保留扇区数
FAT.RsvdSecCnt = ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.RsvdSecCnt[ 0 ] ) | ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.RsvdSecCnt[ 1 ] ) << 8 ;
//DISK根目录项数
RootEntCnt = ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.RootEntCnt[ 0 ] ) | ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.RootEntCnt[ 1 ] ) << 8 ;
//FAT32根目录所在第一簇的簇号
RootClus = ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.RootClus[ 0 ] ) | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.RootClus[ 1 ] ) << 8 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.RootClus[ 2 ] ) << 16 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.RootClus[ 3 ] ) << 24 ;
//FAT16表所占扇区数
FATSz16 = ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.FATSz16[ 0 ] ) | ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.FATSz16[ 1 ] ) << 8 ;
//该卷总扇区数( FAT16 )
TotSec16 = ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec16[ 0 ] ) | ( UINT16 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec16[ 1 ] ) << 8 ;
//FAT32表所占扇区数
FATSz32 = ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.FATSz32[ 0 ] ) | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.FATSz32[ 1 ] ) << 8 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.FATSz32[ 2 ] ) << 16 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> ext.fat32.FATSz32[ 3 ] ) << 24 ;
//该卷总扇区数( FAT32 )
TotSec32 = ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec32[ 0 ] ) | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec32[ 1 ] ) << 8 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec32[ 2 ] ) << 16 | ( UINT32 )( ( ( PUSB_BPB )DISKBUF ) -> base.TotSec32[ 3 ] ) << 24 ;
//将每扇区字节数转换成2的整数次方,以方便运算
switch( FAT.BytesPerSec >> 9 )
{
case 1 : FAT.shift = 9 ; break ;
case 2 : FAT.shift = 10 ; break ;
case 4 : FAT.shift = 11 ; break ;
default: printf( " Sorry,this system is not suit for this type ! \n " ) ;
break ;
}
//DISK根目录所占的扇区数
FAT.RootDirSectors = ( ( RootEntCnt << 5 ) + ( FAT.BytesPerSec - 1 ) ) >> FAT.shift ;
//确定FAT表所占扇区数
FATSz = FATSz16 ? FATSz16 : FATSz32 ;
//DISK根目录第一个扇区的扇区号
FAT.FirstRootSector = ( UINT32 )( FAT.RsvdSecCnt + FATSz * NumFATs ) ;
//DISK簇2的第一个扇区的扇区号
FAT.FirstDataSector = FAT.FirstRootSector + FAT.RootDirSectors ;
// FAT类型辨别
TotSec = TotSec16 ? TotSec16 : TotSec32 ;
//DISK数据区中扇区数
DataSec = TotSec - FAT.FirstDataSector ;
//DISK簇数
Count_of_Cluster = DataSec / FAT.SecPerClus ;
if ( Count_of_Cluster < 4085 )
{
FAT.Type = FAT12 ;
printf( " This FS is FAT12.\n " ) ;
printf( " This System is not suit for FAT12 !\n " ) ;
return( ERR_Init ) ;
}
else if ( Count_of_Cluster < 65525 )
{
FAT.Type = FAT16 ;
printf( " This FS is FAT16.\n " ) ;
printf( " Welcome to you !\n " ) ;
}
else
{
FAT.Type = FAT32 ;
printf( " This FS is FAT32.\n " ) ;
printf( " Welcome to you !\n " ) ;
}
//DISK根目录第一个扇区的扇区号
FAT.FirstRootSector = ( FAT.Type == FAT32 ) ? ( UINT32 )( ( ( RootClus - 2 ) * FAT.SecPerClus ) + FAT.FirstDataSector ) : FAT.FirstRootSector ;
//DISK_BUF能存储的扇区数
DiskNums = DISKBUF_BYTES >> FAT.shift ;
//FILE_BUF能存储的扇区数
FileNums = ( FILEBUF_BYTES >> FAT.shift ) - 1 ;
//调试语句
#ifdef DEBUG_Init
printf( "This FS Type is %d\n", ( UINT16 )FAT.Type ) ;
printf( "FAT表份数 = %d\n", ( UINT16 )NumFATs ) ;
printf( "FAT表所占扇区数 = %ld\n", ( UINT32 )FATSz ) ;
printf( "数据区域总簇数 = %ld\n", ( UINT32 )Count_of_Cluster ) ;
printf( "总扇区数 = %ld\n", ( UINT32 )TotSec ) ;
printf( "数据扇区总数 = %ld\n", ( UINT32 )DataSec ) ;
printf( "根目录扇区总数 = %d\n", FAT.RootDirSectors ) ;
printf( "保留扇区数 = %d\n", FAT.RsvdSecCnt ) ;
printf( "根目录项数 = %d\n", RootEntCnt ) ;
printf( "每簇扇区数 = %d\n", ( UINT16 )FAT.SecPerClus ) ;
printf( "每扇区字节数 = %d", FAT.BytesPerSec ) ;
printf( "即2的%d次方\n", ( UINT16 )FAT.shift ) ;
printf( "根目录起始扇区数 = %ld\n", ( UINT32 )FAT.FirstRootSector ) ;
printf( "数据区域起始扇区数 = %ld\n", ( UINT32 )FAT.FirstDataSector ) ;
#endif
//初始化文件结构变量
for ( s = 0; s < 2; s ++ )
files[ s ].Flags = 0 ;
rFILEBUF = FILEBUF + FAT.BytesPerSec ;
return( InitSuccess ) ;
}
/*********************************************************************************************************
** 函数名称: FATOpen
** 功能描述: 打开文件函数
**
** 输 入: string: 指向要打开的文件名( 路径形式,例如: "/……/……/文件名" )
** ProcessMode: 操作模式ProcessMode:
** ModeA1: 0x00 -- 打开文件,以便读,若文件不存在则退出
** ModeA2: 0x80 -- 打开文件,以便写,若文件不存在则退出
** ModeA3: 0x01 -- 打开文件,以便读,先将文件长度截为0,如果文件不存在则退出
** ModeA4: 0x81 -- 打开文件,以便写,先将文件长度截为0,如果文件不存在则退出
** ModeA5: 0x82 -- 打开文件,以便写,向已有文件的尾部追加内容,如果文件不存在则退出
** ModeB1: 0x10 -- 打开文件,以便读,若文件不存在则创建之
** ModeB2: 0x90 -- 打开文件,以便写,若文件不存在则创建之
** ModeB3: 0x11 -- 打开文件,以便读,先将文件长度截为0,若文件不存在则创建之
** ModeB4: 0x91 -- 打开文件,以便写,先将文件长度截为0,若文件不存在则创建之
** ModeB5: 0x92 -- 打开文件,以便写,向已有文件的尾部追加内容,若文件不存在则创建之
** ModeC1: 0xF1 -- 打开目录,以便读写,若目录不存在则创建之
** ModeC2: 0xF2 -- 删除文件/目录,如果文件/目录不存在则退出
** 输 出: 逐级打开,需先打开上层目录
** 找到的文件/目录在簇内的地址信息记录在FIND结构中
** A.返回ERR_Check报告异常传输错误
** B.返回OpenSuccess则操作成功
** C.返回ERR_NOFile查找文件失败,磁盘中无此文件
** D.返回ERR_OPEN打开文件失败,没有可用的文件结构
**
** 全局变量: FAT.filenum
** 调用模块: ProcessPath, CheckFirst16, x16CheckFile, xProcessDirectory, x16RootDirectory, x16Creat
** 调试码: DEBUG_OPEN
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8 FATOpen( const UINT8 *string, UINT8 ProcessMode )
{
UINT8 i ;
UINT8 s ;
UINT8 r ;
UINT8 Count ;
UINT8 *POINT0 ;
UINT8 TransNum ;
UINT16 Cluster ;
UINT32 ProcessSector ;
//系统时间初始化
sysclock.date.day = 27;
sysclock.date.month = 9 ;
sysclock.date.year = 27 ;
sysclock.time.sec = 0 ;
sysclock.time.min = 0 ;
sysclock.time.hour = 12 ;
//查询可用文件结构
for ( i = 0; i < 2; i ++ )
{
if ( ! ( files[ i ].Flags & 0x80 ) )
break ;
}
if ( files[ i ].Flags & 0x80 )
return( ERR_OPEN ) ;
files[ i ].Flags = 0x80 ; //标记为已用
files[ i ].Flags |= i ; //编号
FAT.filenum = i ;
//查找路径,记录上级目录地址信息
Count = 0 ;
while ( 1 )
{
//处理路径
r = ProcessPath( string, files[ i ].Name ) ;
//查找操作
if ( ! Count )
{
if ( FAT.Type == FAT16 )
s = CheckFirst16( &files[ i ] ) ;
//if ( FAT.Type == FAT32 )
//s = CheckFirst32( FileName ) ;
Count ++ ;
}
else
{
if ( FAT.Type == FAT16 )
s = x16CheckFile( &files[ i ] ) ;
//if ( FAT.Type == FAT32 )
//s = x32CheckFile( FileName ) ;
if ( ++ Count == 10 )
Count = 2 ;
}
//判断查找结果
if ( s == ERR_Check )
return( s ) ;
if ( s == 0x00 )
break ;
if ( r == EndPath )
break ;
}
//处理文件查找结果
if ( s == 0x00 )
{
if ( ProcessMode == ModeA1 || ProcessMode == ModeA2 || ProcessMode == ModeA3 || ProcessMode == ModeA4 || ProcessMode == ModeA5 || ProcessMode == ModeC2 )
return( ERR_NOFile ) ;
else if ( ProcessMode == ModeB1 || ProcessMode == ModeB2 || ProcessMode == ModeB3 || ProcessMode == ModeB4 || ProcessMode == ModeB5 )
{
if ( Count == 1 )
{
s = x16RootDirectory( &files[ i ], ModeX1 ) ;
if ( s != DirectorySuccess )
return( s ) ;
}
else
{
s = x16Creat( &files[ i ], ModeX1 ) ;
if ( s != CreatSuccess )
return( s ) ;
}
}
else if ( ProcessMode == ModeC1 )
{
if ( Count == 1 )
{
s = x16RootDirectory( &files[ i ], ModeX2 ) ;
if ( s != DirectorySuccess )
return( s ) ;
}
else
{
s = x16Creat( &files[ i ], ModeX2 ) ;
if ( s != CreatSuccess )
return( s ) ;
}
files[ i ].Flags = 0 ;
}
}
else
{
if ( ProcessMode == ModeA3 || ProcessMode == ModeA4 || ProcessMode == ModeB3 || ProcessMode == ModeB4 )
{
s = xProcessDirectory( &files[ i ], ModeX3 ) ;
if ( s != DirectorySuccess )
return( s ) ;
}
else if ( ProcessMode == ModeC2 )
{
s = xProcessDirectory( &files[ i ], ModeX4 ) ;
if ( s != DirectorySuccess )
return( s ) ;
files[ i ].Flags = 0 ;
}
}
if ( ProcessMode == ModeC1 || ProcessMode == ModeC2 )
return( OpenSuccess ) ;
// 更新所打开的文件信息
POINT0 = files[ i ].find.Offset ;
files[ i ].clus.fat16.StartClus = ( UINT16 )( *( POINT0 + 26 ) ) | ( ( UINT16 )( *( POINT0 + 27 ) ) << 8 ) ;
files[ i ].clus.fat16.EndClus = files[ i ].clus.fat16.StartClus ;
files[ i ].FileSize = ( UINT32 )( *( POINT0 + 28 ) ) | ( ( UINT32 )( *( POINT0 + 29 ) ) << 8 ) | ( ( UINT32 )( *( POINT0 + 30 ) ) << 16 ) | ( ( UINT32 )( *( POINT0 + 31 ) ) << 24 ) ;
files[ i ].Sectors = ( UINT32 )( files[ i ].FileSize >> FAT.shift ) ;
files[ i ].ShortLength = ( UINT16 )( files[ i ].FileSize - ( UINT32 )( files[ i ].FileSize >> FAT.shift << FAT.shift ) ) ;
files[ i ].StartSector = ( ( files[ i ].clus.fat16.StartClus - 2 ) * FAT.SecPerClus ) + FAT.FirstDataSector ;
files[ i ].EndSector = files[ i ].StartSector ;
files[ i ].UsedSectors = files[ i ].ShortLength ? ( files[ i ].Sectors + 1 ) : files[ i ].Sectors ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -