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

📄 filesystem.c

📁 使用VC模拟一个在单片机内部FLASH的顺序文件系统
💻 C
字号:
#include "stdio.h"
#include "stdlib.h"
#include "type.h"

#include "filesystem.h"

#include "flash.h"
#include "main.h"




/****************************************************************************************************/
//以下为文件系统需要的变量和函数

FILE_HEAD fileFlash[1];			
FILE_HEAD fileHost[1];	
FILE_OPEN fileOpenTmp[1];
uint16 filePtr,fileNextPtr,fileEndPtr;
uint16 fileTmpLen;


uint8 FILEHeadCompare()
{
	if(	fileFlash->dirID[0] != fileHost->dirID[0]	||		
		fileFlash->dirID[1] != fileHost->dirID[1]	||
		fileFlash->fileID[0] != fileHost->fileID[0]	||
		fileFlash->fileID[1] != fileHost->fileID[1]	)
	{
		return FILE_HEAD_NOT_EQU;
	}
	return FILE_HEAD_EQU;
}

// 参数 mode:  0-> FREE文件 1 ->普通文件
uint8 FILELocateID(uint8 mode)
{
	filePtr = FILE_BASE_ADDR;	
	/* 读取filePtr处的文件头信息 */
	FLASHRead(filePtr,(uint8 *)fileFlash,8);	
	do
	{		
		/* 验证当前文件头信息的正确性 */
		if(fileFlash->type > TEA_TYPE) return FILE_LOCATE_ERR;			/* 文件头信息错误,返回*/
		// 需要定位的对象不同,读取到FREE文件的时候返回结果有所区别		
		if(fileFlash->type == FREE_TYPE) 
		{
			if(mode == 0)
			{
				return FILE_LOCATE_OK;		/* 定位到FREE文件,返回*/
			}
			else
			{
				return FILE_LOCATE_END;	/* 定位到FREE文件,返回*/
			}
		}		
		if(FILE_HEAD_NOT_EQU == FILEHeadCompare((uint8 *)fileFlash,(uint8 *)fileHost))
		{			
			// 定位下一个文件的地址,并读取该文件的头信息到fileFlash
FILELocateID_FindNext:
			fileNextPtr = filePtr;
			if(FILE_LOCATE_ERR == FILELocateNext())
			{
				return FILE_LOCATE_ERR;									/* 如果下一个文件的地址定位出错,返回定位错误 */
			}
			filePtr = fileNextPtr;
			continue;
		}
		// 文件头信息相同的情况下有一个特殊,存在着0000,0000的非FREE文件
		if(mode == FILE_LOCATE_FREE)
		{
			// 需要定位的不是FREE文件,虽然ID相同,但是type不同 继续寻找下一个文件
			goto FILELocateID_FindNext;				
		}
		return FILE_LOCATE_OK;											/* 找到匹配ID */
	}while(1);
	
	return FILE_LOCATE_ERR;												/* 文件系统出错 */		
}

void FILEInit()
{
	uint16 i;
	for(i=0;i<16 * 1024;i+=512)
	{
		FLASHPageErase(i);
	}	
	RamSet((uint8 *)fileFlash, 0, 8);
	fileFlash->length[0] = 0x20;
	FLASHWrite(FILE_BASE_ADDR, (uint8 *)fileFlash,8);	
}

uint8 FILEList(uint8 mode)
{
	uint8	i=0;
	if(mode == 0)
	{
		filePtr = FILE_BASE_ADDR;
	}	
	do
	{
		FLASHRead(filePtr,(uint8 *)fileFlash, 8);
		if(fileFlash->type > TEA_TYPE) return FILE_LIST_ERR;		
		
		RamCopy(sysTemp + i,(uint8 *)fileFlash,8);
		i += 8;
		if(i==64)
		{
			return FILE_LIST_OK;	
		}
		if(fileFlash->type == FREE_TYPE)  return FILE_LIST_OK;
		filePtr += 8;	/* 文件头信息长度 */
		filePtr += fileFlash->length[0] * 256 + fileFlash->length[1];
		if(filePtr > FILE_END_ADDR) return FILE_LIST_ERR;
	}while(1);

}

uint8 FILECreateItem()
{
	// 检测flash中是否存在相同的FILE
	switch (FILELocateID(FILE_LOCATE_FILE))
	{	
	case FILE_LOCATE_OK:
		return ERROR_INDEX;								// 返回参数错误
		break;
	case FILE_LOCATE_ERR:
		return ERROR_PROGRAM;						// 返回程序错误
		break;
	case FILE_LOCATE_END:
		// FLASH中没有发现相同ID的文件,开始创建文件
		// 调用FILELocateID 后 filePtr保存当前文件头信息的首地址
		// 从filePtr处开始清空FLASH,长度为头文件长度(8) + 文件长度 + free文件长度(8)
		fileTmpLen = 16;
		fileTmpLen += fileHost->length[0] * 256;
		fileTmpLen += fileHost->length[1];
		FLASHClear(filePtr,fileTmpLen);

		FLASHWrite(filePtr,(uint8 *)fileHost,8);		// 写入文件头信息
		filePtr += fileTmpLen;
		filePtr -= 8;

		// 准备写入FREE文件 
		// fileFlash中存放的是原来的FREE文件信息,所以只要更新一下文件剩余长度即可
		fileTmpLen = FILE_END_ADDR -filePtr;
		fileFlash->length[0] = fileTmpLen >> 8;
		fileFlash->length[1] = fileTmpLen & 0x00ff;
		FLASHWrite(filePtr,(uint8 *)fileFlash,8);		// 写入FREE文件

		return RIGHT_TOKEN;			//文件创建成功
		break;
	}
}

uint8 FILELocateNext()
{
	// 由fileNextPtr决定,下一个文件
	fileNextPtr += 8;
	fileNextPtr += fileFlash->length[0] * 256;
	fileNextPtr += fileFlash->length[1];
	// 判断下一个文件的有效性
	if(fileNextPtr > FILE_END_ADDR)
	{
		return FILE_LOCATE_ERR;
	}
	FLASHRead(fileNextPtr,(uint8 *)fileFlash,8);
	if(fileFlash->type > TEA_TYPE)	return FILE_LOCATE_ERR;
	if (fileFlash->type == FREE_TYPE) return FILE_LOCATE_END;
	return FILE_LOCATE_OK;			// 定位正确
}
// 删除fileHost中指定的文件
uint8 FILEDelt()
{
	uint16 fileIndex1,fileIndex2;
	//定位文件
	switch(FILELocateID(FILE_LOCATE_FILE))
	{
	case FILE_LOCATE_OK:
		//找到匹配文件 确认权限后 删除

		//定位下一个文件的位置
		fileNextPtr = filePtr;
		switch (FILELocateNext())
		{
		case FILE_LOCATE_OK:
			// 下一个文件有效,进行删除操作
			// 为了加快flash移动速度,定位FREE文件地址
			fileIndex1 = filePtr;
			fileIndex2 = fileNextPtr;
			RamSet((uint8 *)fileHost,0,8);		// 清空fileHost中的文件ID信息,准备查找free文件地址
			if(FILE_LOCATE_OK !=FILELocateID(FILE_LOCATE_FREE))
			{
				// 没有找到FREE文件
				return ERROR_PROGRAM;
			}
			// FREE文件定位正确
			fileTmpLen = filePtr - fileIndex2;	// 需要移动数据的长度
			fileTmpLen += 8;							// 把FREE文件一起移动,便于重新定位,更新				
			FLASHMove(fileIndex1,fileIndex2,fileTmpLen);
			// 重新定位free文件,更改剩余空间长度 			
			FILELocateID(FILE_LOCATE_FREE);
			fileTmpLen = FILE_END_ADDR - filePtr;
			fileFlash->length[0] = fileTmpLen >>8 ;
			fileFlash->length[1] = fileTmpLen & 0x00ff;
			FLASHUpdate(filePtr,(uint8 *)fileFlash,8);
			return RIGHT_TOKEN;
			break;
		case FILE_LOCATE_ERR:				
			// 文件系统错误,返回程序错误
			return ERROR_PROGRAM;
			break;
		case FILE_LOCATE_END:
			// 下一个文件是FREE文件,直接把FREE文件覆盖到filePtr处
			// 简化操作
			RamSet((uint8 *)fileFlash,0,8);
			fileTmpLen = FILE_END_ADDR -filePtr;
			fileFlash->length[0] = fileTmpLen >> 8;
			fileFlash->length[1] = fileTmpLen & 0x00ff;
			FLASHUpdate(filePtr,(uint8 *)fileFlash,8);
			return RIGHT_TOKEN;		// 操作正确
			break;
		}
		break;	
	case FILE_LOCATE_ERR:
		// 文件系统错误,返回程序错误
		return ERROR_PROGRAM;
		break;
	case FILE_LOCATE_END:
		// 没有匹配文件,返回参数错误
		return ERROR_INDEX;
		break;
	}
}

uint8 FILEOpen()
{
	switch (FILELocateID(FILE_LOCATE_FILE))
	{
	case FILE_LOCATE_OK:
		// 找到文件
		fileOpenTmp->address = filePtr + 8;
		fileOpenTmp->length = fileFlash->length[0] * 256 + fileFlash->length[1];
		fileOpenTmp->authority = fileFlash->authority;
		fileOpenTmp->type = fileFlash->type;
		return RIGHT_TOKEN;
		break;
	case FILE_LOCATE_ERR:
		// 文件系统错误
		return ERROR_PROGRAM;
		break;
	case FILE_LOCATE_END:
		// 找不到文件
		return ERROR_INDEX;
		break;
	}
}

uint8 FILERead()
{
	// 检验是否已经打开文件
	if((fileOpenTmp->address = 0) || (fileOpenTmp->address > FILE_END_ADDR))
	{
		return ERROR_NOTOPEN;			// 未打开文件
	}

	// 检验权限
	

	// 判断参数是否正确



}


⌨️ 快捷键说明

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