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

📄 fsmdataitem.c

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

  DESCRIPTION:

    This module contains Fsm data item manager.

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


#include "fsmdataitem.h"
#include "Fsmdfs.h"
#include "FsmQueue.h"


#define MAX_DIM_FD		10


/* Flags for Data Item descriptor. */
#define DID_FLAG_FREE			0x00
#define DID_FLAG_IN_USE			0x01
#define DID_FLAG_PENDING		0x02

typedef /*PACKED*/ struct
{
	uint16                  ItemType;
	uint16                  ItemId;
	uint32				    FirstLsn;
	uint32					ItemLength;
  	uint8                   Flag;
	uint32                  ErrorCode;
} FsmDataItemDescriptorT;


/* Global variables and function declare here*/
FsmDevObjHdrT *		FsmDataItemDevObjP;


/* Local variables and function declare here*/
static FsmDataItemDescriptorT	DataItemFds[MAX_DIM_FD];

static HMSEM		DataItemMtxSem;
static uint32		DimErrorCode;	/* data item manager error code. */


static uint32
LocateDataItem(
		uint16 type,
		uint16 id,
		FsmItemDirEntryT * entry
		);

static uint32
ReadDataItemEntry(
		uint32 * Lsn,
		uint32 * EntryCount, 
		FsmItemDirEntryT * Entry
		);

static uint32
ReadSingleInstance(
		uint32 FirstLsn, 
		uint32 offset, 
		uint8 * buf, 
		uint32 size, 
		uint32 * read_size
		);

static uint32
ReadMultInstance(
		uint32 FirstLsn,
		uint32 offset, 
		uint8 * buf,
		uint32 size, 
		uint32 * read_size
		);

/*****************************************************************
 * Function Name:
 *            FsmDataItemInit
 *
 * Description  :
 *
 *
 * Input :
 *
 * First Edit 2003.9.30 wsm
 *
 *****************************************************************/

uint32 FsmDataItemInit(FsmDevObjHdrT * DevObjP)
{
	uint32		i;

	FsmDataItemDevObjP = DevObjP;

	DataItemMtxSem = FsmCreateMtxSem(1);

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

	/* Initialize the data item fd */
	for (i = 0 ; i < MAX_DIM_FD ; i++)
	{
		FsmMemorySet((uint8 *)&DataItemFds[i], 0, sizeof(FsmDataItemDescriptorT));
        DataItemFds[i].Flag = DID_FLAG_FREE;
	}

    return ERR_NONE;
}

/*****************************************************************
 * Function Name:
 *            FsmDataItemExit
 *
 * Description  :
 *
 *
 * Input :
 *
 * First Edit 2003.9.30 wsm
 *
 * 
 *****************************************************************/

uint32 FsmDataItemExit()
{
	uint32		i;
/*	uint32		status;*/

	FsmGetMtxSem(DataItemMtxSem);

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

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

	/* Initialize the data item fd */
	for (i = 0 ; i < MAX_DIM_FD ; i++)
	{
		if (DataItemFds[i].Flag != DID_FLAG_FREE)
		{
			break;
		}
	}

	FsmReleaseMtxSem(DataItemMtxSem);

	if(i < MAX_DIM_FD)
		return ERR_ACCESS_DENY;

	FsmDataItemDevObjP = NULL;

	return FsmDeleteMtxSem(DataItemMtxSem);
}


/*****************************************************************
 * Function Name:
 *            FsmDataItemOpen
 *
 * Description  :
 *           Open a data item file, return the file descriptor
 *
 * Input :
 *           type
 *           id
 *
 * First Edit 2003.9.30 wsm
 *
 *****************************************************************/

uint32 FsmDataItemOpen(uint16 type, uint16 id, uint32 mode)
{
	uint32				fd;
	FsmItemDirEntryT	Entry;
	FsmFlashMediaT   *	MediaP;
	uint32				SpaceAvail;

#ifdef FSM_DEBUG
	MonPrintf("enter interface Data Item Open in %d \n", __LINE__);
#endif

	/* argument check */
	if (FsmDataItemDevObjP == NULL)
    {
		DimErrorCode = ERR_INIT;
		return INVALID_FILE_HANDLE;
	}

	MediaP = (FsmFlashMediaT *)FsmDataItemDevObjP->MediaObjP;

	if (MediaP == NULL)
	{
		DimErrorCode = ERR_SYSTEM;
		return INVALID_FILE_HANDLE;
	}

	if ((type == MATCH_TYPE) || (id == MATCH_ID))
	{
		DimErrorCode = ERR_PARAM;
		return INVALID_FILE_HANDLE;
	}

    /* lock the item fd structure array */
	if ((DimErrorCode = FsmGetMtxSem(DataItemMtxSem)) != ERR_NONE)
	{
#ifdef FSM_DEBUG
		MonPrintf("DataItemLock semaphore fail!");
#endif
		return INVALID_FILE_HANDLE;
	}

    /* Check if the dataitem is in use */
	for(fd = 0; fd < MAX_DIM_FD; fd++)
    {
        if ((DataItemFds[fd].Flag == DID_FLAG_FREE))
        {
            continue;
        }

    	if ((DataItemFds[fd].ItemType == type) && (DataItemFds[fd].ItemId == id))
    	{
			FsmReleaseMtxSem(DataItemMtxSem);

#ifdef FSM_DEBUG
			MonPrintf("The Data Item is on using.");
#endif

			DimErrorCode = ERR_NONE;
			return fd;
    	}
    }

	for(fd = 0; fd < MAX_DIM_FD; fd++)
	{
        if ((DataItemFds[fd].Flag == DID_FLAG_FREE))
        {
			break;
        }
	}

	/* if the  fd array is full */
	if (fd == MAX_DIM_FD)
	{

#ifdef FSM_DEBUG
		MonPrintf("The Data Item Fd is full.");
#endif
		DimErrorCode = ERR_MAX_OPEN;

		FsmReleaseMtxSem(DataItemMtxSem);

		return INVALID_FILE_HANDLE;
	}

    /* this data item not in using */
    DataItemFds[fd].Flag = DID_FLAG_IN_USE;
	DataItemFds[fd].ItemType = type;
    DataItemFds[fd].ItemId = id;

	mode = mode & FSM_OPEN_MODE_MASK;

	DimErrorCode = LocateDataItem(type, id, &Entry);

	if(DimErrorCode == ERR_NONE)
	{
		if((mode == FSM_OPEN_ALWAYS)
			|| (mode == FSM_OPEN_EXISTING))
		{
			DataItemFds[fd].FirstLsn = Entry.FirstLsn;
			DataItemFds[fd].ItemLength = Entry.Length;
			DataItemFds[fd].ErrorCode = ERR_NONE;

			FsmReleaseMtxSem(DataItemMtxSem); 

			DimErrorCode = ERR_NONE;
			return fd;
		}
		else if(mode == FSM_CREATE_NEW)
		{
#ifdef FSM_DEBUG
		    MonPrintf("The Data Item already exist");
#endif
			DimErrorCode = ERR_EXIST;
			goto Open_exit;
		}
		else
		{
			/* FSM_CREATE_ALWAYS is not supported ??????????? */

#ifdef FSM_DEBUG
			MonPrintf("The open mode is not supported!");
#endif

			DimErrorCode = ERR_PARAM;
			goto Open_exit;
		}
	}
	else
	{
		if(mode == FSM_OPEN_EXISTING)
		{
#ifdef FSM_DEBUG
		    MonPrintf("The Data Item not exist");
#endif
			/* DimErrorCode = ERR_NOTEXIST; */
			goto Open_exit;
		}

		/* FSM_CREATE_NEW, FSM_OPEN_ALWAYS, FSM_CREATE_ALWAYS. */
		else if(DimErrorCode == ERR_NOTEXIST) 
		{
			/* space check ,we resever one sector for create the item entry */
			SpaceAvail = DfsAvailSpaceCalc(MediaP);

			if (SpaceAvail < ACCUM_CNT_CREATE)
			{
				DimErrorCode = ERR_FULL;
				goto Open_exit;
			}

			/* add a create operation to the queue */
			DimErrorCode = QueueAddDataItem(CMD_CREATE, type, id, 0, NULL, 0);
			if (DimErrorCode != ERR_NONE)
			{
				goto Open_exit;
			}

			DataItemFds[fd].FirstLsn = -1;
			DataItemFds[fd].ItemLength = 0;
			DataItemFds[fd].ErrorCode = ERR_NONE;

			FsmReleaseMtxSem(DataItemMtxSem);

			DimErrorCode = ERR_NONE;

			return fd;
		}
	}

	/* error exit */
Open_exit:

	DataItemFds[fd].Flag = DID_FLAG_FREE;
	DataItemFds[fd].ItemType = 0;
	DataItemFds[fd].ItemId = 0;

	FsmReleaseMtxSem(DataItemMtxSem);

	return INVALID_FILE_HANDLE;
}

/*****************************************************************
 * Function Name:
 *            FsmDataItemClose
 *
 * Description  :
 *           Close an opened  data item file
 *
 * Input :
 *          Fd
 *
 * First Edit 2003.9.30 wsm
 *
 *****************************************************************/

