📄 fatfunction.c
字号:
/****************************************Copyright (c)**************************************************
** CH374做主机操作U盘读写程序
** FAT16文件系统层
** 功能函数
**
** VBeat 0.5
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: FATFunction.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 "FATFunction.H"
/*********************************************************************************************************
** 函数名称: ProcessName
** 功能描述: 8 + 3文件名处理
**
** 输 入: string: 指向一个普通的文件名
** filename: 指向一个11字节的空数组
** 输 出: string指向的文件名被处理为11字节大小8 + 3文件名数组
**
** 全局变量: 无
** 调用模块: 无
** 调试码: DEBUG_NAME
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ProcessName( const UINT8 * string, UINT8 * filename )
{
#ifdef DEBUG_NAME
UINT8 i ;
#endif
UINT8 ExtFlag ;
UINT8 * POINT0 ;
UINT8 * POINT1 ;
UINT8 * POINT2 ;
//文件名数组初始化
for ( POINT0 = filename; POINT0 < ( filename + 11 ); POINT0 ++ )
* POINT0 = ' ' ;
//确认是否有扩展名
ExtFlag = 0 ;
for ( POINT0 = string ; *POINT0 != '\0' && POINT0 < ( string + 9 ) ; POINT0 ++ )
{
if ( *POINT0 != '.' )
continue ;
ExtFlag = 1 ;
break ;
}
//文件名处理
if ( ExtFlag )
{
for ( POINT0 = string, POINT1 = filename ; *POINT0 != '.' && POINT0 < string + 8 ; POINT0 ++, POINT1 ++ )
* POINT1 = * POINT0 ;
POINT2 = ++ POINT0 ;
for ( POINT1 = filename + 8 ; *POINT0 != '\0' && POINT0 < POINT2 + 3 ; POINT0 ++, POINT1 ++ )
* POINT1 = * POINT0 ;
}
else
{
for ( POINT0 = string, POINT1 = filename ; *POINT0 != '\0' && POINT0 < string + 8 ; POINT0 ++, POINT1 ++ )
* POINT1 = * POINT0 ;
}
//调试语句,查看转换是否正确
#ifdef DEBUG_NAME
for ( i = 0; i < 11; i ++ )
printf( " Process the conversion result : %c\n ", filename[ i ] ) ;
#endif
}
/*********************************************************************************************************
** 函数名称: ProcessPath
** 功能描述: 文件路径处理
**
** 输 入: string: 指向要操作的文件路径,路径输入格式: /……/……/……
** filename: 指向一个11字节的空数组
** 输 出: string指向的文件路径被处理为8 + 3字符数组
** A.返回EndPath报告路径处理结束,当前处理的是最终文件名
** B.否则返回继续标识符NextContinue
**
** 全局变量: 无
** 调用模块: ProcessName
** 调试码: DEBUG_PATH
**
**PS: A.暂时文件名输入需要尽可能准确,例如不要输入10个字符的基本名
** B.此程序因为没有对static变量Count初始化而导致POINT2指针乱飞,由于编译器会经常出现莫名其妙的问题
** 对static显式初始化很有必要
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8 ProcessPath( const UINT8 *string, UINT8 * filename )
{
UINT8 s ;
UINT8 *POINT0 ;
UINT8 *POINT1 ;
UINT8 *POINT3 ;
UINT8 temp[ 13 ] ;
static UINT8 *POINT2 ;
static UINT8 Count = 0 ;
POINT3 = strrchr( string, '/' ) ;
if ( ! Count )
POINT2 = string + 1 ;
//调试语句
#ifdef DEBUG_PATH
printf( " 路径字符串内存地址 = %p\n ", string ) ;
printf( " 静态指针变量POINT2地址 = %p\n ", POINT2 ) ;
printf( " 最后一个路径符号POINT3地址 = %p\n " , POINT3 ) ;
#endif
//临时数组初始化
for ( POINT0 = temp; POINT0 < ( temp + 13 ); POINT0 ++ )
* POINT0 = ' ' ;
if( POINT2 != POINT3 + 1 )
{
s = NextContinue ;
//将路径截取到临时数组中
for ( POINT0 = POINT2, POINT1 = temp; *POINT0 != '/' && POINT0 < ( POINT2 + 13 ) ; POINT0 ++, POINT1 ++ )
* POINT1 = * POINT0 ;
( * ++ POINT1 ) = '\0' ;
POINT2 = ++ POINT0 ;
ProcessName( temp, filename ) ;
Count ++ ;
}
else
{
Count = 0 ;
s = EndPath ;
ProcessName( POINT3+1, filename ) ;
}
//调试语句
#ifdef DEBUG_PATH
printf( " 本次要查找的文件/目录名 = %s\n ", filename ) ;
#endif
return( s ) ;
}
/*********************************************************************************************************
** 函数名称: x16List
** 功能描述: 根据簇号计算并读取FAT16表中相关信息
**
** 输 入: clus : 要计算的簇号
** value : 要更新的值
** ProcessMode: 函数工作模式
** A.ModeZ1: 更新FAT表
** B.ModeZ2: 查找FAT表中下个簇的值
** 输 出: A.返回ERR_List报告异常传输错误
** B.返回ListSuccess表示操作成功完成
** C.ModeZ2下会返回下个簇的值
** 全局变量: FAT.SecPerClus, FAT.FirstDataSector, DISKBUF
** 调用模块: mReadSector, mWriteSector
** 调试码: DEBUG_LIST
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT16 x16List( UINT16 clus, UINT16 value, UINT8 ProcessMode )
{
UINT8 s ;
UINT16 Cluster ;
UINT16 ThisFATEntOffset ;
UINT32 FATOffset ;
UINT32 ThisFATSecNum ;
//计算该簇号对应的起始扇区数以及FAT中偏移
FATOffset = clus << 1 ; //簇N在FAT16表中的偏移
ThisFATSecNum = FAT.RsvdSecCnt + ( FATOffset >> FAT.shift ) ; //簇N在FAT16表中的扇区号
ThisFATEntOffset = FATOffset - ( FATOffset >> FAT.shift << FAT.shift ) ; //簇N在FAT16表中的相对偏移
#ifdef DEBUG_LIST
printf( "簇%d在FAT16表中的相对偏移 = %d\n", clus, ThisFATEntOffset ) ;
printf( "簇N在FAT16表中的偏移 = %ld\n", FATOffset ) ;
printf( "簇N在FAT16表中的扇区号 = %ld\n", ThisFATSecNum ) ;
#endif
s = mReadSector( ThisFATSecNum , 0x01, DISKBUF );
if ( s != USB_INT_SUCCESS )
return( ERR_List ) ;
if ( ProcessMode == ModeZ2 )
{
Cluster = ( UINT16 )DISKBUF[ ThisFATEntOffset ] | ( UINT16 )DISKBUF[ ThisFATEntOffset + 1 ] << 8 ;
return( Cluster ) ;
}
else if ( ProcessMode == ModeZ1 )
{
DISKBUF[ ThisFATEntOffset ] = ( UINT8 )value ;
DISKBUF[ ThisFATEntOffset + 1 ] = ( UINT8 )( value >> 8 ) ;
s = mWriteSector( ThisFATSecNum , 0x01, DISKBUF );
if ( s != USB_INT_SUCCESS )
return( ERR_List ) ;
return( ListSuccess ) ;
}
}
/*********************************************************************************************************
** 函数名称: x16CheckClus
** 功能描述: FAT16查可写簇以便写入数据
**
** 输 入: 无
** 输 出: 返回找到的可写簇簇号
** A.返回ERR_CheckClus报告异常传输错误
** B.若磁盘簇已写满,返回簇号0
**
** 全局变量: FAT.RsvdSecCnt, FAT.FirstRootSector, FAT.BytesPerSec
** 调用模块: mReadSector, mWriteSector
** 调试码: 无
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT16 x16CheckClus( void )
{
UINT8 s ;
UINT8 FindFlag ; //查找成功标记
UINT8 *POINT0 ;
UINT16 Cluster ;
UINT32 ProcessSector ;
//初始化查找标记
FindFlag = 0 ;
for ( ProcessSector = FAT.RsvdSecCnt, POINT0 = DISKBUF + 4; ProcessSector < FAT.FirstRootSector; ProcessSector ++ )
{
s = mReadSector( ProcessSector, 0x01, DISKBUF ); //每次读取一个扇区的FAT表到DISKBUF中
if ( s != USB_INT_SUCCESS )
return( ERR_CheckClus ) ;
for ( ; POINT0 < DISKBUF + FAT.BytesPerSec; POINT0 += 2 ) //在DISKBUF里查找可写簇
{
if( ! ( *POINT0 ) && ! ( *( POINT0 + 1 ) ) )
{
FindFlag = 1 ;
break ;
}
}
//判断本次查找情况:
// A. 查到可写簇 -- 跳出查找循环
// B. 没有查到 -- 重置DISK_BUF内偏移量,继续下一次查找循环
if( ! FindFlag )
{
POINT0 = DISKBUF ;
continue ;
}
break ;
}
//查找结束,根据结果判断返回值
// A. 找到簇,返回实际簇号
// B. 磁盘簇已写满,返回0x00
if( FindFlag )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -