📄 fat.c
字号:
/*
+FHDR------------------------------------------------------------------
Copyright (c),
Tony Yang –51,AVR,ARM firmware developer
Contact:qq 292942278 e-mail:tony_yang123@sina.com.cn
Abstract:
$Id: fat.c,v 1.14 2007/05/11 03:00:55 design Exp $
-FHDR-------------------------------------------------------------------
*/
#include<stdio.h>
#include<include\types.h>
#include<Flash_Management\Flash_Management.h>
#include<include\FAT_cfg.h>
//Current Directory Entry
static struct Directory_Entry_ Directory_Entry;
//CORE of FAT filesystem
static struct core_ CORE;
//BPB
static struct partition_bpb BPB;
//Define FCBs for FileRead/Write
struct FileControlBlock FCB[MaximumFCB];
/*
===============================================================================
函数
字符串转换为大写
入口:*string:字符串首地址
出口:SUCC
===============================================================================
*/
static u8 UPCASE(u8* string)
{
while(*string)
{
if(*string >='a' && *string <= 'z')
{
*string -= 32;
}
string++;
}
return(SUCC);
}
/*
===============================================================================
函数
测试字符串长度
入口:*string:字符串首地址
出口:字符串长度
===============================================================================
*/
static u16 LengthofString(u8 * string)
{
u16 i;
i = 0;
while(*string)
{
i++;
string++;
}
return(i);
}
/*
===============================================================================
函数
连接字符串2到字符串1之后,连接后字符串2无变化
入口:*string1:字符串1首地址,*string2:字符串2首地址
出口:SUCC,FAIL
===============================================================================
*/
static u8 concanenateString(u8 *string1,u8 *string2)
{
u8 len,i;
len = LengthofString(string1);
i = 0;
while(string2[i])
{
string1[len] = string2[i];
len++;
i++;
}
string1[len] = 0;
return(SUCC);
}
/*
===============================================================================
函数
字符串copy
入口:*string1:源字符串首地址;*string2:目标字符串首地址
出口:SUCC
===============================================================================
*/
static u8 stringcpy(u8 *string1,u8 *string2)
{
while(*string1)
{
*string2 = *string1;
string1++;
string2++;
}
*string2 = 0;
return(SUCC);
}
/*
===============================================================================
函数
字符串比较(不区分大小写)
入口:*string1:字符串1首地址;*string2:字符串2首地址
出口:SUCC,FAIL
===============================================================================
*/
static u8 stringcmp(u8 *string1,u8 *string2)
{
UPCASE(string1);
UPCASE(string2);
while((*string1) && (*string2))
{
if((*string1) == (*string2))
{
string1++;
string2++;
}
else
return(FAIL);
}
if( ((*string1) == 0) && ((*string2) == 0))
{
return(SUCC);
}
else
return(FAIL);
}
/*
===============================================================================
函数
在簇链里找当前簇的下一簇
入口:Cluster:当前簇号
出口: 返回下一簇号
===============================================================================
*/
static u32 Get_Next_Cluster_From_Current_Cluster(u32 Cluster)
{
u8 buf[512];
u32 ThisFATSecNum,ThisFATEntOffset;
//FAT16
ThisFATEntOffset = Cluster * 2;
ThisFATSecNum = CORE.relative_sector + BPB.reserved_sector
+ (ThisFATEntOffset / BPB.bytes_per_sector);
ThisFATEntOffset = ThisFATEntOffset % BPB.bytes_per_sector;
read_flash_sector(buf,ThisFATSecNum);
return((u32)buf[ThisFATEntOffset] + ((u32)buf[ThisFATEntOffset + 1]) * 256);
}
/*
===============================================================================
函数
在簇链里找当前簇之前的簇号
入口:Cluster:当前簇号
出口: 返回当前簇之前的簇号
===============================================================================
*/
static u32 Get_Previous_Cluster_From_Current_Cluster(u32 Cluster)
{
u8 buf[512];
u32 CUR_FATSecNum,CUR_FATEntOffset;
u32 CUR_Checking_Cluster_No;
CUR_Checking_Cluster_No = 0;
CUR_FATEntOffset = 0;
CUR_FATSecNum = CORE.FirstSectorofFAT1;
read_flash_sector(buf,CUR_FATSecNum);
do{
if( CUR_Checking_Cluster_No == (CORE.CountofClusters + 2))
{
return(FAIL);
}
if( (u16)(buf[CUR_FATEntOffset] + buf[CUR_FATEntOffset + 1] * 256) == (u16)Cluster)
return(CUR_Checking_Cluster_No);
CUR_Checking_Cluster_No++;
CUR_FATEntOffset += 2;
if(CUR_FATEntOffset >= 512)
{
CUR_FATSecNum++;
read_flash_sector(buf,CUR_FATSecNum);
CUR_FATEntOffset = 0;
}
}while(1);
}
/*
===============================================================================
函数
删除整个簇链,返回文件系统分配使用
入口:Cluster:首簇号
出口: SUCC,FAIL
===============================================================================
*/
static u8 FreeClusterChain(u32 Cluster)
{
u8 buf[512],i;
u32 ThisFAT1SecNum,ThisFATEntOffset,ThisFAT2SecNum;
do{
ThisFATEntOffset = Cluster * 2;
ThisFAT1SecNum = CORE.relative_sector + BPB.reserved_sector
+ (ThisFATEntOffset / BPB.bytes_per_sector);
ThisFAT2SecNum = ThisFAT1SecNum + BPB.sectors_per_FAT;
ThisFATEntOffset = (ThisFATEntOffset) % BPB.bytes_per_sector;
read_flash_sector(buf,ThisFAT1SecNum);
Cluster = (u32)buf[ThisFATEntOffset]+ (u32)buf[ThisFATEntOffset + 1] * 256;
buf[ThisFATEntOffset] = 0x0; //free Cluster
buf[ThisFATEntOffset + 1] = 0x0;
write_flash_sector(buf,ThisFAT1SecNum);
for(i = 1;i < BPB.numbers_of_FAT;i++)
{
write_flash_sector(buf,ThisFAT2SecNum);
ThisFAT2SecNum = ThisFAT2SecNum + BPB.sectors_per_FAT;
}
if(Cluster >= 0xfff6)
return(SUCC);
}while(1);
}
/*
===============================================================================
函数
Given any valid data cluster number N,
Return the sector number of the first sector of that cluster
入口:u32 N:data cluster number N
出口: RETURN first sector of that cluster
===============================================================================
*/
static u32 FirstSectorofCluster(u32 N)
{
return((N - 2) * BPB.sector_per_cluster + CORE.FirstDataSector);
}
/*
===============================================================================
函数
从FAT中分配一个空簇加到簇链当前簇之后
入口:Cluster:当前簇号
出口: 加入的簇号
===============================================================================
*/
u8 Allocate_EMPTY_CLUSTER_TO_CUR_CLUSTER_CHAIN(u32 Cluster,u32 *Added_Cluster,u8 *buf)
{
u32 temp,EMPTY_CLUSTER,ThisFAT1SecNum,ThisFATEntOffset,ThisFAT2SecNum;
u16 i;
EMPTY_CLUSTER = 0;
ThisFAT1SecNum = CORE.relative_sector + BPB.reserved_sector;
ThisFAT2SecNum = ThisFAT1SecNum + BPB.sectors_per_FAT;
do{
ThisFATEntOffset = 0;
read_flash_sector(buf,ThisFAT1SecNum);
for(i = 0;i < 256;i++)
{
if(buf[ThisFATEntOffset] == 0 && buf[ThisFATEntOffset + 1] == 0)
{
////////printf("Cluster %d EMPTY_CLUSTER %d",Cluster,EMPTY_CLUSTER);
temp = Get_Next_Cluster_From_Current_Cluster(Cluster);
buf[ThisFATEntOffset] = (u8)(temp & 0xff); //SET to Allocated Cluster
buf[ThisFATEntOffset + 1] = (u8)((temp >> 8) & 0xff);
write_flash_sector(buf,ThisFAT1SecNum);
//scanf("%c",&a);
temp = ThisFAT2SecNum;
for(i = 1;i < BPB.numbers_of_FAT;i++) //update backup FAT2,etc..
{
write_flash_sector(buf,temp);
temp += BPB.sectors_per_FAT;
}
temp = Get_Next_Cluster_From_Current_Cluster(Cluster);
////////printf("Temp %ld",temp);//scanf("%c",&a);
ThisFATEntOffset = Cluster * 2;
ThisFAT1SecNum = CORE.relative_sector + BPB.reserved_sector
+ (ThisFATEntOffset / BPB.bytes_per_sector);
ThisFATEntOffset = ThisFATEntOffset % BPB.bytes_per_sector;
ThisFAT2SecNum = ThisFAT1SecNum + BPB.sectors_per_FAT;
read_flash_sector(buf,ThisFAT1SecNum);
buf[ThisFATEntOffset] = (u8)(EMPTY_CLUSTER & 0xff);//Add to cluster chain
buf[ThisFATEntOffset + 1] = (u8)((EMPTY_CLUSTER >> 8) & 0xff);
write_flash_sector(buf,ThisFAT1SecNum);
temp = ThisFAT2SecNum;
for(i = 1;i < BPB.numbers_of_FAT;i++) //update backup FAT2,etc..
{
read_flash_sector(buf,temp);
buf[ThisFATEntOffset] = (u8)(EMPTY_CLUSTER & 0xff);//Add to cluster chain
buf[ThisFATEntOffset + 1] = (u8)((EMPTY_CLUSTER >> 8) & 0xff);
write_flash_sector(buf,temp);
temp += BPB.sectors_per_FAT;
} ////////printf("ThisFAT2SecNum %d EMPTY_CLUSTER %d",ThisFAT2SecNum,EMPTY_CLUSTER);//scanf("%c",&a);
//将簇中数据清空
for(i = 0;i< 512;i++)
buf[i] = 0;
ThisFAT1SecNum = FirstSectorofCluster(EMPTY_CLUSTER);
for(i = 0;i < BPB.sector_per_cluster;i++)
write_flash_sector(buf,ThisFAT1SecNum + i);
*Added_Cluster = EMPTY_CLUSTER;
return(SUCC);
}
else
{
ThisFATEntOffset += 2;
EMPTY_CLUSTER ++;
if( EMPTY_CLUSTER == (CORE.CountofClusters + 2))
{
return(FAIL);
}
}
}
ThisFAT1SecNum ++;
ThisFAT2SecNum ++;
}while(1);
}
/*
===============================================================================
函数
从FAT中分配一个空簇
入口:cluster--成功分配的簇号
出口: SUCC,FAIL
===============================================================================
*/
u8 Allocate_An_Empty_cluster(u32 * cluster,u8 * buf)
{
u32 temp,EMPTY_CLUSTER,ThisFAT1SecNum,ThisFATEntOffset,ThisFAT2SecNum;
u16 i;
EMPTY_CLUSTER = 0;
ThisFAT1SecNum = CORE.relative_sector + BPB.reserved_sector;
ThisFAT2SecNum = ThisFAT1SecNum + BPB.sectors_per_FAT;
do{
ThisFATEntOffset = 0;
read_flash_sector(buf,ThisFAT1SecNum);
for(i = 0;i < 256;i++)
{
if(buf[ThisFATEntOffset] == 0 && buf[ThisFATEntOffset + 1] == 0)
{
buf[ThisFATEntOffset] = 0xff; //SET to Allocated Cluster
buf[ThisFATEntOffset + 1] = 0xff;
write_flash_sector(buf,ThisFAT1SecNum);
temp = ThisFAT2SecNum;
for(i = 1;i < BPB.numbers_of_FAT;i++) //update backup FAT2,etc..
{
write_flash_sector(buf,temp);
temp += BPB.sectors_per_FAT;
}
//将簇中数据清空
for(i = 0;i< 512;i++)
buf[i] = 0;
ThisFAT1SecNum = FirstSectorofCluster(EMPTY_CLUSTER);
for(i = 0; i < BPB.sector_per_cluster;i++)
write_flash_sector(buf,ThisFAT1SecNum + i);
*cluster = EMPTY_CLUSTER;
return(SUCC);
}
else
{
ThisFATEntOffset += 2;
EMPTY_CLUSTER ++;
if( EMPTY_CLUSTER == (CORE.CountofClusters + 2))
{
return(FAIL);
}
}
}
ThisFAT1SecNum ++;
ThisFAT2SecNum ++;
}while(1);
}
/*
===============================================================================
函数(CORE_INIT_1)
根据boot sector分区表计算得出分区partition_ID的relative_sector,total_sector等
入口:partition_ID(支持4个分区0,1,2,3)
出口: 无
===============================================================================
*/
static void BPB_INIT_1(u8 partition_ID,u8 *buf)
{
//read_flash_sector(buf,0); //read MBR
CORE.relative_sector = 0;
//(u16)buf[0x1c6 + (u16)partition_ID * 16] +
//(u16)buf[0x1c7 + (u16)partition_ID * 16] * 256;
//+ (u8)sector_buf[0x1c8+ partition_ID * 16] << 16 +
// (u8)sector_buf[0x1c9+ partition_ID * 16] << 24;
CORE.total_sector = *((u32*)( buf+32));
//(u16)buf[0x1ca + (u16)partition_ID * 16] +
//(u16)buf[0x1cb + (u16)partition_ID * 16] * 256 ;
//+ (u8)sector_buf[0x1cc
//+ partition_ID * 16] << 16 +(u8)sector_buf[0x1cd+ partition_ID * 16] << 24;
CORE.system_id = buf[0x1c2]; //Partition Type 0C-FAT32,06-FAT16 ect..
CORE.PartitionID= 'C' + partition_ID; //从C开始到Z结束
}
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -