⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsys.c

📁 USB驱动程序,和NANDflash的驱动, 包括文件系统,cpu是arm
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
#include "..\inc\option.h"
#include "..\inc\Hal.h"
unsigned int m_Offset;
struct _BPB Bpb;
struct _FatGet fat_get;
INT32 RootDirSectors;	
INT32 FirstDataSector;
INT32 FirstFatSecNum;
INT32 FirstRootDirSecNum;
struct _FILE handles;
WORD FatCache[512*256];
volatile SYS_INFO_BLOCK DeviceInfo;
#define GETINT16(p) (*(INT8*)p+0x100*(*(INT8*)(p+1)))
#define GETINT32(p) (*(INT8*)p+0x100*(*(INT8*)(p+1))+0x10000*(*(INT8*)(p+2))+0x1000000*(*(INT8*)(p+3)))

#define getyear(p) (p&0x0FE00)>>9
#define getmonth(p) (p&0x01e0)>>5
#define getday(p) (p&0x1F)
#define gethour(p) (p&0x0F800)>>11
#define getminitor(p) (p&0x07e0)>>5
#define getsecond(p) (p&0x1F)


void unformat_name(char * filename, const unsigned char dirname[11])
{
	int i;
	int j;

	memset(filename, 0, 13);

	for(i=0; i<8; i++)
	{
		if(dirname[i] != 0x20)
			filename[i] = dirname[i];
		else
			break;
	}
	
	if(dirname[8] != 0x20)
	{
		filename[i] = '.';
		j = i + 1;
		
		for(i=8; i<11; i++,j++)
		{
			if(dirname[i] != 0x20)
				filename[j] = dirname[i];
			else
				break;
		}
	}
}
unsigned char SectorGet(INT32 Sector, struct _FatGet *fat_get)
{
	BYTE Cache[512];
	struct _DIR *dir;
	unsigned int j;
	if(RBC_Read(Sector,1,(unsigned char *)Cache)==FALSE)return FALSE;
	dir = (struct _DIR *)Cache;
	dir += fat_get->DirIndex;

	for(j=fat_get->DirIndex;(dir->Name[0] != '\0') && (j< Bpb.BytsPerSec / sizeof(struct _DIR)); j++)//Bpb.BytsPerSec / sizeof(struct _DIR)
	{
		if(dir->Name[0] != 0xE5 && (!(dir->Attr & ATTR_VOLUME_ID)))// not volumn id or long name entry.
		{
			fat_get->DirSectorNum = Sector;
			fat_get->DirIndex = j + 1;
			unformat_name(fat_get->filename, dir->Name);

			return 0;
		}
		dir++;
	}
	fat_get->DirIndex=0;
	return TRUE;
}
unsigned char  get_valid_format(const char *fullpath,char static_path[256])
{
	char* p=static_path;
	char path[256];
	char* ppath = path;
	int dir_len_count; //count dir len.
	int i;

	if(fullpath == NULL || strlen(fullpath) >12)
		return FALSE;
	dir_len_count=0;
	strcpy(path, fullpath);
	for(i=0;(*ppath!=NULL&&i<12);i++)
	{
		if(	*ppath > 96 && *ppath < 123)
		{
			*ppath -= 32;
		}
		ppath++;
	}
	memset(p, 0, 256);
	ppath = path;

	for(;;)
	{
		switch(*ppath)
		{
		case 0:
			if(dir_len_count>=11)	return TRUE;
			else 
			{
				dir_len_count ++;
				*p = 0x20;
				p++;
			}
			continue;
		case '.':
			{
				if(dir_len_count > 8 || dir_len_count ==0) 
					return FALSE;
				if(ppath[1] == '.')
					return FALSE;
//				if(dir_len_count > 8)
//				{
//					*p = *ppath;
//					p++;
//				}
//				else
//				{	
					for(i=0; i<(8 - dir_len_count); i++)
					{
						*p = 0x20;
						p++;
					}
//				}

				dir_len_count =8;
				ppath++;
				continue;
			}
			break;

		case 0x22:
		case 0x2A:
		case 0x2B:
		case 0x2C:
		case 0x2F:
		case 0x3A:
		case 0x3B:
		case 0x3C:
		case 0x3D:
		case 0x3E:
		case 0x3F:
		case 0x5B:
		case 0x5D:
		case 0x7C:
			return FALSE;

		default:
			{
				if(*ppath < 0x20)
					return FALSE;		
			}
			break;
		}
		*p = *ppath;
		dir_len_count ++;

		if(dir_len_count >= 11)
			return TRUE;
		p++;
		ppath++;
	}
}
WORD SectorNum2ClusterNum(INT32 SectorNum)
{
	if(SectorNum < FirstDataSector)
		return 0;
	else
		return (WORD)((SectorNum - FirstDataSector) / Bpb.SecPerClus + 2);
}
INT32 ClusterNum2SectorNum(WORD ClusterNum)
{
	return FirstDataSector + (ClusterNum - 2) * Bpb.SecPerClus;
}
INT32 SectorSearch(INT32 Sector, const char dirname[256], struct _FILE *file)
{
	BYTE Cache[512];
	BYTE filename[256];
	struct _DIR *dir;
	unsigned int j;
	struct _FatGet fat_get;

	if(RBC_Read(Sector,1,(unsigned char *)Cache)==FALSE)return 0xffffffff;

	dir = (struct _DIR *)Cache;
	for(j=0; (dir->Name[0] != '\0') && (j< Bpb.BytsPerSec / sizeof(struct _DIR)); j++)
	{
		if(dir->Name[0] !=0xE5 && (!(dir->Attr & ATTR_VOLUME_ID)))// not volumn id or long name entry.
		{
			if(strlen(dirname)>11)
			{
				fat_get.DirSectorNum=Sector;
				fat_get.DirIndex=j+1;
				if(fat_get.DirIndex!=1||fat_get.DirSectorNum!=FirstRootDirSecNum)
				{
					if(GetLongFileName(&fat_get,filename))
					{
						if(memcmp(filename, dirname, strlen(dirname)) == 0 && (!(dir->Attr & ATTR_VOLUME_ID)))// not volumn id or long name entry.
						{
							if(file != NULL)
							{
								memset(file, 0, sizeof(struct _FILE));
								file->DirSectorNum = Sector;
								file->DirIndex = j;
								memcpy(&file->dir, dir, sizeof(struct _DIR));
							}
							return ClusterNum2SectorNum(dir->FstClusLO);
						}	
					}
				}
			}
			else
			{
				if(memcmp((const char*)dir->Name, dirname, 11) == 0 && (!(dir->Attr & ATTR_VOLUME_ID)))// not volumn id or long name entry.
				{
					if(file != NULL)
					{
						memset(file, 0, sizeof(struct _FILE));
						file->DirSectorNum = Sector;
						file->DirIndex = j;
						memcpy(&file->dir, dir, sizeof(struct _DIR));
					}
			
					return ClusterNum2SectorNum(dir->FstClusLO);
				}
			}
		}
		dir++;
	}

	return 0xffffffff;
}
INT32 Search(INT32 Sector, const char dirname[256], struct _FILE *file)
{	
	unsigned int i;
	WORD Cluster;
	INT32 FirstSectorOfFile;

	for(i=0; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
	{
		FirstSectorOfFile = SectorSearch(Sector++, dirname, file);
		if(FirstSectorOfFile != 0xffffffff)
			return FirstSectorOfFile;
	}
	return 0xffffffff;
}
unsigned int Locate(const char *filename, struct _FILE *file)
{
	INT32 Sector = FirstRootDirSecNum;
	static char static_path[256];
	char *p=static_path;
	if(strlen(filename)<13)
	{
		if(FALSE == get_valid_format(filename,p))
			return FALSE;
	}
	else
		strcpy(p,filename);
	Sector = Search(Sector, p, file);
//	if(*(p+11) == NULL)
		return Sector;
//	return 0xFFFFFFFF;
}
int GetLongFileName(struct _FatGet *fat_get, char *filename)
{
	WORD TmpLen=0;
	unsigned int Sector;
	BYTE Cache[512];
	struct _DIR *dir;
	BYTE *Lfn;
	int i;
	if(fat_get->DirIndex>=2)Sector=fat_get->DirSectorNum;
	else	Sector=fat_get->DirSectorNum-1;
	if(RBC_Read(Sector,1,Cache)==FALSE)
		if(RBC_Read(Sector,1,Cache)==FALSE)
			return FALSE;
	Lfn = (BYTE *) Cache + 0x20 * (fat_get->DirIndex-1);
	dir=(struct _DIR *)((char *) Cache + 0x20 * (fat_get->DirIndex-2));

	if((dir->Attr & 0xF) != 0xF)
		return TmpLen;
	do{
		Lfn -= 32;
		for(i=0; i<31; i++){
			if((i==10) | (i==11) | (i==12) | (i==25) | (i==26))
				continue;
			filename[TmpLen++] = Lfn[i+1];
			if(Lfn[i+1]==0)
				break;
			i++;			//Skip past the Unicode Hi byte
		}
		if(Lfn<Cache)
		{
			if(RBC_Read(Sector,1,Cache)==FALSE)
				if(RBC_Read(Sector,1,Cache)==FALSE)
					return FALSE;
			Lfn = Cache+512-32;
		}
	}while(!(Lfn[0] & 0x40));
	filename[TmpLen]=0;
	return TmpLen;
}
unsigned char GetFirstFile(char* filename)
{
	INT32 Sector;
	unsigned int i;
	WORD Cluster;

	Sector = FirstRootDirSecNum;
	fat_get.DirIndex = 0;

	for(i=0; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
	{
		if(SectorGet(Sector++, &fat_get) == 0)
		{
			if(fat_get.DirIndex!=1||fat_get.DirSectorNum!=FirstRootDirSecNum)
			{
				if(GetLongFileName(&fat_get,filename)!=0)
					return TRUE;
			}
			strcpy(filename, fat_get.filename);
			return TRUE;
		}
	}
	return FALSE;
}

unsigned char GetnextFile(char* filename)
{
	INT32 Sector;
	unsigned int i;
	WORD Cluster;
	Sector = fat_get.DirSectorNum;
	i=(Sector - FirstRootDirSecNum) * Bpb.BytsPerSec / sizeof(struct _DIR) + fat_get.DirIndex +1;
	for(; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
	{
		if(SectorGet(Sector++, &fat_get) == 0)
		{
			if(fat_get.DirIndex!=1||fat_get.DirSectorNum!=FirstRootDirSecNum)
			{
				if(GetLongFileName(&fat_get,filename)!=0)
					return TRUE;
			}
			strcpy(filename, fat_get.filename);
			return TRUE;
		}
	}
	return FALSE;
}

unsigned char GetFileStat( const char *filename, struct _STAT* stat)
{
	INT32 SectorNum;
	struct _FILE file;

	SectorNum = Locate(filename, &file);
	if(SectorNum == 0xffffffff)
		return FALSE;

	stat->Attr = file.dir.Attr;
	stat->CrtDate = file.dir.CrtDate;
	stat->CrtTime = file.dir.CrtTime;
	stat->CrtTimeTenth = file.dir.CrtTimeTenth;
	stat->FileSize = file.dir.FileSize;
	stat->LstAccDate = file.dir.LstAccDate;
	stat->WrtDate = file.dir.WrtDate;
	stat->WrtTime = file.dir.WrtTime;

	return TRUE;
}

unsigned char fat_open(const char* filename)
{
	INT32 FirstSectorNum;

	if(handles.valid==TRUE) return FALSE;

	FirstSectorNum = Locate(filename, &handles);
	if(FirstSectorNum == 0xffffffff)
		return FALSE;

	handles.StartSectorNum = FirstSectorNum;
	handles.CurrentSectorNum = handles.StartSectorNum;
	handles.SectorOffset = 0;
	handles.offset = 0;
	handles.valid = 1;
	return TRUE;
}
unsigned char fat_close()
{
	BYTE Cache[512];
	struct _DIR *dir;
	if(RBC_Read(handles.DirSectorNum,1,Cache)==FALSE)
		if(RBC_Read(handles.DirSectorNum,1,Cache)==FALSE)
		return FALSE;
	dir = (struct _DIR *)Cache;
	dir += handles.DirIndex;
	memcpy(dir, &handles.dir, sizeof(struct _DIR));
	if(!RBC_Write(handles.DirSectorNum,1,Cache,TRUE))
		if(!RBC_Write(handles.DirSectorNum,1,Cache,TRUE))
			return FALSE;
	handles.valid = 0;
	return TRUE;
}
WORD GetNextClusterNum(WORD ClusterNum)
{
	return FatCache[ClusterNum];
}
unsigned int fat_read(void* buffer, unsigned int bytes)
{
	BYTE Cache[512],*pCache;
	unsigned int read_bytes =0;
	unsigned int max_copy_bytes_in_sector;
	WORD Cluster;
	int i;
	

	bytes = (handles.dir.FileSize - handles.offset) > bytes ? bytes : (handles.dir.FileSize - handles.offset);

	Cluster = SectorNum2ClusterNum(handles.CurrentSectorNum);

	i = (handles.CurrentSectorNum - FirstDataSector) % Bpb.SecPerClus;

	if(i != 0)
	{
		for(; i< Bpb.SecPerClus; i++)
		{
			if(RBC_Read(handles.CurrentSectorNum,1,(unsigned char *)Cache)==FALSE)return 0;
			pCache=Cache;
			pCache += handles.SectorOffset;
			max_copy_bytes_in_sector = (Bpb.BytsPerSec - handles.SectorOffset) > (bytes - read_bytes) ? (bytes - read_bytes) : (Bpb.BytsPerSec - handles.SectorOffset);
			memcpy(buffer, pCache, max_copy_bytes_in_sector);

			read_bytes += max_copy_bytes_in_sector;
			handles.SectorOffset += max_copy_bytes_in_sector;
			handles.offset += max_copy_bytes_in_sector;
			buffer = (char*)buffer + max_copy_bytes_in_sector;

			if(handles.SectorOffset == Bpb.BytsPerSec)
			{
				if(i == Bpb.SecPerClus -1)
				{
					Cluster = GetNextClusterNum(Cluster);
					if(Cluster != 0xffff)
						handles.CurrentSectorNum = ClusterNum2SectorNum(Cluster);
				}
				else
					handles.CurrentSectorNum ++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -