📄 fatprocess.c
字号:
files[ i ].clus.fat16.NextClus = x16List( files[ i ].clus.fat16.StartClus, 0, ModeZ2 ) ;
//调试语句
#ifdef DEBUG_OPEN
printf( " 显示文件信息: \n " ) ;
printf( " 本文件编号: %d\n ", ( UINT16 )i ) ;
printf( " 本文件起始簇簇号:%d\n ", files[ i ].clus.fat16.StartClus ) ;
printf( " 本文件长度:%ld\n ", files[ i ].FileSize ) ;
printf( " 本文件所用扇区数:%ld\n ", files[ i ].Sectors) ;
printf( " 本文件零碎数据长度 : %d 字节\n ", files[ i ].ShortLength ) ;
printf( " 本文件占用扇区数: %ld\n ", files[ i ].UsedSectors ) ;
printf( " 即将要操作的下个簇簇号: %d\n ", files[ i ].clus.fat16.NextClus ) ;
#endif
if ( ProcessMode == ModeA1 || ProcessMode == ModeA3 || ProcessMode == ModeB1 || ProcessMode == ModeB3 )
{
//为读取文件初始化
files[ i ].Flags &= 0xF7 ;
if ( files[ i ].clus.fat16.NextClus == 0xFFFF )
{
files[ i ].wr.read.LastClu = 0x01 ;
files[ i ].wr.read.RemainSectors = files[ i ].UsedSectors ;
}
else
{
files[ i ].wr.read.LastClu = 0x00 ;
files[ i ].wr.read.RemainSectors = FAT.SecPerClus ;
}
}
else if ( ProcessMode == ModeA2 || ProcessMode == ModeA4 || ProcessMode == ModeA5 || ProcessMode == ModeB2 || ProcessMode == ModeB4 || ProcessMode == ModeB5 )
{
//为写入文件初始化
files[ i ].Flags |= 0x08 ;
if ( ! files[ i ].clus.fat16.StartClus && ! files[ i ].FileSize )//说明这是一个空文件,没有任何信息
{
files[ i ].wr.write.extra = 0 ;
//查新簇
files[ i ].clus.fat16.StartClus = x16CheckClus( ) ;
if ( files[ i ].clus.fat16.StartClus == 0x00 )
return( ERR_FullDisk ) ;
else if ( files[ i ].clus.fat16.StartClus == ERR_CheckClus )
return( ERR_CheckClus ) ;
//更新根目录中起始簇信息
//调试语句
#ifdef DEBUG_OPEN
printf( " 该文件本来是一个空文件.\n " ) ;
printf( " 更新根目录中起始簇信息: " ) ;
#endif
ProcessSector = files[ i ].find.Sector ;
POINT0 = files[ i ].find.Offset ;
TransNum = files[ i ].find.TransNum ;
s = mReadSector( ProcessSector, TransNum, DISKBUF );
if ( s != USB_INT_SUCCESS )
return( ERR_Write ) ;
*( POINT0 + 26 ) = ( UINT8 )files[ i ].clus.fat16.StartClus ;
*( POINT0 + 27 ) = ( UINT8 )( files[ i ].clus.fat16.StartClus >> 8 ) ;
//调试语句
#ifdef DEBUG_OPEN
printf( " 更新的起始簇号:%d \n ", files[ i ].clus.fat16.StartClus ) ;
#endif
s = mWriteSector( ProcessSector, TransNum, DISKBUF );
if ( s != USB_INT_SUCCESS )
return( ERR_Write ) ;
files[ i ].clus.fat16.EndClus = files[ i ].clus.fat16.StartClus ;
files[ i ].StartSector = ( ( files[ i ].clus.fat16.StartClus - 2 ) * FAT.SecPerClus ) + FAT.FirstDataSector ;
files[ i ].EndSector = files[ i ].StartSector ;
files[ i ].wr.write.WritedSectors = 0 ;
}
else
{
UINT8 mainsectors = files[ i ].Sectors % FAT.SecPerClus ;
#ifdef DEBUG_OPEN
printf( " 该文件本来就有数据.\n " ) ;
#endif
while ( ( Cluster = x16List( files[ i ].clus.fat16.EndClus, 0, ModeZ2 ) ) != 0xFFFF )
files[ i ].clus.fat16.EndClus = Cluster ;
printf( " files[ i ].clus.fat16.EndClus = %d\n ", files[ i ].clus.fat16.EndClus ) ;
if ( ! mainsectors && ! files[ i ].ShortLength ) //如果一簇正好满
{
files[ i ].wr.write.extra = 0 ;
Cluster = x16CheckClus( ) ;
if ( Cluster == 0x00 )
return( ERR_FullDisk ) ;
else if ( Cluster == ERR_CheckClus )
return( ERR_CheckClus ) ;
s = x16List( files[ i ].clus.fat16.EndClus, Cluster, ModeZ1 ) ;
if( s != ListSuccess )
return( s ) ;
files[ i ].clus.fat16.EndClus = Cluster ;
files[ i ].wr.write.WritedSectors = 0 ;
}
else if ( ! files[ i ].ShortLength )
{
files[ i ].wr.write.extra = 0 ;
files[ i ].wr.write.WritedSectors = mainsectors ;
}
else
{
files[ i ].wr.write.extra = files[ i ].ShortLength ;
files[ i ].wr.write.WritedSectors = mainsectors ;
printf( " files[ i ].wr.write.WritedSectors = %d\n ", ( UINT16 )files[ i ].wr.write.WritedSectors ) ;
printf( " files[ i ].wr.write.extra = %d\n ", files[ i ].wr.write.extra ) ;
}
files[ i ].EndSector = ( ( files[ i ].clus.fat16.EndClus - 2 ) * FAT.SecPerClus ) + FAT.FirstDataSector + mainsectors ;
printf( " files[ i ].EndSector = %d\n ", ( UINT16 )files[ i ].EndSector ) ;
//若有零碎数据,将其读出
if ( files[ i ].wr.write.extra )
{
s = mReadSector( files[ i ].EndSector, 1, FILEBUF );
if ( s != USB_INT_SUCCESS )
return( ERR_Write ) ;
}
}
}
return( OpenSuccess ) ;
}
/*********************************************************************************************************
** 函数名称: x16ReadFile
** 功能描述: FAT16读取文件
**
** 输 入: ReadNums: 可选的读取扇区数,若文件数据小于要求量,只会读取文件实际长度
** 输 出: 将所要求数量的文件数据读取到文件缓冲区FILE_BUF
** A.返回ERR_Read报告异常传输错误
** B.返回Clu_End表示一簇已读完,由于程序算法问题,此时FILEBUF中有效数据可能不足2048字节
** C.返回File_End表示文件已读完,由于程序算法问题,此时FILEBUF中应有零碎数据( 不满一个扇区 )
** D.返回ReadSuccess表示读取成功完成,并且不属于上述情况
**
** 全局变量: files[ i ].find.Offset, FAT.SecPerClus, rFILEBUF
** 调用模块: x16ReadFAT, mReadSector,
** 调试码: DEBUG_READ
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8 x16ReadFile( UINT8 ReadNums, UINT8 FileNum )
{
UINT8 i ;
UINT8 s ;
UINT8 TransNum ;
UINT32 ProcessSector ;
/*
for ( i = 0; i < 2; i ++ )
printf( "files[ i ].Flags = %d\n", ( UINT16 )files[ i ].Flags ) ;
//确定指定文件是否有效
for ( i = 0; i < 2; i ++ )
if ( ( files[ i ].Flags & 0x07 ) == FileNum )
break ;
if ( ! ( files[ i ].Flags & 0x80 ) || files[ i ].Flags & 0x08 || ( ( files[ i ].Flags & 0x07) != i ) )
{
printf( " 错误的文件编号: %d\n ", ( UINT16 )i ) ;
return( ERR_Read ) ;
}*/
/* 下面这段实际只是为保险起见,在程序测试无错后可以用下面这句代替 */
i = FileNum ;
//调试语句
#ifdef DEBUG_READ
printf( " 开始读取文件. \n " ) ;
printf( " 显示所读文件相关信息: \n " ) ;
printf( " 本文件起始簇簇号:%d\n ", files[ i ].clus.fat16.StartClus ) ;
printf( " 目前已读到簇号: %d\n ", files[ i ].clus.fat16.EndClus ) ;
printf( " 将要读取的起始扇区号 : %lu\n ", files[ i ].EndSector ) ;
printf( " 本文件长度:%ld\n ", files[ i ].FileSize ) ;
printf( " 目前还有%ld扇区未读.\n ", files[ i ].Sectors ) ;
printf( " 本文件零碎数据长度 : %d 字节\n ", files[ i ].ShortLength ) ;
#endif
ProcessSector = files[ i ].EndSector ;
TransNum = ( files[ i ].wr.read.RemainSectors >= FileNums ) ? FileNums : files[ i ].wr.read.RemainSectors ;
TransNum = ( TransNum > ReadNums ) ? ReadNums : TransNum ;
//调试语句
#ifdef DEBUG_READ
printf( " 要读取的扇区数:%d\n ", ( UINT16 )TransNum ) ;
printf( " 现在是文件的最后一个簇了吗 ? Answer = %d\n ", ( UINT16 )files[ i ].wr.read.LastClu ) ;
#endif
s = mReadSector( ProcessSector, TransNum, rFILEBUF );
if ( s != USB_INT_SUCCESS )
return( ERR_Read ) ;
files[ i ].wr.read.ReadSectors = TransNum ;
files[ i ].wr.read.RemainSectors -= TransNum ;
//调试语句
#ifdef DEBUG_READ
printf( " 该簇剩余扇区数 = %d\n ", ( UINT16 )files[ i ].wr.read.RemainSectors ) ;
#endif
if( ! files[ i ].wr.read.RemainSectors ) //剩余扇区数为0,即一簇已读完
{
if( ! files[ i ].wr.read.LastClu )
//上次读取的不是文件的最后一个簇,下次继续读取文件
{
//调试语句
#ifdef DEBUG_READ
printf( " 一簇已读完!\n " ) ;
#endif
files[ i ].UsedSectors -= ( UINT32 )FAT.SecPerClus ;
files[ i ].clus.fat16.EndClus = files[ i ].clus.fat16.NextClus ;
if ( ( files[ i ].clus.fat16.NextClus = x16List( files[ i ].clus.fat16.EndClus, 0, ModeZ2 ) ) == 0xFFFF )
{
files[ i ].wr.read.LastClu = 1 ;
files[ i ].wr.read.RemainSectors = files[ i ].UsedSectors ;
}
else
{
files[ i ].wr.read.LastClu = 0 ;
files[ i ].wr.read.RemainSectors = FAT.SecPerClus ;
}
files[ i ].EndSector = ( ( files[ i ].clus.fat16.EndClus - 2 ) * FAT.SecPerClus ) + FAT.FirstDataSector ;
return( Clu_End ) ;
}
else //最后一个簇,与前一if嵌套实际说明文件已经全部读完
{
//调试语句
#ifdef DEBUG_READ
printf( " 文件已经读取完毕!\n " ) ;
#endif
return( File_End ) ;
}
}
else //未读到簇完
{
files[ i ].EndSector += TransNum ;
}
return( ReadSuccess ) ;
}
/*********************************************************************************************************
** 函数名称: x16WriteFile
** 功能描述: FAT16写文件
**
** 输 入: WriteNums: 可选的写入字节数
** 输 出: 将FILE_BUF中的数据写入文件
** A.返回ERR_Write报告异常传输错误
** B.返回WriteSuccess则写入成功返回
** C.返回ERR_FullDisk表示磁盘已写满,无法正常写入数据
**
** 全局变量: FAT.SecPerClus, FAT.SecPerClus, files[ i ].wr.write.extra
** 调用模块: x16CheckClus, mReadSector, mWriteSector, x16List, memmove, memcpy
** 调试码: DEBUG_WRITE
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8 x16WriteFile( UINT16 WriteNums, UINT8 FileNum )
{
UINT8 i ;
UINT8 s ;
UINT8 TransNum ;
UINT8 writesectors ;
UINT16 TransBytes ; //传输的字节数
UINT16 Cluster ;
UINT16 bytes ;
UINT32 ProcessSector ;
/*
for ( i = 0; i < 2; i ++ )
printf( "files[ i ].Flags = %d\n", ( UINT16 )files[ i ].Flags ) ;
//确定指定文件是否有效
for ( i = 0; i < 2; i ++ )
if ( ( files[ i ].Flags & 0x07 ) == FileNum )
break ;
if ( ! ( files[ i ].Flags & 0x80 ) || ! ( files[ i ].Flags & 0x08 ) || ( ( files[ i ].Flags & 0x07 ) != i ) )
{
printf( " 错误的文件编号: %d\n ", ( UINT16 )i ) ;
return( ERR_Write ) ;
}*/
/* 上面这段实际只是为保险起见,在程序测试无错后可以用下面这句代替 */
i = FileNum ;
//判断WriteNums是否合理
WriteNums = ( WriteNums > 2048 ) ? 2048 : WriteNums ;
//计算FILE_BUF中数据长度
//调试语句
#ifdef DEBUG_WRITE
printf( " 更新文件长度信息 .\n " ) ;
printf( " 文件原长度 = %lu\n ", files[ i ].FileSize ) ;
#endif
files[ i ].FileSize += ( UINT32 )WriteNums ;
//调试语句
#ifdef DEBUG_WRITE
printf( " 更新文件长度信息 .\n " ) ;
printf( " 数据最新长度 = %lu\n ", files[ i ].FileSize ) ;
#endif
/*--------------------------------------------------------------------
以下if-else结构用来写入数据到文件中
分两种情况考虑:
A:一次传输的数据越界了
B:未越界,全部传输到一个簇内
-------------------------------------------------------------------- */
//调试语句
#ifdef DEBUG_WRITE
printf( "写入数据 !\n" ) ;
printf( " 用以判断越界的数据信息 :\n " ) ;
printf( " 簇内已写的扇区数: " ) ;
printf( " %d \n ", ( UINT16 )files[ i ].wr.write.WritedSectors ) ;
printf( " 文件缓冲区内一次能传输的扇区数 :\n " ) ;
printf( " FileNums = %d \n ", ( UINT16 )FileNums ) ;
printf( " DISK每簇扇区数: " ) ;
printf( " FAT.SecPerClus = %d \n ", ( UINT16 )FAT.SecPerClus ) ;
#endif
//处理零碎数据
memcpy ( FILEBUF + files[ i ].wr.write.extra, rFILEBUF, WriteNums ) ;
if ( WriteNums == 2048 )
{
writesectors = FileNums ;
bytes = 0 ;
}
else if ( bytes = WriteNums - ( WriteNums >> FAT.shift << FAT.shift ) )
{
writesectors = ( WriteNums + files[ i ].wr.write.extra ) >> FAT.shift ;
if ( ! writesectors )
{
files[ i ].wr.write.extra = files[ i ].wr.write.extra + bytes ;
#ifdef DEBUG_WRITE
printf( " 写入成功 ! \n " ) ;
#endif
return( WriteSuccess ) ;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -