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

📄 fat12.c

📁 FAT12 文件系统,囊括了文件系统的各个函数,另外还包括了地址映射,适合读写NAND_FLASH
💻 C
📖 第 1 页 / 共 5 页
字号:

		if(dir_len_count > 11)			//文件名称长度不能大于11
			return NULL;

		pstatic++;
		ppath++;
	}

	return static_path;					//该语句不会被执行
}





/************ 函数 void unformat_name(char * filename, const unsigned char dirname[11]) *************/
/* 功能:	将dirname[11]中的8-3存储格式的文件名转换成不带空格的打印格式文件名存到filename中		*/
/* 入口参数:char * filename---准备存放转换后的打印格式的文件名缓冲区								*/
/*			const unsigned char dirname[11]---待转换的存储格式文件名								*/
/* 出口参数:无																						*/
/* 说明:	非用户使用函数																			*/
/****************************************************************************************************/
void unformat_name(char * filename, const unsigned char *dirname)//OK
{
	int i;
	int j;

	memset(filename, 0, 13);			//文件名缓冲区清0

	for(i=0; i<8; i++)
	{
		if(dirname[i] != 0x20)			
			filename[i] = dirname[i];	//dirname[]中的文件名送filename[]缓冲区
		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];//dirname[]中的文件扩展名送缓冲区
			else
				break;
		}
	}
}



/**** 函数 DWORD DirSectorFileNameSearch(DWORD LgSector, const char dirname[11],  _FILE *file) ******/
/*功能:在所给的sector内寻找与dirname(存储格式)名称相同的目录项,找到之后返回该逻辑扇区号本身,否则返回*/
/*		0xffffffff   																				*/
/*入口参数:DWORD LgSector----扇区号																	*/
/*			const char dirname[11]---存储格式的目录或文件名,存储格式[aaaaaaaabbb]					*/
/*			_FILE *file---准备存放找到的文件信息的文件缓冲区										*/
/*出口参数:找到之后返回目录/文件所在镞的起始扇区号,否则返回0xFFFFFFFF,同时更新file中的文件信息	*/
/*说明:	该函数仅由FileSearchByName函数调用														*/
/*			非用户使用函数																			*/
/****************************************************************************************************/
DWORD DirSectorFileNameSearch(DWORD LgSector, const char dirname[11],  _FILE *file)//OK
{
	BYTE* Cache;
	DIRENTRY *dir;
	unsigned int j;
	BYTE tempbuffer[512];

	Cache = ReadLgSector(LgSector,tempbuffer);
	if(Cache == NULL)
		return 0xffffffff;
	
	dir = (DIRENTRY *)Cache;
	for(j=0; (dir->deName[0] != '\0') && (j< BytesPerSector / sizeof(DIRENTRY)); j++)					//在整个扇区搜索非空的目录项
	{
		if((memcmp((const char*)dir->deName, dirname, 11) == 0) && (!(dir->deAttributes & ATTR_VOLUME)))//如果目录名/文件名相同,且不是卷标项目
		{
			if(file != NULL)																			//如果文件不空才进行更新
			{
				memset((BYTE *)file, 0, sizeof(_FILE));
				file->DirSectorNum = LgSector;															//更新文件中的扇区信息
				file->DirIndex = j;																		//更新文件中的目录项索引
				memcpy((BYTE *)(&file->dir), (BYTE *)dir, sizeof(DIRENTRY));							//更新文件中的目录项信息
			}
			return ClusterNumToSectorNum(dir->deStartCluster);											//返回该目录/文件所在镞的起始扇区号
		}
		dir++;
	}
	return 0xffffffff;
}


//该函数涉及到文件目录项的长度更改问题
/********************** 函数 int ValidDirSearch(DWORD LgSector, FatGet *fat_get) ********************/
/* 功能:在所给Lgsector内寻找第一个未被删除且不是卷标项的目录(文件)项,记录项目名称等信息到fat_get中	*/
/* 入口参数:DWORD LgSector----扇区号																*/
/*			FatGet *fat_get---记录文件信息的缓冲区													*/
/* 出口参数:如果存在这样的目录项则返回0,否则如果该扇区空返回1,找不到返回2							*/
/* 说明:	非用户使用函数																			*/
/****************************************************************************************************/
int ValidDirSearch(DWORD LgSector, FatGet *fat_get)//OK
{
	BYTE* Cache;
	DIRENTRY *dir;
	unsigned int j;
	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};
	BYTE tempbuffer[512];

	Cache = ReadLgSector(LgSector,tempbuffer);
	if(Cache == NULL)
		return 1;

	dir = (DIRENTRY *)Cache;
	dir += fat_get->DirIndex;												//找到该文件的目录项位置

	for(j=fat_get->DirIndex; (dir->deName[0] != '\0') && (j< BytesPerSector / sizeof(DIRENTRY)); j++)
	{
		if(dir->deName[0] != 0xe5 && (!(dir->deAttributes & ATTR_VOLUME)))	//如果目录名/文件未删除,且不是卷标项目则记录在fat_get中
		{
			if((memcmp((const char*)dir->deName, dot, 11) == 0) || (memcmp((const char*)dir->deName, dotdot, 11) == 0))
			{	continue;	}
			else
			{
				fat_get->DirSectorNum = LgSector;
				fat_get->DirIndex = j;//+ 1 原来加1是考虑到windows操作系统在创建文件时即使对于短文件名,目录项也会占用64个字节,而不是32
				unformat_name(fat_get->filename, dir->deName);

				return 0;
			}
		}

		dir++;
	}

	return 2;
}



/********* 函数 DWORD FileSearchByName(DWORD LgSector, const char dirname[11], _FILE *file) *********/
/* 功能:	根据文件名(存储格式)在根目录区或者数据区寻找是否有与dirname名称相同的目录或文件,找到之 */
/*			后返回该文件的起始扇区号,同时将文件信息存储在输入存储区file中。注意寻找时的策略是按照文 */
/*			件链接的顺序																			*/
/* 入口参数:DWORD LgSector----扇区号,应该为FirstDirSector(33)或大于等于64						*/
/*			const char dirname[11]----要查找的目录或文件名,存储格式[aaaaaaaabbb]					*/
/*			_FILE *file----存储文件信息的缓冲区														*/
/* 出口参数:如果存在这样的目录项则返回该文件目录项所在的扇区号,否则如果找不到返回0xffffffff		*/
/* 说明:	该函数仅由FileLocateByPath函数调用														*/
/*			非用户使用函数																			*/
/****************************************************************************************************/
DWORD FileSearchByName(DWORD LgSector, const char dirname[11], _FILE *file)//OK
{	
	DWORD sectornum;
	WORD  Cluster;
	DWORD FirstSectorOfFile;


	if(LgSector == FirstDirSector)											//先找根目录区
	{
		for(sectornum=0; sectornum<RootDirSectors; sectornum++)				//在整个根目录区的所有扇区中寻找
		{
			FirstSectorOfFile = DirSectorFileNameSearch(LgSector++, dirname, file); //寻找与dirname名称相同的目录/文件,得到该文件目录项所在的扇区号
			if(FirstSectorOfFile != 0xffffffff)                       		//返回目录/文件的扇区号
			{	return FirstSectorOfFile;	}
		}
	}
	else
	{
		Cluster = SectorNumToClusterNum(LgSector);							//在非根目录区寻找

		while(Cluster != 0x0fff)											//不是最后一簇
		{
			for(sectornum=0; sectornum< SectorsPerCluster; sectornum++)
			{
				FirstSectorOfFile = DirSectorFileNameSearch(LgSector++, dirname, file);//寻找名称相同的目录/文件项
				if(FirstSectorOfFile != 0xffffffff)
				{	return FirstSectorOfFile;	}
			}

			Cluster = GetNextLgClusterNum(Cluster);							//寻找时按照文件链接的顺序
			LgSector = ClusterNumToSectorNum(Cluster);
		}
	}

	return 0xffffffff;														//找不到
}



/******************** 函数 DWORD FileLocateByPath(const char *path, _FILE *file) ********************/
/* 功能:根据输入的路径名定位文件,即在根目录区查找到它的第一级目录,在下一个簇查找到它的第二级目录, */
/*		直到最终定位文件,将找到的文件信息保存在输入缓冲区file中										*/
/* 入口参数:const char *path-----路径,打印格式[\aaaaaa\aaaa\aaaaa.bbb]								*/
/*			_FILE *file----保存文件信息的缓冲区														*/
/* 出口参数:如果存在这样的目录项则返回该文件最后目录项所在的扇区号,或者当路径只有[\]而没有其他路径	*/
/*			名时将返回根目录扇区号,否则如果找不到则返回0xffffffff									*/
/*说明:	该函数仅由其他函数调用																	*/
/*			非用户使用函数																			*/
/****************************************************************************************************/
DWORD FileLocateByPath(const char *path, _FILE *file)//OK
{
	DWORD Sector = FirstDirSector;
	char *p;

	p = get_valid_format(path);												//将文件路径转换成存储格式便于在根目录区寻找
	if(p == NULL)
		{ return 0xffffffff; }

	p++;																	//在第一级目录中忽略第一个‘\’

	for(;;)
	{
		if(*p == NULL)
		{ return Sector; }													//找到之后返回该文件最后一级目录项所在扇区号
		Sector = FileSearchByName(Sector, p, file);							//在根目录区寻找是否有与路径每一小段同名的目录/文件项
		if(Sector == 0xffffffff)
			{ return 0xffffffff; }

		p+=12;																//指向下一级目录并跳过'\'
	}
	return 0xffffffff;														//该语句事实上不会被执行
}


