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

📄 fsmdfs.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************
 
  FILE NAME: FsmDfs.c

  DESCRIPTION:

    This module contains functions of Data file system.

 Copyright (c) 2002, VIA Technologies, Inc.
*****************************************************************************/


#include "fsmdefs.h"
#include "ostype.h"
#include "FsmApi.h"
#include "string.h"
#include "FsmQueue.h"
#include "FsmDev.h"
#include "FsmDfs.h"
#include "stdlib.h"
#include "FsmFlash.h"



#define FsmGetCurrentDate()		0


#define MAX_DFS_FD				20


/* global vairibale declare */

FsmFsDrvT		FsmDfsDrv =
				{
					FsmDfsCreate,
					FsmDfsOpen,
					FsmDfsDelete,
					FsmDfsClose,
					FsmDfsRead,
					FsmDfsWrite,
					FsmDfsIoCtrl,
					FsmDfsInit,
					FsmDfsTerminate 
				};


FsmDfsFileDescriptorT		FsmDfsFds[MAX_DFS_FD];


/* local vairibale declare */

static HMSEM			FsmDfsMtxSem;

static HFSMTASK			hWriteTask;



static uint32
DfsLocateFile(
		FsmDevObjHdrT * DevP, 
		char * path,
		uint32 * ParentDirFirstLsn,
		FsmFileDirEntryT * entry
		);

static uint32
DfsReadFileEntry(
		FsmDevObjHdrT * DevP, 
		uint32	*	StartLsn, 
		uint32	*	offset,
		FsmFileDirEntryT * entry
		);

static uint32		DfsFilenameValid(const char * path);

static uint32		DfsAllocFd(void); 
static uint32		DfsFreeFd(uint32 fd);

static uint32		DfsIsParentDirOpened(char * path);
static uint32		DfsIsFileOpened(char * path);



/*****************************************************************
 * 
 * FsmDfsStartup :
 *       Initialize the internal structure of data file system.
 *
 * Input:
 *        NONE
 *
 * Output:
 *       ERR_NONE  on success
 *
 *       error code on failure.
 *
 *****************************************************************/

uint32 FsmDfsStartup()
{
	uint32		i;
	uint32		status;

	FsmDfsMtxSem = FsmCreateMtxSem(1);

	if (FsmDfsMtxSem == NULL)
	{
	    return ERR_SYSTEM;	
	}

	status = QueueCreate();

	if (status != ERR_NONE)
	{
		FsmDeleteMtxSem(FsmDfsMtxSem);

		return status;
	}

	FsmMemorySet((uint8 *)&FsmDfsFds[0], 
				 0, 
				 MAX_DFS_FD * sizeof(FsmDfsFileDescriptorT)
				 );

	for(i = 0; i < MAX_DFS_FD; i++)
	{
		FsmDfsFds[i].Flag = DFD_FLAG_FREE;
	}

	for(i = 0; i < MAX_DFS_FD; i++)
	{
		FsmDfsFds[i].MutexSem = FsmCreateMtxSem(1);

		if(FsmDfsFds[i].MutexSem == NULL)
			break;
	}

	if(i < MAX_DFS_FD)
	{
		while(i > 0)
		{
			FsmDeleteMtxSem(FsmDfsFds[i - 1].MutexSem);
			FsmDfsFds[i - 1].MutexSem = NULL;
			i--;
		}

		QueueDestroy();
		FsmDeleteMtxSem(FsmDfsMtxSem);

		return ERR_SYSTEM;
	}

	hWriteTask = FsmCreateTask( "bkgd_wr", 
								FSM_WRITE_TASK_PRIORITY, 
								FSM_WRITE_TASK_STACK_SIZE, 
								(uint32)BkgdWriteTask
								);

	if (hWriteTask == NULL)
	{
		for(i = 0; i < MAX_DFS_FD; i++)
		{
			FsmDeleteMtxSem(FsmDfsFds[i].MutexSem);
			FsmDfsFds[i].MutexSem = NULL;
		}

		QueueDestroy();
		FsmDeleteMtxSem(FsmDfsMtxSem);

		return ERR_SYSTEM;
	}

	return ERR_NONE;
}

/*****************************************************************
 * 
 * FsmDfsExit :
 *       cleanup the internal structure of data file system
 *       before data file system terminates.
 *
 * Input:
 *        NONE
 *
 * Output:
 *       ERR_NONE  on success
 *
 *       error code on failure.
 *
 *****************************************************************/

uint32 FsmDfsExit()
{
	uint32		i;

	FsmDeleteTask(hWriteTask);

	for(i = 0; i < MAX_DFS_FD; i++)
	{
		FsmDeleteMtxSem(FsmDfsFds[i].MutexSem);
		FsmDfsFds[i].MutexSem = NULL;
	}

	QueueDestroy();

	FsmDeleteMtxSem(FsmDfsMtxSem);

	return ERR_NONE;
}

/*****************************************************************
 * Function Name: 
 *            FsmDfsInit
 *
 * Description  : 
 *           Parse command , implement the ioctrl interface
 *
 * Input : 
 *           DevObjP      : pointer to the Device structure
 *           SectorSize   : sector size
 *
 * First Edit 2003.8.13 wsm
 *
 *****************************************************************/

uint32 FsmDfsInit(FsmDevObjHdrT * DevObjP, uint32 SectorSize)
{
	uint32				temp;
    FsmFlashMediaT *	FlashMedia;

	if (SectorSize == 0)
		return ERR_PARAM;

	if (DevObjP->DevDrvP->FsmDevInit(DevObjP) != HW_ERR_NONE)
	{
#ifdef FSM_DEBUG
		MonPrintf("\nFailed on Initializing device!");
#endif
		return ERR_SYSTEM;
	}

	/* creat the media structure */
	FlashMedia = (FsmFlashMediaT *)FsmTryMalloc(sizeof(FsmFlashMediaT));

	if (FlashMedia == NULL )
	{
		DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);

#ifdef FSM_DEBUG
		MonPrintf("Malloc fail at start up");
#endif
		return ERR_MEMORY;
	}

	FlashMedia->MediaObjHdr.DevObjP = DevObjP;
	FlashMedia->SectorSize = SectorSize;

	FlashMedia->BlockSize = ((FsmFlashDevT *)DevObjP)->BlockSize;

	temp = ((FsmFlashDevT *)DevObjP)->BlockSize - sizeof(FsmBlockInfoT);

	FlashMedia->SectorsPerBlock = (uint16)(temp / (SectorSize + sizeof(FsmFlashSectorHdrT)));

	FlashMedia->MaxPsn = ((uint32)FlashMedia->SectorsPerBlock) * (((FsmFlashDevT *)DevObjP)->Blocks);

	/* FlashMedia->SpareBlk = (uint16)(-1); */

	FlashMedia->MapTblLock = FsmCreateMtxSem(1);

	if (FlashMedia->MapTblLock == NULL)
	{
#ifdef FSM_DEBUG
		MonPrintf("Malloc fail at start up");
#endif

		FsmFree((void *)FlashMedia);

		DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);

		return ERR_SYSTEM;
	}

	FlashMedia->InfoLock = FsmCreateMtxSem(1);

	if (FlashMedia->InfoLock == NULL)
	{
#ifdef FSM_DEBUG
		MonPrintf("Malloc fail at start up");
#endif

		FsmDeleteMtxSem(FlashMedia->MapTblLock);

		FsmFree((void *)FlashMedia);

		DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);

		return ERR_SYSTEM;
	}

	temp = FlashMedia->MaxPsn * sizeof(uint32 *);

	FlashMedia->Lsn2PsnP = (uint32 *)FsmTryMalloc(temp);

	if (FlashMedia->Lsn2PsnP == NULL )
	{
#ifdef FSM_DEBUG
		MonPrintf("Malloc fail at start up");
#endif

		FsmDeleteMtxSem(FlashMedia->InfoLock);

		FsmDeleteMtxSem(FlashMedia->MapTblLock);

		FsmFree((void *)FlashMedia);

		DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);

		return ERR_MEMORY;
	}

	FsmMemorySet((uint8 *)FlashMedia->Lsn2PsnP, (uint8)INVALID_PSN, temp);

	temp = sizeof(FsmBlockStatisticT) * ((uint32)((FsmFlashDevT*)DevObjP)->Blocks);

	FlashMedia->BlockInfoP = (FsmBlockStatisticT *)FsmTryMalloc(temp);

	if(FlashMedia->BlockInfoP == NULL)
	{
#ifdef FSM_DEBUG
		MonPrintf("Malloc fail at start up");
#endif

		FsmFree(FlashMedia->Lsn2PsnP);

		FsmDeleteMtxSem(FlashMedia->InfoLock);

		FsmDeleteMtxSem(FlashMedia->MapTblLock);

		FsmFree((void *)FlashMedia);

		DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);

		return ERR_MEMORY;
	}

	FsmMemorySet((uint8 *)FlashMedia->BlockInfoP, 0, temp);

	/* Now FlashMedia (MediaObj) has been initialized. */

	DevObjP->MediaObjP = (void *)FlashMedia;  /* DevObj has been initialized. It can be passed to InitUnit. */

	/* call power lost recovery process */
	temp = FsmPlrDfsCheck(DevObjP,
						  ((FsmFlashDevT*)DevObjP)->BlockSize,
						  ((FsmFlashDevT*)DevObjP)->Blocks
						  );

	if(temp != ERR_NONE)
	{
		FsmFree((void *)FlashMedia->BlockInfoP);

		FsmFree(FlashMedia->Lsn2PsnP);

		FsmDeleteMtxSem(FlashMedia->InfoLock);

		FsmDeleteMtxSem(FlashMedia->MapTblLock);

		FsmFree((void *)FlashMedia);

		DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);

		return temp;
	}

	return ERR_NONE;
}

