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

📄 usbfat16.c

📁 ARM主USB程序
💻 C
📖 第 1 页 / 共 4 页
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//定位文件,即在根目录区查找到它的第一级目录,在下一个簇查找到它的第二级目录……,直到最终定位文件。
// return the first sector number of dir/file content.
// 0xffffffff indicate failed.
// if path is root dir, file arg is ignore.


DWORD fat_locate(const char *path, _FILE *file)
{
	DWORD Sector = FirstDirSector;
	char *p;

	p = get_valid_format(path);//判断是否合法
	if(p == NULL)
		return 0xffffffff;

	// locate first sub dir.
	p++;//忽略第一个‘\’

	// locate next sub dir(s).
	for(;;)
	{
		if(*p == NULL)
			return Sector;
		Sector = fat_search(Sector, p, file);//在根目录区寻找是否有与P同名的目录/文件项
		if(Sector == 0xffffffff)
			return 0xffffffff;

		p+=12;
	}
	// we never go here.
	return 0xffffffff;
}




//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//获得当前的系统时间


void fat_datetime(FatDateTime *fatdatetime)
{
	int year,month,day,weekday,hour,min,sec;
	WORD pdate = fatdatetime->Date;
	WORD ptm = fatdatetime->Time;

	if(rBCDYEAR == 0x99) 
	    year = 0x1999;
	else 
	    year = 0x2000 + rBCDYEAR;
	    month=rBCDMON;
	    day=rBCDDAY;
	    weekday=rBCDDATE;
	    hour=rBCDHOUR;
	    min=rBCDMIN;
	    sec=rBCDSEC;

	pdate = ((day << DD_DAY_SHIFT)&DD_DAY_MASK)+((month <<DD_MONTH_SHIFT)&DD_MONTH_MASK)
	        +(((year-1980) <<DD_YEAR_SHIFT)&DD_YEAR_MASK);
	
	ptm = ((hour<<DT_HOURS_SHIFT)&DT_HOURS_MASK)+((min<<DT_MINUTES_SHIFT)&DT_MINUTES_MASK)
	      +(((sec/2)<<DT_2SECONDS_SHIFT)&DT_2SECONDS_MASK);
	
	fatdatetime->TimeTenth = (sec % 2) * 100; //+ systm.wMilliseconds / 10;
}




