📄 fat.c
字号:
/************************************************************/
/* FAT Code for M32L */
/* By pasyong */
/* 2006-4 */
/* Base ICC6.31A */
/************************************************************/
#include <iom8v.h>
#include <macros.h>
#include <string.h>
#include "DEFINE.H"
#include "mmc.h"
#include "fat.h"
#include "UART.H"
#include "DELAY.H"
extern uint08 BUFFER[512];
unsigned char LONGNAME_BUFFER_ADDR[30];
unsigned char DIRNAME_BUFFER_ADDR[30];
unsigned char *LongNameBuffer = (unsigned char *) LONGNAME_BUFFER_ADDR;
unsigned char *DirNameBuffer = (unsigned char *) DIRNAME_BUFFER_ADDR;
struct partrecord PartInfo;
unsigned char Fat32Enabled;
unsigned long FirstDataSector;
unsigned int BytesPerSector;
unsigned int SectorsPerCluster;
unsigned long FirstFATSector;
unsigned long FirstDirSector;
unsigned long FileSize;
unsigned long FatInCache = 0;
//********************************************************************************************
//读一个扇区
//void ReadBlock(unsigned long LBA)
//********************************************************************************************
/*{
unsigned long temp;
temp=LBA<<9;
SD_Read_Block(temp);
}*/
/*-----------------------------------------------------------------------
查询数据区一个簇开始扇区号
-----------------------------------------------------------------------*/
unsigned long fatClustToSect(unsigned long clust)
{
return ((clust-2) * SectorsPerCluster) + FirstDataSector;
}
/*-----------------------------------------------------------------------
查询一个簇所占扇区数
-----------------------------------------------------------------------*/
unsigned int fatClusterSize(void)
{
// return the number of sectors in a disk cluster
return SectorsPerCluster;
}
/*-----------------------------------------------------------------------
查询SD卡文件系统信息
-----------------------------------------------------------------------*/
unsigned char fatInit(void)
{
uint16 data;uint08 t1,t2;
struct bpb710 *bpb;
uint08 i;
uint16 temp;
// 读MBR结构
//ReadBlock(0);
MMC_get_data_LBA(0,512,BUFFER);
// 读取分区表信息
PartInfo = *((struct partrecord *) ((struct partsector *)BUFFER)->psPart);
// 读引导扇区
// 引导扇区号在PartInfo.prStartLBA中
//ReadBlock(PartInfo.prStartLBA); //ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer );
MMC_get_data_LBA(PartInfo.prStartLBA,512,BUFFER);
bpb = (struct bpb710 *) ((struct bootsector710 *) BUFFER)->bsBPB;
FirstDataSector = PartInfo.prStartLBA;
if(bpb->bpbFATsecs)
{
// bpbFATsecs非0,为FAT16,FAT表所占的扇区数在bpbFATsecs里
FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;
}
else
{
// bpbFATsecs是0,为FAT32,FAT表所占的扇区数在bpbBigFATsecs里
FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
}
SectorsPerCluster = bpb->bpbSecPerClust;
BytesPerSector = bpb->bpbBytesPerSec;
FirstFATSector = bpb->bpbResSectors + PartInfo.prStartLBA;
//查询SD卡文件系统分区类型
switch (PartInfo.prPartType)
{
case PART_TYPE_DOSFAT16:
case PART_TYPE_FAT16:
case PART_TYPE_FAT16LBA:
// 第一个目录扇区号为2
FirstDirSector = CLUST_FIRST;
//FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;
Fat32Enabled = 0;
break;
case PART_TYPE_FAT32LBA:
case PART_TYPE_FAT32:
FirstDirSector = bpb->bpbRootClust;
Fat32Enabled = 1;
break;
default:break;
//return 1;
}
//put_char(PartInfo.prPartType);
//put_char((bpb->bpbBytesPerSec)>>8);
//put_char(bpb->bpbSecPerClust);
//查询SD卡文件系统信息
switch (PartInfo.prPartType)
{
case PART_TYPE_DOSFAT16:
put_chars("DOSFAT 16");
//LCD_write_english_string(0,0,"DOSFAT 16");
break;
case PART_TYPE_FAT16:
put_chars("FAT16");
//LCD_write_english_string(0,0,"FAT16 ");
break;
case PART_TYPE_FAT16LBA:
put_chars("FAT16 LBA");
//LCD_write_english_string(0,0,"FAT16 LBA");
break;
case PART_TYPE_FAT32LBA:
put_chars("FAT32 LBA");
//LCD_write_english_string(0,0,"FAT32 LBA");
break;
case PART_TYPE_FAT32:
put_chars("FAT32");
//LCD_write_english_string(0,0,"FAT32");
break;
default:
put_chars("NO Parttion");
//LCD_write_english_string(0,0,"No Partition!");
break;
}
//显示磁盘容量
data=PartInfo.prSize>>11; //单位是MB
put_chars(" Totel ");
temp=data/1000;
if(temp)
put_char(temp+0x30);
temp=data/100%10;
put_char(temp+0x30);
temp=data/10%10;
put_char(temp+0x30);
temp=data%10;
put_char(temp+0x30);
put_chars(" MB");
return 0;
}
/*-----------------------------------------------------------------------
查询一个文件的开始簇
-----------------------------------------------------------------------*/
unsigned int baseentry = 0;
unsigned int entrycount = 0;
unsigned long fatGetDirEntry(unsigned int entry)
{
unsigned long sector;
struct direntry *de = 0; // 防止compiler warning
struct winentry *we;
unsigned int hasBuffer;
unsigned int b;
int i,index;
char *p;
entrycount = 0;
DirNameBuffer = 0;
// 读取目录区数据
sector = fatClustToSect(FirstDirSector);
/*put_char(0x55);
put_char(0xAA);
put_char(sector>>24);
put_char(sector>>16);
put_char(sector>>8);
put_char(sector);
*/
hasBuffer = 0;
index = 16; //一个扇区包含16个目录
do
{
if(index == 16) // 是否该一人一扇区time for next sector ?
{
//ReadBlock(sector++);
MMC_get_data_LBA(sector++,512,BUFFER);
de = (struct direntry *)BUFFER;
index = 0;
}
if(*de->deName != 0xE5) //此目录不为空
{
// 如果if not a deleted entry
if(de->deAttributes == ATTR_LONG_FILENAME) //如果是长文件名
{
// we have a long name entry
we = (struct winentry *) de;
b = 13 *( (we->weCnt-1) & 0x0f); // index into string
p = &LongNameBuffer[b];
for (i=0;i<5;i++) *p++ = we->wePart1[i*2]; // copy first part
for (i=0;i<6;i++) *p++ = we->wePart2[i*2]; // second part
for (i=0;i<2;i++) *p++ = we->wePart3[i*2]; // and third part
if (we->weCnt & 0x40) *p = 0; // in case dirnamelength is multiple of 13
if ((we->weCnt & 0x0f) == 1) hasBuffer = 1; // mark that we have a long entry
}
else
{
// we have a short name entry
// check if this is the end of a multi-part long name entry
if(hasBuffer)
{
// a long entry name has been collected
// is it a directory ?
if(de->deAttributes == ATTR_DIRECTORY) //目录
{
unsigned long save = FirstDirSector;
unsigned int save2 = baseentry;
unsigned long rval;
strcpy(DirNameBuffer,LongNameBuffer);
strcat(DirNameBuffer,"/");
// rprintfStr(LongNameBuffer); rprintfProgStrM("/"); //EOL();
// call recursively
FirstDirSector = ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
rval = fatGetDirEntry(entry);
FirstDirSector = save;
baseentry = save2;
if (rval)
return rval;
else
{
// reload original sector
//ReadBlock(sector-1);//ataReadSectors( DRIVE0, sector-1, 1, SectorBuffer);
MMC_get_data_LBA((sector-1),512,BUFFER);
entrycount--; // decrement entry counter
*DirNameBuffer = 0;
}
}
else // normal file entry正常的文件
if(entrycount == entry) //跳出
break;
hasBuffer = 0; // clear buffer
entrycount++; // increment entry counter
}
// else ignore short_name_only entries
}
}
de++;
index++;
}while (*de->deName || index == 16); // 0 in de->deName[0] if no more entries
if (hasBuffer == 0) // end of entries
return 0;
FileSize = de->deFileSize;
return (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
}
/*-----------------------------------------------------------------------
在FAT表中查询下一个簇所在扇区号
-----------------------------------------------------------------------*/
unsigned long fatNextCluster(unsigned long cluster)
{
unsigned long nextCluster;
unsigned long fatMask;
unsigned long fatOffset;
unsigned long sector;
unsigned int offset;
if(Fat32Enabled) //表示FAT32格式
{
// 一个表项为4bytes(32 bits)
fatOffset = cluster << 2;
// 设置 FAT32 bit mask
fatMask = FAT32_MASK;
}
else //表示FAT16
{
// 一个表项为2bytes(16 bits)
fatOffset = cluster << 1;
// 设置 FAT16 bit mask
fatMask = FAT16_MASK;
}
//计算FAT扇区号
sector = FirstFATSector + (fatOffset / BytesPerSector);
//计算FAT扇区号中表项的偏移地址
offset = fatOffset % BytesPerSector;
//ReadBlock(sector);
MMC_get_data_LBA(sector,512,BUFFER);
// 读取下一个簇号
nextCluster = (*((unsigned long*) &((char*)BUFFER)[offset])) & fatMask;
// 是否文件的结束簇
if (nextCluster == (CLUST_EOFE & fatMask))
nextCluster = 0;
return nextCluster;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -