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

📄 fsmwritetask.c

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

	temp = ItemP->offset / MediaObjP->SectorSize;

	while(temp > 0)
	{
		OldPsn = DfsLsn2Psn(MediaObjP, lsn);
		OldSectorAddr = DfsPsn2Addr(MediaObjP, OldPsn);

		ret  =  DevRead( DevP, 
						 (uint8 *)&lsn,
						 OldSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
						 FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
						 );

		if(ret != ERR_NONE)
			return ret;

		temp--;
	}

	RemainLen = ItemP->length;
	WriteOffset = ItemP->offset % MediaObjP->SectorSize;

	while (RemainLen > 0)
	{
		OldPsn = DfsLsn2Psn(MediaObjP, lsn);
		OldSectorAddr = DfsPsn2Addr(MediaObjP, OldPsn);

		ret = GetFreePsn(DevP, &NewPsn);
		if (ret != ERR_NONE)
		{
			return ret;
		}

		NewSectorAddr = DfsPsn2Addr(MediaObjP, NewPsn);

		/* New sector state to writing */
		SectorHdr.Status = SECTOR_WRITING;
		ret = DevWrite( DevP, 
						(uint8 *)&SectorHdr.Status, 
						NewSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
						FIELD_SIZE(FsmFlashSectorHdrT, Status)
						);

		if(ret != ERR_NONE)
			return ret;

		/* Read Old sector header information. */
		ret  =  DevRead( DevP,
						 (uint8 *)&SectorHdr, 
						 OldSectorAddr, 
						 sizeof(FsmFlashSectorHdrT)
						 );

		if(ret != ERR_NONE)
			return ret;

		SectorHdr.Status = SECTOR_WRITING;
		ret = DevWrite( DevP,
						(uint8 *)&SectorHdr,
						NewSectorAddr,
						sizeof(FsmFlashSectorHdrT)
						);

		if(ret != ERR_NONE)
			return ret;

		if (WriteOffset > 0)
		{
			ret =  DevCopy( DevP,
							NewSectorAddr + sizeof(FsmFlashSectorHdrT), 
							OldSectorAddr + sizeof(FsmFlashSectorHdrT), 
							WriteOffset
							);

			if(ret != ERR_NONE)
				return ret;
		}

		if (RemainLen < (MediaObjP->SectorSize - WriteOffset))
		{
			WriteLen = RemainLen;

			ret = DevWrite( DevP, 
							DataP, 
							NewSectorAddr + sizeof(FsmFlashSectorHdrT) + WriteOffset, 
							WriteLen
							);

			if(ret != ERR_NONE)
				return ret;

			WriteOffset += WriteLen;

			ret =  DevCopy( DevP,
							NewSectorAddr + sizeof(FsmFlashSectorHdrT) + WriteOffset,
							OldSectorAddr + sizeof(FsmFlashSectorHdrT) + WriteOffset,
							MediaObjP->SectorSize - WriteOffset
							);

			if(ret != ERR_NONE)
				return ret;

			RemainLen = 0;
		}
		else
		{
			WriteLen = MediaObjP->SectorSize - WriteOffset;

			ret = DevWrite( DevP,
							DataP,
							NewSectorAddr + sizeof(FsmFlashSectorHdrT) + WriteOffset,
							WriteLen
							);

			if(ret != ERR_NONE)
				return ret;

			RemainLen -= WriteLen;
			WriteOffset = 0;

			DataP = &DataP[WriteLen];
		}

		if (FsmGetMtxSem(MediaObjP->MapTblLock) != ERR_NONE)
		{
			return ERR_SYSTEM;
		}
		MediaObjP->Lsn2PsnP[lsn] = NewPsn;
		if (FsmReleaseMtxSem(MediaObjP->MapTblLock) != ERR_NONE)
		{
			return ERR_SYSTEM;
		}

		/* new sector state to updating */
		SectorHdr.Status = SECTOR_UPDATING;
		ret = DevWrite( DevP,
						(uint8 *)&SectorHdr.Status,
						NewSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
						FIELD_SIZE(FsmFlashSectorHdrT, Status)
						);

		if(ret != ERR_NONE)
			return ret;

		/* old sector state to deleting */
		SectorHdr.Status = SECTOR_DELETING;
		ret = DevWrite( DevP, 
						(uint8 *)&SectorHdr.Status, 
						OldSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status), 
						FIELD_SIZE(FsmFlashSectorHdrT, Status)
						);	

		if(ret != ERR_NONE)
			return ret;

		/* new sector state to valid */
		SectorHdr.Status = SECTOR_VALID;
		ret = DevWrite( DevP,
						(uint8 *)&SectorHdr.Status,
						NewSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
						FIELD_SIZE(FsmFlashSectorHdrT, Status)
						);

		if(ret != ERR_NONE)
			return ret;

		/* old sector state to invalid */
		SectorHdr.Status = SECTOR_INVALID;
		ret = DevWrite( DevP,
						(uint8 *)&SectorHdr.Status,
						OldSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
						FIELD_SIZE(FsmFlashSectorHdrT, Status)
						);

		if(ret != ERR_NONE)
			return ret;

		BlkNum = (uint16)(OldPsn / MediaObjP->SectorsPerBlock);

		if (FsmGetMtxSem(MediaObjP->InfoLock) != ERR_NONE)
		{
			return ERR_SYSTEM;
		}
		MediaObjP->BlockInfoP[BlkNum].DirtySectors += 1;
		MediaObjP->BlockInfoP[BlkNum].UsedSectors -= 1;
		if (FsmReleaseMtxSem(MediaObjP->InfoLock) != ERR_NONE)
		{
			return ERR_SYSTEM;
		}

		ret  =  DevRead( DevP,
						 (uint8 *)&lsn,
						 OldSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
						 FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
						 );

		if(ret != ERR_NONE)
			return ret;
	}

	return ERR_NONE;
}