/*****************************************************************
 * Function Name: 
 *          FsmDfsTerminate
 *          All files opened from this device 
 *          should be closed before calling this function.
 *          FsmDfsTerminate doesn't close any files.
 *
 * Description  : 
 *          Parse command , implement the ioctrl interface
 *
 * Input :
 *          DevObjP      : pointer to the Device structure
 *
 * First Edit 2003.8.13 wsm
 *
 *****************************************************************/

uint32 FsmDfsTerminate(FsmDevObjHdrT * DevObjP)
{
/*	uint32			status;*/
	uint32			i;
    FsmFlashMediaT *	FlashMedia;

	FsmGetMtxSem(FsmDfsMtxSem);

	/* If it is called when system starts, FsmGetMtxSem always fails.
	status = FsmGetMtxSem(FsmDfsMtxSem);

	if(status != ERR_NONE)
	{
		return status;
	}
	*/

	for(i = 0; i < MAX_DFS_FD; i++)
	{
		if((FsmDfsFds[i].Flag != DFD_FLAG_FREE)
			&& (FsmDfsFds[i].FdHdr.DevObjP == DevObjP))
		{
			break;
		}
	}

	FsmReleaseMtxSem(FsmDfsMtxSem);

	if(i < MAX_DFS_FD)
	{
		return ERR_ACCESS_DENY;
	}

	/* all files from this device must have been closed before came to here. */
	FlashMedia = (FsmFlashMediaT *)DevObjP->MediaObjP;

	FsmFree((void *)FlashMedia->BlockInfoP);

	FsmFree(FlashMedia->Lsn2PsnP);

	FsmDeleteMtxSem(FlashMedia->InfoLock);

	FsmDeleteMtxSem(FlashMedia->MapTblLock);

	FsmFree((void *)FlashMedia);

	DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);

	return ERR_NONE;
}

/*
 * Function Name: DfsOpen
 * Description  : Open a file, return the file descriptor, implement the open interface 
 * Arguments    : path      : file path
 *              : mode      : open mode
 * First Edit 2003.8.13 wsm
 */

uint32 FsmDfsOpen(FsmDevObjHdrT * DevObjP, char * path, uint32 mode, uint32 * ErrorCodeP )
{
	uint32				status;
	uint32              index;
	uint32              length;
	uint8				root_dir = FALSE;
	uint32              ParentDirFirstLsn;
	uint32				fd;
	FsmFileDirEntryT    entry;


#ifdef FSM_DEBUG
	MonPrintf("Interface DfsOpen \n");
#endif

	root_dir = FALSE;

	if(path == NULL)
	{
		status = ERR_PARAM;
		goto DfsOpen_Exit;
	}

	length = strlen(path);

	if((length == 0) || (length > DFS_MAX_PATH_LEN))
	{
		status = ERR_PARAM;
		goto DfsOpen_Exit;
	}

	if(DfsFilenameValid(path) == FALSE)
	{
		status = ERR_PARAM;
		goto DfsOpen_Exit;
	}

	if(length > 1)
	{
		/* path should not end with slash if it is not the root dir. */
		if((path[length - 1] == '\\') || (path[length - 1] == '/'))
		{
			status = ERR_PARAM;
			goto DfsOpen_Exit;
		}
	}
	else
	{
		if ((length == 1) && ((*path == '\\') || (*path == '/')))
		{
			if(mode & FSM_OPEN_FILE)
			{
				status = ERR_PARAM;
				goto DfsOpen_Exit;
			}

			root_dir = TRUE;
		}
	}

	if ((status = FsmGetMtxSem(FsmDfsMtxSem)) != ERR_NONE)
	{
		goto DfsOpen_Exit;
	}

	index = DfsIsFileOpened(path);

	if (index != INVALID_FILE_HANDLE)
	{
		if ((FsmDfsFds[index].AccessMode & FSM_OPEN_WRITE)
			|| (mode & FSM_OPEN_WRITE))
		{
			/* the file or directory has been opened or is being re-opened for writing. */
			FsmReleaseMtxSem(FsmDfsMtxSem);

			status = ERR_ACCESS_DENY;
			goto DfsOpen_Exit;
		}

		/* allows multiple open for read. */
	}

	fd = DfsAllocFd();

	if (fd == INVALID_FILE_HANDLE)
	{
		FsmReleaseMtxSem(FsmDfsMtxSem);

		status = ERR_MAX_OPEN;
		goto DfsOpen_Exit;
	}

	FsmDfsFds[fd].AccessMode = mode;	/* prevent the followed open for write or for read if mode = WRITE. */

	FsmDfsFds[fd].FdHdr.DevObjP = DevObjP;	/* prevent this device from being unmounted. */

	strcpy(FsmDfsFds[fd].PathName, path);

	FsmReleaseMtxSem(FsmDfsMtxSem); 

	status = FsmGetMtxSem(FsmDfsFds[fd].MutexSem);

	if(status != ERR_NONE)
	{
		DfsFreeFd(fd);
		goto DfsOpen_Exit;
	}

	/* Is it the root directory ? */
	if (root_dir)
	{
/*		FsmDfsFds[fd].AccessMode = mode; */
		FsmDfsFds[fd].FileLength = 0;
		FsmDfsFds[fd].FirstLsn = 0;
		FsmDfsFds[fd].ParentDirFirstLsn = (uint32)(-1);		/* 0; */
		FsmDfsFds[fd].FilePointer = 0;						/* 1; */
		FsmDfsFds[fd].CreateDate = 0;
		FsmDfsFds[fd].CreateTime = 0;
		FsmDfsFds[fd].Attrib = ENTRY_TYPE_SUBDIR;

		goto DfsOpen_Exit_Success;
		/*
		FsmDfsFds[fd].Flag = DFD_FLAG_IN_USE;	// prevent from being preempted.

		FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);

		if(ErrorCodeP != NULL)
			*ErrorCodeP = ERR_NONE;

		return fd;
		*/
	}
	else
	{
		status = DfsLocateFile(DevObjP, path, &ParentDirFirstLsn, &entry);
		if (status != ERR_NONE)
		{
			goto DfsOpen_Exit2;
		}
	}

	if ((entry.Type == ENTRY_TYPE_FILE) && (mode & FSM_OPEN_FILE))
	{
		status = ERR_NONE;
		FsmDfsFds[fd].FileLength  = entry.Length;
		FsmDfsFds[fd].FilePointer = 0;
	}
	else if ((entry.Type == ENTRY_TYPE_SUBDIR) && (mode & FSM_OPEN_DIR))
	{
		status = ERR_NONE;

		/* 
		 * For subdirectory, Length always = 0.
		 * We will use this field as file pointer
		 * along with FilePointer field.
		 * In that case, Length field stores sector LSN,
		 * and FilePointer field stores offset into the sector.
		 */
		FsmDfsFds[fd].FileLength  = entry.FirstLsn;

⌨️ 快捷键说明

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