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

📄 fsmqueue.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 3 页
字号:
				MonPrintf("\nOops, there is a bug in Queue module!");
				return ERR_SYSTEM; /* ERROR */
			}

#endif /* DEBUG_FSM */

			FsmWriteQueue.FirstP->NextP = NewP;

			FsmWriteQueue.LastP->NextP = NewP;

			FsmWriteQueue.LastP = NewP;

			break;
		}


		/***************************************************************************************************
		 *
		 *

		 
	File Data:	0                      Offset                     Offset+Length                     End of File
		 |		!                         !        Length            !                                   |
		 |		+-------------------------|--------------------------|----------------------------+      |
		 +--->	|                         |      Append/Modify       |                            |  <---+
				|                         |     Operation in the     |                            |
				|                         |       Write Queue        |                            |
				+-------------------------|--------------------------|----------------------------+
				                          |                          |
	  CMD_MODIFY       Off                |                          |
						+-----------+     |                          |
		Case 1 ----->   |    Len    |     |                          |
						+-----------+     |                          |
						                  |                          |
					   Off		          |                          |
						+-----------------+----------------+         |
		Case 2 ----->	|		      Length               |         |
						+-----------------+----------------+         |
						                  |                          |
					   Off		          |                          |
						+-----------------+--------------------------+--------+
		Case 3 ----->	|		           Length                             |
						+-----------------+--------------------------+--------+
						                  |                          | 
										  |   Off                    |
										  |    +---------------+     |
		Case 4 -------------------------> |    |    Length     |     |
										  |    +---------------+     |
										  |                          |
										  |   Off                    |
										  |    +---------------------+----------+
		Case 5 -------------------------> |    |            Length              |
										  |    +---------------------+----------+
										  |                          |
										  |                          |      Off
										  |                          |       +-----------+
		Case 6 ---------------------------+--------------------------+--->   |   Len     |
										  |                          |       +-----------+



		****************************************************************************************************/

		/* UPDATE DATA TO EXISTED APPEND ITEMS */
		CurP = FsmWriteQueue.FirstP->NextP;
		tempDataP = DataP;
		CopyDataCnt = 0;

		for ( ; ((CurP != NULL) && (length > 0)); CurP = CurP->NextP)
		{
			if ((CurP->type != type) || (CurP->ItemFd.fd != fd))
				continue;

			if (CurP->cmd != CMD_APPEND)
				continue;

			if ((offset + length) <= CurP->offset)
			{
				/* It is the Case 1 as shown above. */

				break;
			}
			else if ((offset < CurP->offset)) /* MUST NOT use <=, the following should be executed only once. */
			{
#if 0
				if (NewP->offset == offset) /* To ensure it is the first time of running. */
					NewP->length = CurP->offset - offset;
#endif

				if ((offset + length) <= (CurP->offset + CurP->length))
				{
					/* It is the Case 2 as shown above. */

					uint32	copy_len;

					copy_len = offset + length - CurP->offset;
					FsmMemoryMove((uint8 *)(CurP + 1), tempDataP + CurP->offset - offset, copy_len);
					length -= copy_len;

					CopyDataCnt += copy_len;

					break;
				}
				else /* ((offset + length) > (CurP->offset + CurP->length)) */
				{
					/* It is the Case 3 as shown above. */

					FsmMemoryMove((uint8 *)(CurP + 1), tempDataP + CurP->offset - offset, CurP->length);
					tempDataP += CurP->offset + CurP->length - offset;
					length = (offset + length) - (CurP->offset + CurP->length);
					offset = CurP->offset + CurP->length; /* Now offset will be equal to offset of the next Append operation. */

					CopyDataCnt += CurP->length;

					continue;	/* There must be another Append operations in the write queue. */
				}
			}
			else if (offset < (CurP->offset + CurP->length))
			{
#if 0
				if (NewP->offset == offset) /* To ensure it is not from Case 3. */
					NewP->length = 0;
#endif

				if ((offset + length) <= (CurP->offset + CurP->length))
				{
					/* It is the Case 4 as shown above. */

					FsmMemoryMove(((uint8 *)(CurP + 1)) + (offset - CurP->offset), tempDataP, length);

					CopyDataCnt += length;

					length = 0;

					break;
				}
				else
				{
					/* It is the Case 5 as shown above. */

					uint32		copy_len;

					copy_len = CurP->offset + CurP->length - offset;
					FsmMemoryMove(((uint8 *)(CurP + 1)) + (offset - CurP->offset), tempDataP, copy_len);
					tempDataP += copy_len;
					offset += copy_len;
					length -= copy_len;

					CopyDataCnt += copy_len;

					continue;	/* There must be another Append operations in the write queue. */
				}
			}
			else
			{
				/* It is the Case 6 as shown above. */
			}
		}

#if 1
		NewP->length -= CopyDataCnt;
#endif

		length = NewP->length;
		offset = NewP->offset;



		/* update data to existed modify items. */
		PrevP = FsmWriteQueue.FirstP;
		CurP = PrevP->NextP;

		for ( ; ((CurP != NULL) && (length > 0)); PrevP = CurP, CurP = CurP->NextP)
		{
			if (CurP->type != type || CurP->ItemFd.fd != fd)
				continue;

			if (CurP->cmd != CMD_MODIFY)
				continue;

			if ((CurP->offset <= offset) &&
				((CurP->offset + CurP->length) >= (offset + length)))
			{
				/* It is the Case 4 as shown above. */

				FsmMemoryMove(((uint8 *)(CurP + 1)) + (offset - CurP->offset), DataP, length);

				length = 0;

				break;
			}
			else if (CurP->offset >= offset &&
				(CurP->offset + CurP->length) <= (offset + length))
			{
				/* It is the Case 3 as shown above. */

				/* Free current item from queue. */

#ifdef DEBUG_FSM
				if (FsmWriteQueue.LastP == NULL)
				{
					FsmFree((void *)NewP);
					MonPrintf("\nOops, there is a bug in Queue module!");
					return ERR_SYSTEM; /* ERROR */
				}
#endif /* DEBUG_FSM */

				/* Dequeue current item. */

				PrevP->NextP = CurP->NextP;

				if (FsmWriteQueue.LastP == CurP)
				{
					FsmWriteQueue.LastP = PrevP;
				}

				 /* 
				  * This IF may be superfluous. 
				  * Foreground API will forbid this 
				  * NewP operation to enter queue. 
				  */
				if (CurP->SemEvent != NULL) 
				{
					FsmReleaseBinSem(CurP->SemEvent);
				}

				FsmFree((void *)CurP);

				CurP = PrevP;

				FsmWriteQueue.AccumCnt -= ACCUM_CNT_MODIFY;

				continue;
			}
			else if (CurP->offset > offset &&
				CurP->offset < (offset + length) &&
				(CurP->offset + CurP->length) > (offset + length))
			{
				/* It is the Case 2 as shown above. */

				FsmMemoryMove((uint8 *)(CurP + 1), 
							  DataP + (CurP->offset - offset), 
							  offset + length - CurP->offset);

				length = CurP->offset - offset;
			}
			else if (CurP->offset < offset &&
				offset < (CurP->offset + CurP->length) &&
				(CurP->offset + CurP->length) < (offset + length))
			{
				/* It is the Case 5 as shown above. */

				uint32		copy_len;

				copy_len = CurP->offset + CurP->length - offset;

				FsmMemoryMove(((uint8 *)(CurP + 1)) + (offset - CurP->offset), 
							  DataP, 
							  copy_len);

				length -= copy_len;
				DataP  += copy_len;
				offset += copy_len;
			}
			else
			{
				/* Here are Case 1 and Case 6 as shown above. */
			}
		}

		if (length > 0)
		{
			/* if (NewP->length > length) */
			if (NewP->offset != offset)
			{
				FsmMemoryMove((uint8 *)(NewP + 1), DataP, length);
			}

			NewP->length = length;
			NewP->offset = offset;

#ifdef DEBUG_FSM

			if (FsmWriteQueue.LastP == NULL)
			{
				FsmFree((void *)NewP);
				MonPrintf("\nOops, there is a bug in Queue module!");
				return ERR_SYSTEM; /* ERROR */
			}

#endif /* DEBUG_FSM */

			FsmWriteQueue.LastP->NextP = NewP;

			FsmWriteQueue.LastP = NewP;
		}
		else
		{
			FsmFree((void *)NewP);
			FsmWriteQueue.AccumCnt -= ACCUM_CNT_MODIFY;
		}

		break;
	}

	/* UNLOCK QUEUE */
	FsmReleaseMtxSem(FsmWriteQueue.QueueMtxLock);

	return ERR_NONE;
}

/*#############################################################################
  ### QueueAddFileDir
  ###
  ### DESCRIPTION:
  ###   This function inserts a queue item whose type is file or dir
  ###   into the queue. This function allocates memory for queue
  ###   item structure and data object.
  ### PARAMETERS:
  ###    IN:  
  ###         cmd      Operation command.
  ###                  It may be the following value:
  ###                     CMD_CREATE   : Create a file
  ###                     CMD_MKDIR    : Make a directory
  ###                     CMD_MODIFY   : Modify a file
  ###                     CMD_APPEND   : Append a file
  ###                     CMD_TRUNCATE : Truncate a file
  ###                     CMD_DELETE   : Delete a file
  ###                     CMD_RMDIR    : Remove a directory
  ###                     CMD_RENAME   : Rename a file or a directory
  ###         fd       File descriptor.
  ###         offset   the number of offset bytes 
  ###                  from the beginning of file contents
  ###                  to current operation position.
  ###         DataP    Points to data object to store data.
  ###         length   Byte size of data object.
  ###         
  ###    OUT: 
  ###
  ### RETURNS:
  ###    Returns the following errors codes:
  ###         ERR_NONE
  ###         ERR_SYSTEM
  ###         ERR_MEMORY
  ###         ERR_PARAM
  ###
 */
uint32 QueueAddFileDir(
	uint8 cmd, 
	uint32 fd, 
	uint32 offset, 
	uint8 * DataP, 
	uint32 length
	)
{
	uint32					SectorSize;
	FsmDfsFileDescriptorT *	FdP;

	if ((cmd != CMD_CREATE)
		&& (cmd != CMD_MKDIR)
		&& (cmd != CMD_APPEND)
		&& (cmd != CMD_DELETE)
		&& (cmd != CMD_RMDIR)
		&& (cmd != CMD_RENAME)
		&& (cmd != CMD_MODIFY)
		&& (cmd != CMD_TRUNCATE))
	{
		return ERR_PARAM;
	}

	FdP = &FsmDfsFds[fd];
	SectorSize = ((FsmFlashMediaT*)FdP->FdHdr.DevObjP->MediaObjP)->SectorSize;

	return QueueAdd(
					QUEUE_FILE_DIR, 
					cmd, 
					fd,
					offset, 
					DataP, 
					length,
					SectorSize);
}

/*#############################################################################
  ### QueueAddDataItem
  ###
  ### DESCRIPTION:
  ###   This function inserts a queue item whose type is data item
  ###   into the queue. This function allocates memory for queue
  ###   item structure and data object.
  ###
  ### PARAMETERS:
  ###    IN:  
  ###         cmd      Operation command.
  ###                  It may be the following value:
  ###                     CMD_CREATE   : Create a data item
  ###                     CMD_MODIFY   : Modify a data item
  ###                     CMD_APPEND   : Append a data item
  ###                     CMD_DELETE   : Delete a data item
  ###         ItemType data item type;
  ###         ItemId   data item id;
  ###         offset   the number of offset bytes 
  ###                  from the beginning of data item contents
  ###                  to current operation position.
  ###         DataP    Points to data object to store data.
  ###         length   Byte size of data object.
  ###         
  ###    OUT: 
  ###
  ### RETURNS:
  ###    Returns the following errors codes:
  ###         ERR_NONE
  ###         ERR_SYSTEM
  ###         ERR_MEMORY
  ###         ERR_PARAM
  ###
 */
uint32 QueueAddDataItem(
	uint8 cmd, 
	uint16 ItemType, 
	uint16 ItemId, 
	uint32 offset, 
	uint8 * DataP, 
	uint32 length
	)
{
	uint32		SectorSize;
	FsmItemFdT	itemfd;

	itemfd.Item.ItemType = ItemType;
	itemfd.Item.ItemId = ItemId;

	if ((cmd != CMD_CREATE)
		&& (cmd != CMD_APPEND)
		&& (cmd != CMD_DELETE)
		&& (cmd != CMD_MODIFY))
	{
		return ERR_PARAM;
	}
	
	SectorSize = ((FsmFlashMediaT*)(FsmDataItemDevObjP->MediaObjP))->SectorSize;

	return QueueAdd(
					QUEUE_DATA_ITEM, 
					cmd, 
					itemfd.fd,
					offset, 
					DataP, 
					length,
					SectorSize);
}

/*#############################################################################
  ### QueuePeek
  ###
  ### DESCRIPTION:
  ###   Gets address of the first queue item.
  ###
  ### PARAMETERS:
  ###    IN:  
  ###         QueueItemPP    Points to address of the first queue item.
  ###         
  ###    OUT: 
  ###         QueueItemPP    Points to address of the first queue item.
  ###
  ### RETURNS:
  ###    Returns the following errors codes:
  ###         ERR_NONE
  ###         ERR_SYSTEM
  ###
 */
uint32 QueuePeek(FsmQueueItemT ** QueueItemPP)
{
	uint32		ret;

	if (QueueCreated == 0)
		return ERR_INIT;

	ret = FsmGetBinSem(FsmWriteQueue.SyncLock);
	if (ret != ERR_NONE)
	{
		return ret;
	}

	ret = FsmGetMtxSem(FsmWriteQueue.QueueMtxLock);
	if (ret != ERR_NONE)
	{
		return ret;
	}

	*QueueItemPP = FsmWriteQueue.FirstP;

	FsmReleaseMtxSem(FsmWriteQueue.QueueMtxLock);
	FsmReleaseBinSem(FsmWriteQueue.SyncLock);
	
	if (*QueueItemPP == NULL)
	{
		return ERR_SYSTEM;
	}
	
	return ERR_NONE;
}

/*#############################################################################
  ### QueueDel
  ###
  ### DESCRIPTION:
  ###   Delete the first item of the queue.
  ###
  ### PARAMETERS:
  ###    IN:  
  ###         
  ###    OUT: 
  ###
  ### RETURNS:
  ###    Returns the following errors codes:
  ###         ERR_NONE
  ###         ERR_SYSTEM
  ###
 */
uint32 QueueDel()
{
	uint32				ret;
	uint32				SectorSize;
	FsmQueueItemT *		CurP;
	FsmDevObjHdrT *		DevP;

	FsmDfsFileDescriptorT *	FdP;

	if (QueueCreated == 0)
		return ERR_INIT;

	ret = FsmGetMtxSem(FsmWriteQueue.QueueMtxLock);
	if (ret != ERR_NONE)
	{
		return ret;
	}

	if (FsmWriteQueue.FirstP != NULL)
	{
		/* Dequeue the first Item. */
		CurP = FsmWriteQueue.FirstP;
		FsmWriteQueue.FirstP = CurP->NextP;
		CurP->NextP = NULL;

		if (FsmWriteQueue.FirstP == NULL)
		{
#ifdef DEBUG_FSM

			/* If the tail item has already been dequeued, fails this function. */
			if ((FsmWriteQueue.LastP == NULL) || (FsmWriteQueue.LastP != CurP))
			{
				if (CurP->SemEvent != NULL)
				{
					FsmReleaseBinSem(CurP->SemEvent);
				}

				FsmFree((void *)CurP);

				MonPrintf("\nOops, there is a bug in Queue module!");

				return ERR_SYSTEM; /* ERROR */
			}

#endif /* DEBUG_FSM */

⌨️ 快捷键说明

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