static uint32 SingleInstanceAppend(
	FsmQueueItemT * ItemP,
	FsmDevObjHdrT * DevP,
	FsmDfsFileDescriptorT * FdP
	)
{
	uint8				method;
	uint8				MultiInstStatus;

	FsmFlashSectorHdrT	SectorHdr;

	uint32				temp;
	uint32				ret;
	uint32				length;
	uint32				StartLsn;
	uint16				BlkNum;
	uint32				CopyOffset;
	uint32				lsn;
	uint32				NextLsn;
	uint32				NewPsn, OldPsn;
	uint32				NewEntryAddr, OldEntryAddr;
	uint32				NewSectorAddr, OldSectorAddr;

	uint8 *				DataP = (uint8 *)(ItemP + 1);

	FsmFlashMediaT *	MediaObjP = (FsmFlashMediaT * )DevP->MediaObjP;

	DEV_COPY_FUNCPTR	DevCopy = DevP->DevDrvP->FsmDevCopy;
	DEV_WRITE_FUNCPTR	DevWrite = DevP->DevDrvP->FsmDevWrite;
	DEV_READ_FUNCPTR	DevRead = DevP->DevDrvP->FsmDevRead;

	/*
	 * GetFreeEntry must be called prior to GetValidEntry,
	 * or the entry address and index returned from GetValidEntry
	 * may be invalid after calling GetFreeEntry, because 
	 * GetFreeEntry will reclaim a certain dirty sector if there 
	 * is no free entry that may have been returned in the 
	 * calling to GetValidEntry.
	 * 
	 */
	ret = GetFreeEntry(ItemP, &NewEntryAddr);
	if (ret != ERR_NONE)
	{
		return ret;
	}

	ret = GetValidEntry(ItemP, &OldEntryAddr);
	if (ret != ERR_NONE)
	{
		return ret;
	}

	if (ItemP->type == QUEUE_FILE_DIR)
	{
		method = METHOD_SINGLE;
		StartLsn = FdP->FirstLsn;
	}
	else
	{
		ret  =  DevRead( DevP,
						 (uint8 *)&StartLsn,
						 OldEntryAddr + FIELD_OFFSET(FsmItemDirEntryT, FirstLsn),
						 FIELD_SIZE(FsmItemDirEntryT, FirstLsn)
						 );

		if(ret != ERR_NONE)
			return ret;

		ret  =  DevRead( DevP,
						 (uint8 *)&method, 
						 OldEntryAddr + FIELD_OFFSET(FsmItemDirEntryT, Method),
						 FIELD_SIZE(FsmItemDirEntryT, Method)
						 );

		if(ret != ERR_NONE)
			return ret;
	}

	lsn = StartLsn;

	while (TRUE)
	{
		OldPsn = DfsLsn2Psn(MediaObjP, lsn);
		OldSectorAddr = DfsPsn2Addr(MediaObjP, OldPsn);

		ret  =  DevRead( DevP,
						 (uint8 *)&lsn,
						 OldSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
						 FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
						 );

		if(ret != ERR_NONE)
			return ret;

		if (lsn == (uint32)(-1))
		{
			break;
		}
		StartLsn = lsn;
	}

	lsn = StartLsn;

	ret = GetFreePsn(DevP, &NewPsn);

	if (ret != ERR_NONE)
	{
		return ret;
	}

	NewSectorAddr = DfsPsn2Addr(MediaObjP, NewPsn);

	/* new sector state to writing */
	SectorHdr.Status = SECTOR_WRITING;
	ret = DevWrite( DevP,
					(uint8 *)&SectorHdr.Status,
					NewSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
					FIELD_SIZE(FsmFlashSectorHdrT, Status)
					);

	if(ret != ERR_NONE)
		return ret;

	if (method == METHOD_SINGLE)
	{
		CopyOffset = 0;
	}
	else
	{
		uint16		i;
		uint16		Instances;

		temp = MediaObjP->SectorSize - FIELD_SIZE(FsmMultiInstanceT, Length);
		Instances = (uint16)(temp / (ItemP->offset + FIELD_SIZE(FsmMultiInstanceT, Status)));

		for (i = 0; i < Instances; i++)
		{
			MultiInstStatus = 0;

			ret  =  DevRead( DevP,
							 (uint8 *)&MultiInstStatus,
							 OldSectorAddr + sizeof(FsmFlashSectorHdrT)			\
								+ FIELD_OFFSET(FsmMultiInstanceT, Status[0])		\
								+ i * FIELD_SIZE(FsmMultiInstanceT, Status),
							 FIELD_SIZE(FsmMultiInstanceT, Status)
							 );

			if(ret != ERR_NONE)
				return ret;

			if (MultiInstStatus == INSTANCE_VALID)
			{
				break;
			}
		}

		if(i >= Instances)
			return ERR_SYSTEM;	/* ERR_FORMAT; */

		CopyOffset = Instances * FIELD_SIZE(FsmMultiInstanceT, Status);
		CopyOffset += FIELD_SIZE(FsmMultiInstanceT, Length);
		CopyOffset += i * ItemP->offset;
	}

	length = ItemP->length;

	temp = ItemP->offset % MediaObjP->SectorSize;

	if (temp > 0)
	{
		/* Copy data from old sector to the new sector. */
		ret = DevCopy( DevP,
						NewSectorAddr + sizeof(FsmFlashSectorHdrT),
						OldSectorAddr + sizeof(FsmFlashSectorHdrT) + CopyOffset,
						temp
						);

		if(ret != ERR_NONE)
			return ret;

		if (length <= (MediaObjP->SectorSize - temp))
		{
			ret = DevWrite( DevP,
							DataP,
							NewSectorAddr + sizeof(FsmFlashSectorHdrT) + temp, 
							length
							);

			if(ret != ERR_NONE)
				return ret;

			length = 0;
		}
		else
		{
			ret = DevWrite( DevP,
							DataP,
							NewSectorAddr + sizeof(FsmFlashSectorHdrT) + temp, 
							MediaObjP->SectorSize - temp
							);

			if(ret != ERR_NONE)
				return ret;

			length -= (MediaObjP->SectorSize - temp);
			DataP  += (MediaObjP->SectorSize - temp);
			/* DataP = &DataP[MediaObjP->SectorSize - temp]; */
		}
	}
	else
	{
		ret =  DevCopy( DevP,
						NewSectorAddr + sizeof(FsmFlashSectorHdrT),
						OldSectorAddr + sizeof(FsmFlashSectorHdrT) + CopyOffset,
						MediaObjP->SectorSize
						);

		if(ret != ERR_NONE)
			return ret;
	}

	SectorHdr.Status = SECTOR_WRITING;
	SectorHdr.Type   = SECTOR_TYPE_SID;
	SectorHdr.Lsn    = StartLsn;

	if(length > 0)
	{
		ret = GetFreeLsn(DevP, &NextLsn);
		if (ret != ERR_NONE)
		{
			return ret;
		}

		SectorHdr.NextLsn = NextLsn;
	}
	else
	{
		SectorHdr.NextLsn = (uint32)(-1);
	}

	ret = DevWrite( DevP,
					(uint8 *)&SectorHdr,
					NewSectorAddr,
					sizeof(FsmFlashSectorHdrT)
					);

	if(ret != ERR_NONE)
		return ret;

	if (FsmGetMtxSem(MediaObjP->MapTblLock) != ERR_NONE)
	{
		return ERR_SYSTEM;
	}
	/* Update map information. */
	MediaObjP->Lsn2PsnP[StartLsn] = NewPsn;
	if (FsmReleaseMtxSem(MediaObjP->MapTblLock) != ERR_NONE)
	{
		return ERR_SYSTEM;
	}


	for ( lsn = NextLsn; length > 0; lsn = NextLsn)
	{
		ret = GetFreePsn(DevP, &NewPsn);
		if (ret != ERR_NONE)
		{
			return ret;
		}

		NewSectorAddr = DfsPsn2Addr(MediaObjP, NewPsn);

		/* New sector state to writing. */
		SectorHdr.Status = SECTOR_WRITING;
		ret = DevWrite( DevP,
						(uint8 *)&SectorHdr.Status,
						NewSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status), 
						FIELD_SIZE(FsmFlashSectorHdrT, Status)
						);

		if(ret != ERR_NONE)
			return ret;

		if (length <= MediaObjP->SectorSize)
		{
			NextLsn = (uint32)(-1);

			ret = DevWrite( DevP,
							DataP,
							NewSectorAddr + sizeof(FsmFlashSectorHdrT),
							length
							);

			if(ret != ERR_NONE)
				return ret;

			length = 0;
		}
		else
		{
			ret = DevWrite( DevP, 
							DataP, 
							NewSectorAddr + sizeof(FsmFlashSectorHdrT), 
							MediaObjP->SectorSize
							);

			if(ret != ERR_NONE)
				return ret;

			length -= MediaObjP->SectorSize;
			DataP  += MediaObjP->SectorSize;

			/* DataP = &DataP[MediaObjP->SectorSize]; */
		}

		SectorHdr.Status  = SECTOR_WRITING;
		SectorHdr.Type    = SECTOR_TYPE_SID;
		SectorHdr.Lsn     = lsn;
		SectorHdr.NextLsn = (uint32)(-1);

		ret = DevWrite( DevP,
						(uint8 *)&SectorHdr,
						NewSectorAddr,
						sizeof(FsmFlashSectorHdrT)
						);

		if(ret != ERR_NONE)
			return ret;

		if (FsmGetMtxSem(MediaObjP->MapTblLock) != ERR_NONE)
		{
			return ERR_SYSTEM;
		}
		/* Update the Map table,so the subsequent */
		/* call to GetFreeLsn will not return value of this lsn. */
		MediaObjP->Lsn2PsnP[lsn] = NewPsn;
		if (FsmReleaseMtxSem(MediaObjP->MapTblLock) != ERR_NONE)
		{
			return ERR_SYSTEM;
		}

		if (length > 0)
		{
			ret = GetFreeLsn(DevP, &NextLsn);
			if (ret != ERR_NONE)
			{
				return ret;
			}

			SectorHdr.NextLsn = NextLsn;

			ret = DevWrite( DevP,
							(uint8 *)&SectorHdr.NextLsn,
							NewSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
							FIELD_SIZE(

⌨️ 快捷键说明

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