?? fat.c
字號:
/****************************************Copyright (c)**************************************************
** 廣州周立功單片機發展有限公司
** 研 究 所
** ARM開發組
**
** http://www.zlgmcu.com
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: floppy.c
**創 建 人: 陳明計
**最后修改日期: 2003年9月5日
**描 述: FAT文件系統的文件分配表基本操作函數
**
**--------------歷史版本信息----------------------------------------------------------------------------
** 創建人: 陳明計
** 版 本: V1.0
** 日 期: 2003年9月5日
** 描 述: 原始版本
**
**--------------當前版本修訂------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2004年4月10日
** 描 述: 修改注釋
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#define IN_FAT
#include "config.h"
/*********************************************************************************************************
** 函數名稱: FATGetNextClus
** 功能描述: 返回FAT表指定簇的下一個簇號
**
** 輸 入: Drive:驅動器號
** Index:簇號
** 輸 出: 下一個簇號
**
** 全局變量: 無
** 調用模塊: 無
**
** 作 者: 陳明計
** 日 期: 2003年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2004年4月10日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint32 FATGetNextClus(uint8 Drive, uint32 Index)
{
uint16 temp, ByteIndex;
uint32 SecIndex;
uint8 *Buf;
Disk_Info * Disk;
uint32 Rt;
Disk = GetDiskInfo(Drive);
if (Disk == NULL)
{
return BAD_CLUS;
}
if (Index >= (Disk->ClusPerData))
{
return BAD_CLUS;
}
/* 計算扇區號和字節索引 */
switch (Disk->FATType)
{
case FAT12:
SecIndex = Index * 3 / (2 * Disk->BytsPerSec);
ByteIndex = ((Index * 3) / 2) - (SecIndex * Disk->BytsPerSec);
SecIndex += Disk->FATStartSec;
break;
case FAT16:
SecIndex = Index * 2 / Disk->BytsPerSec + Disk->FATStartSec;
ByteIndex = (Index * 2) & (Disk->BytsPerSec - 1);
break;
case FAT32:
SecIndex = Index * 4 / Disk->BytsPerSec + Disk->FATStartSec;
ByteIndex = (Index * 4) & (Disk->BytsPerSec - 1);
break;
default:
return BAD_CLUS;
}
Buf = OpenSec(Drive, SecIndex);
if (Buf == NULL)
{
return BAD_CLUS;
}
ReadSec(Drive, SecIndex);
/* 讀取FAT表數據 */
switch (Disk->FATType)
{
case FAT12:
temp = Buf[ByteIndex];
ByteIndex++;
if (ByteIndex >= Disk->BytsPerSec) /* 下一個字節是否在下一個扇區 */
{
Buf = OpenSec(Drive, SecIndex + 1);
if (Buf == NULL)
{
return BAD_CLUS;
}
ReadSec(Drive, SecIndex + 1);
temp = temp | (Buf[0] << 8);
CloseSec(Drive, SecIndex + 1);
}
else
{
temp = temp | (Buf[ByteIndex] << 8);
}
if ((Index & 0x01) != 0) /* 判斷哪12位有效 */
{
temp = temp / 16;
}
else
{
temp = temp & 0x0fff;
}
Rt = temp;
if (temp >= (BAD_CLUS & 0x0fff)) /* 是否有特殊意義 */
{
Rt = ((uint32)0x0fffL << 16) | (temp | 0xf000);
}
break;
case FAT16:
temp = Buf[ByteIndex] | (Buf[ByteIndex + 1] << 8);
Rt = temp;
if (temp >= (BAD_CLUS & 0xffff)) /* 是否有特殊意義 */
{
Rt = ((uint32)0x0fffL << 16) | temp;
}
break;
case FAT32:
Rt = Buf[ByteIndex] | (Buf[ByteIndex + 1] << 8);
Rt |= ((uint32)Buf[ByteIndex + 2] << 16) | ((uint32)Buf[ByteIndex + 3] << 24);
Rt = Rt & 0x0fffffff;
break;
default:
Rt = BAD_CLUS;
break;
}
CloseSec(Drive, SecIndex);
return Rt;
}
/*********************************************************************************************************
** 函數名稱: FATSetNextClus
** 功能描述: 設置下一個簇
**
** 輸 入: Drive:驅動器號
** Index:簇號
** Next:下一個簇號
** 輸 出: 無
**
** 全局變量: 無
** 調用模塊: 無
**
** 作 者: 陳明計
** 日 期: 2003年9月6日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2004年4月10日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void FATSetNextClus(uint8 Drive, uint32 Index, uint32 Next)
{
uint16 temp;
uint16 SecIndex, ByteIndex;
uint8 *Buf;
Disk_Info * Disk;
Disk = GetDiskInfo(Drive);
if (Disk == NULL)
{
return;
}
if (Index <= EMPTY_CLUS_1)
{
return;
}
if (Index >= Disk->ClusPerData)
{
return;
}
/* 計算扇區號和字節索引 */
switch (Disk->FATType)
{
case FAT12:
SecIndex = Index * 3 / (2 * Disk->BytsPerSec);
ByteIndex = ((Index * 3) / 2) - (SecIndex * Disk->BytsPerSec);
SecIndex += Disk->FATStartSec;
break;
case FAT16:
SecIndex = Index * 2 / Disk->BytsPerSec + Disk->FATStartSec;
ByteIndex = (Index * 2) & (Disk->BytsPerSec - 1);
break;
case FAT32:
SecIndex = Index * 4 / Disk->BytsPerSec + Disk->FATStartSec;
ByteIndex = (Index * 4) & (Disk->BytsPerSec - 1);
break;
default:
return;
}
Buf = OpenSec(Drive, SecIndex);
if (Buf == NULL)
{
return;
}
ReadSec(Drive, SecIndex);
switch (Disk->FATType)
{
case FAT12:
temp = Next & 0x0fff;
if ((Index & 0x01) != 0) /* 判斷哪12位有效 */
{
temp = temp * 16;
temp |= (Buf[ByteIndex] & 0x0f);
Buf[ByteIndex] = temp;
}
else
{
Buf[ByteIndex] = temp;
}
ByteIndex++;
temp = temp >> 8;
if (ByteIndex >= Disk->BytsPerSec) /* 下一個字節是否在下一個扇區 */
{
Buf = OpenSec(Drive, SecIndex + 1);
if (Buf == NULL)
{
break;
}
ReadSec(Drive, SecIndex + 1);
if ((Index & 0x01) != 0) /* 判斷哪12位有效 */
{
Buf[0] = temp;
}
else
{
Buf[0] = (Buf[0] & 0xf0) | temp;
}
WriteSec(Drive, SecIndex + 1);
CloseSec(Drive, SecIndex + 1);
}
else
{
if ((Index & 0x01) != 0) /* 判斷哪12位有效 */
{
Buf[ByteIndex] = temp;
}
else
{
Buf[ByteIndex] = (Buf[ByteIndex] & 0xf0) | temp;
}
}
break;
case FAT16:
Buf[ByteIndex] = Next;
Buf[ByteIndex + 1] = Next >> 8;
break;
case FAT32:
Buf[ByteIndex] = Next;
Buf[ByteIndex + 1] = Next >> 8;
Buf[ByteIndex + 2] = Next >> 16;
Buf[ByteIndex + 3] = (Buf[ByteIndex + 3] & 0xf0) | ((Next >> 24) & 0x0f);
break;
default:
break;
}
WriteSec(Drive, SecIndex);
CloseSec(Drive, SecIndex);
return ;
}
/*********************************************************************************************************
** 函數名稱: FATAddClus
** 功能描述: 為指定簇鏈增加一個簇
**
** 輸 入: Drive:驅動器號
** Index:簇鏈中任意一個簇號,如果為0,則為一個空鏈增加一個簇
** 輸 出: 增加的簇號
**
** 全局變量: 無
** 調用模塊: 無
**
** 作 者: 陳明計
** 日 期: 2003年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2004年4月10日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint32 FATAddClus(uint8 Drive, uint32 Index)
{
uint32 NextClus,ThisClus,MaxClus;
Disk_Info * Disk;
Disk = GetDiskInfo(Drive);
if (Disk == NULL)
{
return BAD_CLUS;
}
if (Index >= BAD_CLUS)
{
return BAD_CLUS;
}
MaxClus = Disk->ClusPerData;
/* 查找最后一個簇 */
ThisClus = Index;
if (ThisClus != EMPTY_CLUS && ThisClus != EMPTY_CLUS_1)
{
while (1)
{
NextClus = FATGetNextClus(Drive, ThisClus);
if (NextClus >= EOF_CLUS_1)
{
break;
}
if (NextClus <= EMPTY_CLUS_1)
{
break;
}
if (NextClus == BAD_CLUS)
{
return BAD_CLUS;
}
ThisClus = NextClus;
}
}
else
{
ThisClus = EMPTY_CLUS_1;
}
for (NextClus = ThisClus + 1; NextClus < MaxClus; NextClus++)
{
if (FATGetNextClus(Drive, NextClus) == EMPTY_CLUS)
{
break;
}
}
if (NextClus >= MaxClus)
{
for (NextClus = EMPTY_CLUS_1 + 1; NextClus < ThisClus; NextClus++)
{
if (FATGetNextClus(Drive, NextClus) == EMPTY_CLUS)
{
break;
}
}
}
if (FATGetNextClus(Drive, NextClus) == EMPTY_CLUS)
{
if (ThisClus > EMPTY_CLUS_1)
{
FATSetNextClus(Drive, ThisClus, NextClus);
}
FATSetNextClus(Drive, NextClus, EOF_CLUS_END);
return NextClus;
}
else
{
return BAD_CLUS;
}
}
/*********************************************************************************************************
** 函數名稱: FATDelClusChain
** 功能描述: 刪除指定簇鏈
**
** 輸 入: Drive:驅動器號
** Index:簇鏈中首簇號
** 輸 出: 無
**
** 全局變量: 無
** 調用模塊: FATGetNextClus,FATSetNextClus
**
** 作 者: 陳明計
** 日 期: 2003年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2004年4月10日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void FATDelClusChain(uint8 Drive, uint32 Index)
{
uint32 NextClus, ThisClus;
if (Index <= EMPTY_CLUS_1)
{
return;
}
if (Index >= BAD_CLUS)
{
return;
}
ThisClus = Index;
while (1)
{
NextClus = FATGetNextClus(Drive, ThisClus);
FATSetNextClus(Drive, ThisClus, EMPTY_CLUS);
if (NextClus >= BAD_CLUS)
{
break;
}
if (NextClus <= EMPTY_CLUS_1)
{
break;
}
ThisClus = NextClus;
}
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -