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

📄 fsmdataitem.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 3 页
字号:
			ItemLength = DataItemFds[fd].ItemLength;
		}
		else
			ItemLength = Entry.Length;
	}
	else
	{
		uint32		paddr;
		uint16		sector_type;

		ItemLength = DataItemFds[fd].ItemLength;

		Entry.FirstLsn = DataItemFds[fd].FirstLsn;

        paddr = DfsLsn2Psn(MediaP, DataItemFds[fd].FirstLsn);
	    paddr = DfsPsn2Addr(MediaP, paddr); 

		if(paddr == (uint32)(-1))
		{
			DimErrorCode = ERR_EOF;
			goto Read_exit;
		}

		DimErrorCode = DevRead( FsmDataItemDevObjP,
								(uint8 *)&sector_type,
								paddr + FIELD_OFFSET(FsmFlashSectorHdrT, Type),
								FIELD_SIZE(FsmFlashSectorHdrT, Type)
								);

        if (DimErrorCode != ERR_NONE)
		{
            DataItemFds[fd].ErrorCode = DimErrorCode;
			goto Read_exit;
		}

		if (sector_type == SECTOR_TYPE_MID)
		{
			Entry.Method = METHOD_MULTI;
		}
		else if (sector_type == SECTOR_TYPE_SID)
		{
            Entry.Method = METHOD_SINGLE;
		}
		else
		{
			DataItemFds[fd].ErrorCode = ERR_FORMAT;
			goto Read_exit;
		}
	}

	/* the offset is illegal */
	if (ItemLength <= offset)
	{
		DimErrorCode = ERR_EOF;
		goto Read_exit;
	}

	/* the variable Readsize save the 'readable' content size */
    if (ItemLength < (size + offset))
    {
#ifdef FSM_DEBUG
	    MonPrintf(" You want to read too much from the data item!\n");
#endif
        size = 	ItemLength - offset;
		eof = TRUE;
    }

    if ((Entry.Method == METHOD_SINGLE) && (Entry.FirstLsn != (uint32)(-1)))
    {
		DimErrorCode = ReadSingleInstance(Entry.FirstLsn, offset, buffer, size, &ReadSize);
    }
    else if (Entry.Method  == METHOD_MULTI)
    {
		/* Read the multi instance content */
		DimErrorCode = ReadMultInstance(Entry.FirstLsn, offset, buffer, size, &ReadSize);
    }


	if ((DimErrorCode != ERR_NONE) && (DimErrorCode != ERR_EOF))
	{
		if ((reopen == TRUE) || (fd < MAX_DIM_FD))
		{
			DataItemFds[fd].ErrorCode = DimErrorCode;
		}

		ReadSize = 0;

		goto Read_exit;
	}

    /* merge the content in the queue */
    DimErrorCode = QueueReadDataItem(type, id, offset, buffer, size, &ReadSize);

	if((DimErrorCode == ERR_NONE) && (eof == TRUE))
	{
		DimErrorCode = ERR_EOF;
	}

    if ((reopen == TRUE) || (fd < MAX_DIM_FD))
	{
		DataItemFds[fd].ErrorCode = DimErrorCode;
	}

Read_exit:

	FsmReleaseMtxSem(MediaP->MapTblLock);
    FsmReleaseMtxSem(DataItemMtxSem);

    return ReadSize;
}

/*****************************************************************
 * Function Name:
 *           FsmDataItemWrite
 *
 * Description  :
 *           Write content to an opened data item file
 *
 * Input :
 *           ItemId
 *           buffer
 *           size
 *
 * First Edit 2003.9.30 wsm
 *
 *****************************************************************/

uint32 FsmDataItemWrite(uint16 type, uint16 id, uint32 offset, uint8 * buffer, uint32 size)
{
	uint32		fd;
	uint16		open_here;
	uint32		append_size;
	uint32		modify_size;

	uint32		SpaceReq;
	uint32		SpaceAvail;
	uint32		ItemLength;

	FsmFlashMediaT *	MediaP;

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

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

	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;
	}

	/* lock the data item interface */
	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))
		{
			break;
		}
	}

	/* The data item is not opened , so we look up in the media */
	if (fd == MAX_DIM_FD)
	{
		fd = (uint16)FsmDataItemOpen (type, id, FSM_OPEN_ALWAYS);

		if (fd == INVALID_FILE_HANDLE)
		{
			/* Can not create the item */
			FsmReleaseMtxSem(DataItemMtxSem);

			return 0;
		}

		open_here = TRUE;
	}
	else
	{
		open_here = FALSE;
	}

	ItemLength = DataItemFds[fd].ItemLength;

	/* the offset is illegal. Notice the new item may be created! */
	if (ItemLength < offset)
	{
		DimErrorCode = ERR_PARAM;

		goto Write_exit;
	}

	append_size = 0;
	modify_size = 0;

	if ((offset + size) > ItemLength)
	{
		append_size = offset + size - ItemLength;
		modify_size = ItemLength - offset;
	}
	else
	{
		modify_size = size;
	}

	/* space check */
	SpaceReq = 0;

	if(modify_size > 0)
	{
		SpaceReq += ACCUM_CNT_MODIFY;

		SpaceReq += ACCUM_CNT_MODIFY_RESERVED(offset, modify_size, MediaP->SectorSize);
	}

	if(append_size > 0)
	{
		SpaceReq += ACCUM_CNT_APPEND(ItemLength, append_size, MediaP->SectorSize);
	}

	SpaceAvail = DfsAvailSpaceCalc(MediaP);

	if (SpaceReq > SpaceAvail)
	{
		DimErrorCode = ERR_FULL;

		goto Write_exit;
	}

	if(modify_size > 0)
	{
		DimErrorCode = QueueAddDataItem(CMD_MODIFY, type, id, offset, buffer, modify_size);

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

	if(append_size > 0)
	{
		DimErrorCode = QueueAddDataItem(CMD_APPEND, 
										type, 
										id,
										offset + modify_size, 
										(uint8 *)buffer + modify_size, 
										append_size
										);
	}

	if (DimErrorCode == ERR_NONE)
	{
		DataItemFds[fd].ItemLength += append_size;
	}

Write_exit:

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

	if (open_here == FALSE)
	{
		DataItemFds[fd].ErrorCode = DimErrorCode;
	}
	else
	{
		/* We open the item */
		FsmDataItemClose(fd);
	}

	FsmReleaseMtxSem(DataItemMtxSem);

	return size;                         
}