//获得当前的系统时间,该文件需要根据芯片本身的实时时钟寄存器来修改,程序其他部分正确
/************************** 函数 void fat_datetime(FatDateTime *fatdatetime) ************************/
/* 功能:从系统的实时时钟获得当前的系统时间,并将时间写到fatdatetime中								*/
/* 入口参数:FatDateTime *fatdatetime----准备更新的时间变量											*/
/* 出口参数:无																						*/
/* 说明:	非用户使用函数																			*/
/****************************************************************************************************/
void fat_datetime(FatDateTime *fatdatetime)//OK
{
	int year,month,day,hour,min,sec;
	
	// TimeGet();
    
     /*RTCYear=year;
      RTCMonth= month;
      RTCDay=day;
      RTCHour=hour;
      RTCMinute=min;
      RTCSecond=sec;*/
      
    year = RTCYear;
    month = RTCMonth;
    day = RTCDay;
    //weekday = RTCDate;
    hour = RTCHour;
    min = RTCMinute;
    sec = RTCSecond;
    

	fatdatetime->Date = ((day << DD_DAY_SHIFT)&DD_DAY_MASK)|((month <<DD_MONTH_SHIFT)&DD_MONTH_MASK)
	        |(((year-1980) <<DD_YEAR_SHIFT)&DD_YEAR_MASK);
	
	fatdatetime->Time = ((hour<<DT_HOURS_SHIFT)&DT_HOURS_MASK)|((min<<DT_MINUTES_SHIFT)&DT_MINUTES_MASK)
	      |(((sec>>1)<<DT_2SECONDS_SHIFT)&DT_2SECONDS_MASK);
	
	//fatdatetime->TimeTenth = (sec % 2) * 100; 						//系统的毫秒数/ 10;
}


/******************************* 函数 int fat_mkdir( const char *dirname) ***************************/
/* 功能:在已经存在的父目录下创建一个子目录,仅1级目录: \父目录\新子目录								*/
/* 入口参数: const char *dirname----准备创建的目录名(打印格式),应该为[\aaaa\bbbbbbbbbbb],其中aaaa	*/
/*			是已经存在的父目录,bbbbbbbbbbb是即将建立的目录名(各级目录名长度都要小于11个字符);如果	*/
/*			只有[\bbbbbbbbbbb],即只有新目录名,则在根目录下创建新目录								*/
/* 出口参数:创建成功返回0																			*/
/* 说明:	用户使用函数																			*/
/****************************************************************************************************/
int fat_mkdir( const char *dirname)//OK
{	
	BYTE i;
	DIRENTRY dir;
	DWORD SectorNum;
	char path[512];
	char name[11];
	char *p;
	FatDateTime datatime;
	_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};
	BYTE tempbuffer[512];

	p = get_valid_format(dirname);									//首先将目录格式转换成存储格式
	if(p == NULL)													//如果目录名输入非法,则返回1
		{ return 1; }
	
	if(FileLocateByPath(dirname, NULL) != 0xffffffff)				//再判断该目录是否已经存在,如果存在则返回4
		{ return 4; }

	/******** 将目录分为父目录和新目录两级来处理 *********/
	strncpy(name, &p[strlen(p)-11], 11);							//拷贝新的子目录名到name暂存
    
    strcpy(path, dirname);
	p = strrchr(path, '\\');										//查找path中最后出现‘\'的位置,返回该位置的指针
	
	if(p == path) 													
		{ *(p+1) = '\0'; }											//此时只有新目录名.在第1个'\'之后赋结束符,即将在根目录下创建一个新子目录
	else
		{ *p = '\0'; }												//否则存在父目录时path中最后一次出现‘\'的位置赋'\0',此时说明有上一级目录
    
	/********* 定位父目录 *********/
	SectorNum = FileLocateByPath(path, NULL);						//获取父目录目录项所在的扇区号
	if(SectorNum == 0xffffffff)										//判断该路径是否不存在
	{ return 2; }

	/*********** 以下填充新目录中的属性时间等信息 *****************/
	memset((BYTE *)&dir, 0, sizeof(dir));							//dir首先清0
	memcpy((BYTE *)(dir.deName), na

⌨️ 快捷键说明

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