///////////////////////////////////////////////////////////////////////////////////////////////////////
// fat apis
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//创建目录
int usbfat_mkdir( const char *dirname)//仅1级目录: 父目录\新目录
{
	DIRENTRY dir;
	DWORD SectorNum;
	char path[512];
	char name[11];
	char *p;
	FatDateTime tm;
	_FILE file;	
	BYTE* Cache;
	DIRENTRY *pdir;
	WORD NewCluster;
	char dot[11] = {'.', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
	char dotdot[11] = {'.', '.', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};

	// is path format correct ?
	p = get_valid_format(dirname);
	if(p == NULL)
		return 1;

	//if exist this dir ?
	if(fat_locate(dirname, NULL) != 0xffffffff)
		return 4;

	//separate path into parent and name(directory name)
	strncpy(name, &p[strlen(p)-11], 11);//拷贝新的目录名->name
    //获得了文件的第一级目录(parent path)名称
	strcpy(path, dirname);
	p = strrchr(path, '\\');//返回path中‘\’第一次出现的指针
	if(p == path) // it is root dir.
		*(p+1) = '\0';
	else
		*p = '\0';
    
	//locate parent path
	SectorNum = fat_locate(path, NULL);//获取第一级目录指向第一个扇区的地址
	if(SectorNum == 0xffffffff)
		return 2;

	//fill dir attributes
	memset((BYTE *)&dir, 0, sizeof(dir));
	memcpy((BYTE *)(dir.deName), name, 11);
	dir.deAttributes = ATTR_DIRECTORY;//目录属性
	fat_datetime(&tm);
	dir.CrtDate = dir.LstAccDate = dir.WrtDate = tm.Date;
	dir.CrtTime = dir.WrtTime = tm.Time;
	dir.CrtTimeTenth = tm.TimeTenth;

	//alloc one dir在父目录所指的扇区下获得一个新的目录项
	if(AllocDir(SectorNum, &dir, &file) != 0)
		return 3;

	//alloc a cluster
	NewCluster = AllocCluster(0);
	if(NewCluster == 0xffff)
		return 4;

	//flush to disk
	Cache = GetSectorData(file.DirSectorNum);//将新的目录项所在扇区读入
	if(Cache == NULL)
		return 6;

	pdir = (DIRENTRY *)Cache;
	pdir += file.DirIndex;

	pdir->deStartCluster = NewCluster;//指向新的一簇
	Flush();

	//create . and .. dir items.
	Cache = GetSectorData(ClusterNum2SectorNum(NewCluster));//将新簇的第一个扇区读入
	if(Cache == NULL)
		return 6;

	pdir = (DIRENTRY *)Cache;//获得一个目录项本地目录:.?
	memset((BYTE *)pdir, 0, sizeof(DIRENTRY));
	memcpy((BYTE *)(pdir->deName), dot, 11);
	pdir->deAttributes = ATTR_DIRECTORY;
	fat_datetime(&tm);//获得当前系统的时间,填写当前目录项的属性
	pdir->CrtDate = pdir->LstAccDate = pdir->WrtDate = tm.Date;
	pdir->CrtTime = pdir->WrtTime = tm.Time;
	pdir->CrtTimeTenth = tm.TimeTenth;
	pdir->deStartCluster = NewCluster;//指向本地

	pdir++;//获得一个目录项父目录:..
	memset((BYTE *)pdir, 0, sizeof(DIRENTRY));
	memcpy((BYTE *)(pdir->deName), dotdot, 11);
	pdir->deAttributes = ATTR_DIRECTORY;
	fat_datetime(&tm);
	pdir->CrtDate = pdir->LstAccDate = pdir->WrtDate = tm.Date;
	pdir->CrtTime = pdir->WrtTime = tm.Time;
	pdir->CrtTimeTenth = tm.TimeTenth;
	pdir->deStartCluster = SectorNum2ClusterNum(SectorNum);

	Flush();

	return 0;
}




//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////


//删除目录
int usbfat_rmdir( const char *dirname)
{
	DWORD SectorNum;
	_FILE file;
	char filename[13];

	//is dir have no sub dir or file ?
	if(usbfat_getfirst(dirname, filename) == 0)
		return 3;

	//locate
	SectorNum = fat_locate(dirname, &file);
	if(SectorNum == 0xffffffff)
		return 4;

	// is it a dir ?
	if(!(file.dir.deAttributes & ATTR_DIRECTORY))
		return 6;

	if(DeleteDir(&file) != 0)
		return 5;

	FreeCluster(file.dir.deStartCluster);

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

FatGet fat_get;


//path所指目录下是否有子目录或文件,获得第一个子目录/文件名



int usbfat_getfirst(const char *path, char* filename)
{
	DWORD Sector;
	unsigned int i;
	WORD Cluster;

	//if exist this dir ?
	Sector = fat_locate(path, NULL);
	if(Sector == 0xffffffff)
		return 1;

	if(Sector ==FirstDirSector)
	{
		fat_get.IsRootDir = 1;
		fat_get.DirIndex = 2;

		for(i=0; i<RootDirCount * sizeof(DIRENTRY) / BytesPerSector; i++)
		{
			if(SectorGet(Sector++, &fat_get) == 0)
			{
				strcpy(filename, fat_get.filename);
				return 0;
			}
		}
	}

	else
	{
		fat_get.IsRootDir = 0;
		fat_get.DirIndex = 2;

		Cluster = SectorNum2ClusterNum(Sector);

		// because the sector is the first sector of parent dir,
		// so it is the first sector of cluster.
		/*
		i = (Sector - FirstDataSector) % Bpb.SecPerClus;
		
		if(i != 0)
		{
			for(; i< Bpb.SecPerClus; i++)
			{
				if(SectorGet(Sector++, &fat_get) == 0)
				{
					strcpy(filename, fat_get.filename);
					return 0;
				}
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}*/
		
		while(Cluster != 0xffff)
		{
			for(i=0; i< SectorsPerCluster; i++)
			{
				if(SectorGet(Sector++, &fat_get) == 0)
				{
					strcpy(filename, fat_get.filename);
					return 0;
				}
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}
	}

	return 2;
}



//////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////

int usbfat_getnext(char* filename)
{
	DWORD Sector;
	unsigned int i;
	WORD Cluster;

	Sector = fat_get.DirSectorNum;

	if(fat_get.IsRootDir)
	{
		i=(Sector - RootDirSectors) * BytesPerSector/ sizeof(DIRENTRY) + fat_get.DirIndex +1;

		for(; i<RootDirCount * sizeof(DIRENTRY) / BytesPerSector; i++)
		{
			if(SectorGet(Sector++, &fat_get) == 0)
			{
				strcpy(filename, fat_get.filename);
				return 0;
			}
		}
	}

	else
	{
		Cluster = SectorNum2ClusterNum(Sector);

		i = (Sector - FirstDataSector) % SectorsPerCluster;

		if(i != 0)
		{
			for(; i< SectorsPerCluster; i++)
			{
				if(SectorGet(Sector++, &fat_get) == 0)
				{
					strcpy(filename, fat_get.filename);
					return 0;
				}
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}

		while(Cluster != 0xffff)
		{
			for(i=0; i< SectorsPerCluster; i++)
			{
				if(SectorGet(Sector++, &fat_get) == 0)
				{
					strcpy(filename, fat_get.filename);
					return 0;
				}
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}
	}

	return 2;
}


/////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
_FILE handles[16];

int usbfat_close(int handle)
{
	_FILE *fp;
	FatDateTime tm;
	BYTE* Cache;
	DIRENTRY *dir;

	if(handle <0 || handle >= sizeof(handles)/sizeof(_FILE))
		return -1;

	fp = &handles[handle];

	fat_datetime(&tm);
	fp->dir.LstAccDate = fp->dir.WrtDate = tm.Date;
	fp->dir.WrtTime = tm.Time;

	Cache = GetSectorData(fp->DirSectorNum);
	if(Cache == NULL)
		return -2;

	dir = (DIRENTRY *)Cache;
	dir += fp->DirIndex;

	memcpy((BYTE *)dir, (BYTE *)&fp->dir, sizeof(DIRENTRY));
	Flush();
    usbFlushFAT();
	handles[handle].valid = 0;
	return 0;
}



////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////

int usbfat_creat(const char* filename, BYTE attribute)
{
	DIRENTRY dir;
	char path[512];
	char name[11];
	char *p;
	DWORD ParentDirSectorNum;
	FatDateTime tm;
	_FILE file;
	DIRENTRY *pdir;
	WORD NewCluster;
	BYTE* Cache;

	// is path format correct ?
	p = get_valid_format(filename);
	if(p == NULL)
		return -2;

	//if exist this file ?
	if(fat_locate(filename, NULL) != 0xffffffff)
		return -3;

	//separate path into parent and name
	strncpy(name, &p[strlen(p)-11], 11);

	strcpy(path, filename);
	p = strrchr(path, '\\');
	*p = '\0';

	//locate parent path
	ParentDirSectorNum = fat_locate(path, NULL);
	if(ParentDirSectorNum == 0xffffffff)
		return -4;

	//fill dir attributes
	memset((BYTE *)&dir, 0, sizeof(dir));
	memcpy((BYTE *)(dir.deName), name, 11);
	dir.deAttributes = attribute;
	fat_datetime(&tm);
	dir.CrtDate = dir.LstAccDate = dir.WrtDate = tm.Date;
	dir.CrtTime = dir.WrtTime = tm.Time;
	dir.CrtTimeTenth = tm.TimeTenth;
	dir.deFileSize = 0;

	//alloc one dir
	if(AllocDir(ParentDirSectorNum, &dir, &file) != 0)
		return -5;

	//alloc a cluster
	NewCluster = AllocCluster(0);
	if(NewCluster == 0xffff)
		return -6;

	//flush to disk
	Cache = GetSectorData(file.DirSectorNum);
	if(Cache == NULL)
		return -7;

	pdir = (DIRENTRY *)Cache;
	pdir += file.DirIndex;

	pdir->deStartCluster= NewCluster;
	Flush();

	return usbfat_open(filename);
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

long usbfat_lseek(int handle, long offset, int origin)
{
	_FILE *fp;
	WORD Cluster;
	unsigned int len;
	int i;

	if(handle <0 || handle >= sizeof(handles)/sizeof(_FILE))
		return 0;

	fp = &handles[handle];

	switch(origin)
	{
	case SEEK_SET:
		{
			if(offset < 0)

⌨️ 快捷键说明

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