uint32 FsmDataItemClose(uint32 ItemFd)
{
	uint32	status;

#ifdef FSM_DEBUG
	MonPrintf("Interface Data Item Close in %d \n",  __LINE__);
#endif

	if(ItemFd >= MAX_DIM_FD)
	{
		return ERR_PARAM;
	}

    /* lock the item fd structure */
	if ((status = FsmGetMtxSem(DataItemMtxSem)) != ERR_NONE)
	{
#ifdef FSM_DEBUG
		MonPrintf("Data item Lock semaphore fail! %d\n", ItemFd);
#endif
		return status;
	}

	if (DataItemFds[ItemFd].Flag == DID_FLAG_FREE)
	{
		FsmReleaseMtxSem(DataItemMtxSem);
		return ERR_PARAM;
	}

	/* free this item fd */
	DataItemFds[ItemFd].Flag = DID_FLAG_FREE;
	DataItemFds[ItemFd].ItemType = 0;
	DataItemFds[ItemFd].ItemId = 0;
	DataItemFds[ItemFd].FirstLsn = 0;
	DataItemFds[ItemFd].ItemLength = 0;
	DataItemFds[ItemFd].ErrorCode = ERR_NONE;

	FsmReleaseMtxSem(DataItemMtxSem);

	return ERR_NONE;
}

/*****************************************************************
 * Function Name:
 *           FsmDataItemRead
 *
 * Description  :
 *           Read content from an opened data item file
 *
 * Input :
 *           ItemId
 *           buffer
 *           size
 *
 * First Edit 2003.9.30 wsm
 *
 *****************************************************************/

uint32 FsmDataItemRead(uint16 type, uint16 id, uint32 offset, uint8 * buffer, uint32 size)
{
	uint32		ReadSize = 0;
	uint32		ItemLength;
	uint32		fd;
	uint16		reopen = FALSE;
	uint16		eof = FALSE;

	FsmItemDirEntryT	Entry;
	DEV_READ_FUNCPTR	DevRead;
	FsmFlashMediaT *	MediaP;

#ifdef FSM_DEBUG
	MonPrintf("Interface Data Item Read in %d \n",  __LINE__);
#endif

	/* arguments check */
	if (FsmDataItemDevObjP == NULL)
	{
		DimErrorCode = ERR_SYSTEM;
		return 0;
	}

	DevRead = FsmDataItemDevObjP->DevDrvP->FsmDevRead;
	MediaP  = (FsmFlashMediaT *)FsmDataItemDevObjP->MediaObjP;

	if (MediaP == NULL)
	{
		DimErrorCode = ERR_SYSTEM;
		return 0;
	}

	if ((type == MATCH_TYPE) || (id == MATCH_ID))
	{
		DimErrorCode = ERR_PARAM;
		return 0;
	}

	if (buffer == NULL)
	{
		DimErrorCode = ERR_PARAM;
		return 0;
	}

	if (size == 0)
	{
		DimErrorCode = ERR_NONE;
		return 0;
	}

	/* arguments check end */

    if ((DimErrorCode = FsmGetMtxSem(DataItemMtxSem)) != ERR_NONE)
	{
#ifdef FSM_DEBUG
		MonPrintf("Data item Lock semaphore fail! \n" );
#endif

		return 0;
	}

	for (fd = 0; fd < MAX_DIM_FD; fd++)
	{
		if ((DataItemFds[fd].Flag == DID_FLAG_FREE))
		{
			continue;
		}

		if ((DataItemFds[fd].ItemType == type) && (DataItemFds[fd].ItemId == id))
		{
			/* has been opened. */
			if (DataItemFds[fd].FirstLsn == (uint32)(-1))
			{
				if (DataItemFds[fd].ItemLength == 0)
				{
					/* it is an empty item */
					FsmReleaseMtxSem(DataItemMtxSem);
					DimErrorCode = ERR_EOF;

					return 0;
				}
				else
					reopen = TRUE;
			}
			else
				reopen = FALSE;

			break;
		}
	}

	/* lock the write task. */
	if ((DimErrorCode = FsmGetMtxSem(MediaP->MapTblLock)) != ERR_NONE )
	{
#ifdef FSM_DEBUG
		MonPrintf(" MapTblLock semaphore fail!\n");
#endif
		FsmReleaseMtxSem(DataItemMtxSem);

		return 0;
	}

	/* The data item is not opened or new created (without the firstlsn), so we look up in the media */
	if ((fd == MAX_DIM_FD) || (reopen == TRUE))
	{
		DimErrorCode = LocateDataItem(type, id, &Entry);

		if(DimErrorCode != ERR_NONE)
		{
			goto Read_exit;
		}

		/* if need to update the firstLsn field */
		if (reopen == TRUE)
		{
            DataItemFds[fd].FirstLsn = Entry.FirstLsn ;

⌨️ 快捷键说明

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