/*****************************************************************
 * Function Name:
 *           FsmDataItemDelete
 *
 * Description  :
 *           Delete an item
 *
 * Input :
 *           Type
 *           Id
 *
 * First Edit 2003.9.30 wsm
 *
 *****************************************************************/

uint32 FsmDataItemDelete(uint16 type, uint16 id)
{
	uint32			status;
	uint32			fd;

	FsmItemDirEntryT	Entry;

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

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

	if ((status = FsmGetMtxSem(DataItemMtxSem)) != ERR_NONE)
	{
#ifdef FSM_DEBUG
		MonPrintf("DataItemLock semaphore fail!");
#endif
		return status;
	}

	/* Check if the datatiem 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))
		{
#ifdef FSM_DEBUG
			MonPrintf("The Data Item is in use.");
#endif
			FsmReleaseMtxSem(DataItemMtxSem);

    		return ERR_ACCESS_DENY;
		}
	}

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

	if(status != ERR_NONE)
	{
		FsmReleaseMtxSem(DataItemMtxSem);

		return status; /* ERR_NOTEXIST; */
	}

	/* add a delete command into the queue */
	status = QueueAddDataItem(CMD_DELETE, type, id, 0, NULL, 0);

	if(status == ERR_NONE)
	{
		status = WaitTypeIdEmpty(type, id, WAIT_FOREVER);
	}

	FsmReleaseMtxSem(DataItemMtxSem);

	return status;
}

/*****************************************************************
 * Function Name:
 *           FsmDataItemFindFirst
 *
 * Description  :
 *           Write content to an opened data item file
 *
 * Input :
 *           Type
 *           Info
 *
 * First Edit 2003.9.30 wsm
 *  The queue should be flushed first for exactly searching.
 *****************************************************************/

uint32 FsmDataItemFindFirst(uint16 type, uint16 id, FsmItemInfoT * Info )
{
	uint8		found;
	uint32		fd;
	uint32		Lsn;
	uint32		EntryCount;

	FsmItemDirEntryT	Entry;
	FsmFlashMediaT *	MediaP;

#ifdef FSM_DEBUG
	MonPrintf("Enter interface Find First Data Item in %d \n", __LINE__);
#endif

	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 ((DimErrorCode = FsmGetMtxSem(DataItemMtxSem)) != ERR_NONE)
	{
#ifdef FSM_DEBUG
		MonPrintf("DataItemLock semaphore fail!");
#endif
		return INVALID_FILE_HANDLE;
	}

	/* Check if the datatiem in using */
	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
		FsmReleaseMtxSem(DataItemMtxSem);
		DimErrorCode = ERR_MAX_OPEN;

		return INVALID_FILE_HANDLE;
	}

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


	/* lock the write process and the reclaim */
	if ((DimErrorCode = FsmGetMtxSem(MediaP->MapTblLock)) != ERR_NONE )
	{
#ifdef FSM_DEBUG
		MonPrintf(" MapTblLock semaphore fail!\n");
#endif
		/* free the fd */
		DataItemFds[fd].ItemType = 0;
		DataItemFds[fd].ItemId = 0;
		DataItemFds[fd].Flag = DID_FLAG_FREE;

		FsmReleaseMtxSem(DataItemMtxSem);

		return INVALID_FILE_HANDLE;
	}

	/* look up the data item on flash */

	/* the default lsn and the start entry count */
	Lsn = 1;
	EntryCount = 0;

	found = FALSE;

	while((DimErrorCode = ReadDataItemEntry(&Lsn, &EntryCount, &Entry)) == ERR_NONE)
	{
		if ((type == MATCH_TYPE) && (id == MATCH_ID))
		{
    		found = TRUE;
		}
		else if ((type == MATCH_TYPE) && (id == Entry.ItemId ))
		{  
    		found = TRUE;
		}
		else if ((type == Entry.ItemType ) && (id == MATCH_ID))
		{
    		found = TRUE;
		}
		else if ((type == Entry.ItemType ) && (id == Entry.ItemId ))
		{
    		found = TRUE;
		}
		else
		{
    		found = FALSE;
			continue;
		}

    	Info->ItemType = Entry.ItemType ;
    	Info->ItemId = Entry.ItemId ;
    	Info->ItemLength = Entry.Length ;
    	Info->Attrib = Entry.Type ;
    	Info->Method = Entry.Method;    

		/* we save the lsn in Firstlsn and the entry count in ItemLength */
    	DataItemFds[fd].FirstLsn = Lsn;
		DataItemFds[fd].ItemLength = EntryCount;

    	break;
	}

	if (found == FALSE)
	{
		/* free the fd */
		DataItemFds[fd].ItemType = 0;
		DataItemFds[fd].ItemId = 0;
		DataItemFds[fd].Flag = DID_FLAG_FREE;

		fd  = INVALID_FILE_HANDLE;
	}

	FsmReleaseMtxSem(MediaP->MapTblLock);

	FsmReleaseMtxSem(DataItemMtxSem);

⌨️ 快捷键说明

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