?? fatfunction.c
字號(hào):
/****************************************Copyright (c)**************************************************
** CH374做主機(jī)操作U盤讀寫程序
** FAT16文件系統(tǒng)層
** 功能函數(shù)
**
** VBeat 0.5
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: FATFunction.C
**創(chuàng) 建 人: 徐亦朱
**最后修改日期: 2007年9月27日
**描 述: FAT文件系統(tǒng)層功能函數(shù)
**
**--------------歷史版本信息----------------------------------------------------------------------------
** 創(chuàng)建人: 徐亦朱
** 版 本: VBeat 0.3
** 日 期: 2007年9月21日
** 描 述: 完善程序風(fēng)格
**
**--------------當(dāng)前版本修訂------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007年9月27日
** 描 述: 優(yōu)化數(shù)據(jù)結(jié)構(gòu)及算法
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include <stdio.h>
#include <string.h>
#include "HAL.H"
#include "HAL_BASE2.C"
#include "PARA_HW2.C"
#include "FAT.H"
#include "FATFunction.H"
/*********************************************************************************************************
** 函數(shù)名稱: ProcessName
** 功能描述: 8 + 3文件名處理
**
** 輸 入: string: 指向一個(gè)普通的文件名
** filename: 指向一個(gè)11字節(jié)的空數(shù)組
** 輸 出: string指向的文件名被處理為11字節(jié)大小8 + 3文件名數(shù)組
**
** 全局變量: 無
** 調(diào)用模塊: 無
** 調(diào)試碼: 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 ;
//文件名數(shù)組初始化
for ( POINT0 = filename; POINT0 < ( filename + 11 ); POINT0 ++ )
* POINT0 = ' ' ;
//確認(rèn)是否有擴(kuò)展名
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 ;
}
//調(diào)試語句,查看轉(zhuǎn)換是否正確
#ifdef DEBUG_NAME
for ( i = 0; i < 11; i ++ )
printf( " Process the conversion result : %c\n ", filename[ i ] ) ;
#endif
}
/*********************************************************************************************************
** 函數(shù)名稱: ProcessPath
** 功能描述: 文件路徑處理
**
** 輸 入: string: 指向要操作的文件路徑,路徑輸入格式: /……/……/……
** filename: 指向一個(gè)11字節(jié)的空數(shù)組
** 輸 出: string指向的文件路徑被處理為8 + 3字符數(shù)組
** A.返回EndPath報(bào)告路徑處理結(jié)束,當(dāng)前處理的是最終文件名
** B.否則返回繼續(xù)標(biāo)識(shí)符NextContinue
**
** 全局變量: 無
** 調(diào)用模塊: ProcessName
** 調(diào)試碼: DEBUG_PATH
**
**PS: A.暫時(shí)文件名輸入需要盡可能準(zhǔn)確,例如不要輸入10個(gè)字符的基本名
** B.此程序因?yàn)闆]有對(duì)static變量Count初始化而導(dǎo)致POINT2指針亂飛,由于編譯器會(huì)經(jīng)常出現(xiàn)莫名其妙的問題
** 對(duì)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 ;
//調(diào)試語句
#ifdef DEBUG_PATH
printf( " 路徑字符串內(nèi)存地址 = %p\n ", string ) ;
printf( " 靜態(tài)指針變量POINT2地址 = %p\n ", POINT2 ) ;
printf( " 最后一個(gè)路徑符號(hào)POINT3地址 = %p\n " , POINT3 ) ;
#endif
//臨時(shí)數(shù)組初始化
for ( POINT0 = temp; POINT0 < ( temp + 13 ); POINT0 ++ )
* POINT0 = ' ' ;
if( POINT2 != POINT3 + 1 )
{
s = NextContinue ;
//將路徑截取到臨時(shí)數(shù)組中
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 ) ;
}
//調(diào)試語句
#ifdef DEBUG_PATH
printf( " 本次要查找的文件/目錄名 = %s\n ", filename ) ;
#endif
return( s ) ;
}
/*********************************************************************************************************
** 函數(shù)名稱: x16List
** 功能描述: 根據(jù)簇號(hào)計(jì)算并讀取FAT16表中相關(guān)信息
**
** 輸 入: clus : 要計(jì)算的簇號(hào)
** value : 要更新的值
** ProcessMode: 函數(shù)工作模式
** A.ModeZ1: 更新FAT表
** B.ModeZ2: 查找FAT表中下個(gè)簇的值
** 輸 出: A.返回ERR_List報(bào)告異常傳輸錯(cuò)誤
** B.返回ListSuccess表示操作成功完成
** C.ModeZ2下會(huì)返回下個(gè)簇的值
** 全局變量: FAT.SecPerClus, FAT.FirstDataSector, DISKBUF
** 調(diào)用模塊: mReadSector, mWriteSector
** 調(diào)試碼: 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 ;
//計(jì)算該簇號(hào)對(duì)應(yīng)的起始扇區(qū)數(shù)以及FAT中偏移
FATOffset = clus << 1 ; //簇N在FAT16表中的偏移
ThisFATSecNum = FAT.RsvdSecCnt + ( FATOffset >> FAT.shift ) ; //簇N在FAT16表中的扇區(qū)號(hào)
ThisFATEntOffset = FATOffset - ( FATOffset >> FAT.shift << FAT.shift ) ; //簇N在FAT16表中的相對(duì)偏移
#ifdef DEBUG_LIST
printf( "簇%d在FAT16表中的相對(duì)偏移 = %d\n", clus, ThisFATEntOffset ) ;
printf( "簇N在FAT16表中的偏移 = %ld\n", FATOffset ) ;
printf( "簇N在FAT16表中的扇區(qū)號(hào) = %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 ) ;
}
}
/*********************************************************************************************************
** 函數(shù)名稱: x16CheckClus
** 功能描述: FAT16查可寫簇以便寫入數(shù)據(jù)
**
** 輸 入: 無
** 輸 出: 返回找到的可寫簇簇號(hào)
** A.返回ERR_CheckClus報(bào)告異常傳輸錯(cuò)誤
** B.若磁盤簇已寫滿,返回簇號(hào)0
**
** 全局變量: FAT.RsvdSecCnt, FAT.FirstRootSector, FAT.BytesPerSec
** 調(diào)用模塊: mReadSector, mWriteSector
** 調(diào)試碼: 無
**
**
** 作 者: 徐亦朱
** 日 期: 2007年9月21日
**-------------------------------------------------------------------------------------------------------
** 修改人: 徐亦朱
** 日 期: 2007.9.27
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT16 x16CheckClus( void )
{
UINT8 s ;
UINT8 FindFlag ; //查找成功標(biāo)記
UINT8 *POINT0 ;
UINT16 Cluster ;
UINT32 ProcessSector ;
//初始化查找標(biāo)記
FindFlag = 0 ;
for ( ProcessSector = FAT.RsvdSecCnt, POINT0 = DISKBUF + 4; ProcessSector < FAT.FirstRootSector; ProcessSector ++ )
{
s = mReadSector( ProcessSector, 0x01, DISKBUF ); //每次讀取一個(gè)扇區(qū)的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. 查到可寫簇 -- 跳出查找循環(huán)
// B. 沒有查到 -- 重置DISK_BUF內(nèi)偏移量,繼續(xù)下一次查找循環(huán)
if( ! FindFlag )
{
POINT0 = DISKBUF ;
continue ;
}
break ;
}
//查找結(jié)束,根據(jù)結(jié)果判斷返回值
// A. 找到簇,返回實(shí)際簇號(hào)
// B. 磁盤簇已寫滿,返回0x00
if( FindFlag )
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -