?? disk.c
字號:
/****************************************Copyright (c)**************************************************
** 廣州周立功單片機發展有限公司
** 研 究 所
** ARM開發組
**
** http://www.zlgmcu.com
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: disk.c
**創 建 人: 陳明計
**最后修改日期: 2003年9月3日
**描 述: FAT文件系統關于邏輯盤管理的部分
**
**--------------歷史版本信息----------------------------------------------------------------------------
** 創建人: 陳明計
** 版 本: V1.0
** 日 期: 2003年9月3日
** 描 述: 原始版本
**
**--------------當前版本修訂------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2004年4月10日
** 描 述: 增加注釋
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#define IN_DISK
#include "config.h"
Disk_Info DiskInfo[MAX_DRIVES]; //邏輯盤信息
/*********************************************************************************************************
** 函數名稱: DiskInit
** 功能描述: 初始化邏輯盤管理模塊
**
** 輸 入: 無
**
** 輸 出: 無
**
** 全局變量: DiskInfo
** 調用模塊: 無
**
** 作 者: 陳明計
** 日 期: 2003年9月3日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2004年4月10日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DiskInit(void)
{
uint8 i;
for (i = 0; i < MAX_DRIVES; i++)
{
DiskInfo[i].Drive = EMPTY_DRIVE; // 沒有分配
DiskInfo[i].FATType = 0xff; // 無效的文件系統
DiskInfo[i].SecPerClus = 0; // 每簇扇區數
DiskInfo[i].NumFATs = 0; // FAT表數
DiskInfo[i].SecPerDisk = 0xffffffff;// 邏輯驅動器包含扇區數
DiskInfo[i].BytsPerSec = 0; // 每扇區字節數
DiskInfo[i].RootDirTable = 0; // 根目錄開始扇區號(FAT32為開始簇號)
DiskInfo[i].RootSecCnt = 0; // 根目錄占用扇區數
DiskInfo[i].FATStartSec = 0; // FAT表開始扇區號
DiskInfo[i].FATSecCnt = 0; // 每個FAT占用扇區數
DiskInfo[i].DataStartSec = 0; // 數據區開始扇區號
DiskInfo[i].PathClusIndex = 0; // 當前目錄
DiskInfo[i].DiakCommand = NULL; // 驅動程序
}
CacheInit(); //初始化磁盤cache
}
/*********************************************************************************************************
** 函數名稱: GetDiskInfo
** 功能描述: 獲取指定邏輯盤信息
**
** 輸 入: 邏輯盤號
**
** 輸 出: 指向邏輯盤信息的結構體指針
**
** 全局變量: DiskInfo
** 調用模塊: 無
**
** 作 者: 陳明計
** 日 期: 2003年9月3日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
Disk_Info * GetDiskInfo(uint8 Drive)
{
Disk_Info *Rt;
Rt = NULL;
if (Drive < MAX_DRIVES)
{
if (DiskInfo[Drive].Drive != EMPTY_DRIVE)
{
Rt = DiskInfo + Drive;
}
}
return Rt;
}
/*********************************************************************************************************
** 函數名稱: GetEmptyDiskInfoAddr
** 功能描述: 獲取空閑邏輯盤
**
** 輸 入: 無
**
** 輸 出: 指向邏輯盤信息的結構體指針
**
** 全局變量: DiskInfo
** 調用模塊: 無
**
** 作 者: 陳明計
** 日 期: 2003年9月3日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
Disk_Info * GetEmptyDiskInfoAddr(void)
{
uint8 i;
Disk_Info *Rt;
Rt = NULL;
for (i = 0; i < MAX_DRIVES; i++)
{
if (DiskInfo[i].Drive == EMPTY_DRIVE) // 邏輯盤號空閑
{
Rt = DiskInfo + i;
DiskInfo[i].Drive = i;
break;
}
}
return Rt;
}
/*********************************************************************************************************
** 函數名稱: AddFileDriver
** 功能描述: 增加一個底層驅動程序
**
** 輸 入: DiakCommand:驅動程序接口函數
**
** 輸 出: 無
**
** 全局變量: DiskInfo
** 調用模塊: 無
**
** 作 者: 陳明計
** 日 期: 2003年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2004年4月10日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void AddFileDriver(uint16 (* DiakCommand)(uint8 Cammand, void *Parameter))
{
uint8 i;
uint8 *Buf;
uint16 temp;
uint32 temp1;
if (DiakCommand == NULL) // 參數無效退出
{
return;
}
if (DiakCommand(DISK_INIT, NULL) == DISK_INIT_NOT_OK) // 底層驅動初始化不成功退出
{
return;
}
/* 重新獲取邏輯盤信息 */
for (i = 0; i < MAX_DRIVES; i++)
{
if (DiskInfo[i].Drive != EMPTY_DRIVE) /* 邏輯盤已分配 */
{
Buf = OpenSec(DiskInfo[i].Drive, 0); /* 打開扇區0(保留扇區) */
ReadSec(DiskInfo[i].Drive, 0);
if (Buf != NULL)
{
/* 每扇區字節數 */
DiskInfo[i].BytsPerSec = Buf[11] | (Buf[12] << 8);
/* 每簇扇區數 */
DiskInfo[i].SecPerClus = Buf[13];
/* FAT開始扇區號 */
DiskInfo[i].FATStartSec = Buf[14] | (Buf[15] << 8);
/* FAT表個數 */
DiskInfo[i].NumFATs = Buf[16];
/* 根目錄占扇區數 */
DiskInfo[i].RootSecCnt = ((Buf[17] | (Buf[18] << 8)) * 32 +
DiskInfo[i].BytsPerSec - 1) /
DiskInfo[i].BytsPerSec;
/* 邏輯盤(卷)占扇區數 */
temp = Buf[19] | (Buf[20] << 8);
if (temp != 0)
{
DiskInfo[i].SecPerDisk = temp;
}
else
{
DiskInfo[i].SecPerDisk = Buf[32] | (Buf[33] << 8);
DiskInfo[i].SecPerDisk |= (((uint32)Buf[34] << 16) | ((uint32)Buf[35] << 24));
}
/* FAT表占用扇區數 */
temp = Buf[22] | (Buf[23] << 8);
if (temp != 0)
{
DiskInfo[i].FATSecCnt = temp;
}
else
{
DiskInfo[i].FATSecCnt = Buf[36] | (Buf[37] << 8);
DiskInfo[i].FATSecCnt |= (((uint32)Buf[38] << 16) | (uint32)(Buf[39] << 24));
}
/* 當前目錄為根目錄 */
DiskInfo[i].PathClusIndex = 0;
}
/* 根目錄開始扇區號 */
DiskInfo[i].RootDirTable = DiskInfo[i].NumFATs * DiskInfo[i].FATSecCnt +
DiskInfo[i].FATStartSec;
/* 數據區開始扇區號 */
DiskInfo[i].DataStartSec = DiskInfo[i].RootDirTable + DiskInfo[i].RootSecCnt;
temp1 = DiskInfo[i].SecPerDisk - DiskInfo[i].DataStartSec;
temp1 = temp1 / DiskInfo[i].SecPerClus;
DiskInfo[i].ClusPerData = temp1;
/* 判斷是FAT12、FAT16還是FAT32 */
if (temp1 < 4085)
{
DiskInfo[i].FATType = FAT12;
}
else if (temp1 < 65525)
{
DiskInfo[i].FATType = FAT16;
}
else
{
DiskInfo[i].FATType = FAT32;
/* FAT32 RootDirTable為開始簇號 */
DiskInfo[i].RootDirTable = Buf[44] | (Buf[45] << 8);
DiskInfo[i].RootDirTable |= (((uint32)Buf[46] << 16) | ((uint32)Buf[47] << 24));
DiskInfo[i].PathClusIndex = DiskInfo[i].RootDirTable;
}
CloseSec(DiskInfo[i].Drive, 0); /* 關閉扇區 */
}
}
}
/*********************************************************************************************************
** 函數名稱: RemoveFileDriver
** 功能描述: 刪除一個底層驅動程序
**
** 輸 入: Drive:邏輯驅動器號
**
** 輸 出: 無
**
** 全局變量: DiskInfo
** 調用模塊: 無
**
** 作 者: 陳明計
** 日 期: 2003年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2004年4月10日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void RemoveFileDriver(uint8 Drive)
{
Disk_RW_Parameter Pa;
if (Drive < MAX_DRIVES)
if (DiskInfo[Drive].Drive != EMPTY_DRIVE)
{
AllCacheWriteBack();
Pa.Drive = Drive;
Pa.RsvdForLow = DiskInfo[Drive].RsvdForLow;
DiskInfo[Drive].DiakCommand(DISK_CLOSE, &Pa);
DiskInfo[Drive].Drive = EMPTY_DRIVE; // 沒有分配
DiskInfo[Drive].FATType = 0xff; // 無效的文件系統
DiskInfo[Drive].SecPerClus = 0; // 每簇扇區數
DiskInfo[Drive].NumFATs = 0; // FAT表數
DiskInfo[Drive].SecPerDisk = 0xffffffff;// 邏輯驅動器包含扇區數
DiskInfo[Drive].BytsPerSec = 0; // 每扇區字節數
DiskInfo[Drive].RootDirTable = 0; // 根目錄開始扇區號(FAT32為開始簇號)
DiskInfo[Drive].RootSecCnt = 0; // 根目錄占用扇區數
DiskInfo[Drive].FATStartSec = 0; // FAT表開始扇區號
DiskInfo[Drive].FATSecCnt = 0; // 每個FAT占用扇區數
DiskInfo[Drive].DataStartSec = 0; // 數據區開始扇區號
DiskInfo[Drive].PathClusIndex = 0; // 當前目錄
DiskInfo[Drive].DiakCommand = NULL; // 驅動程序
}
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -