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

📄 fsmwritetask.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 5 页
字号:
	ret = DevWrite( DevP,
					(uint8 *)&ItemEntry,
					NewEntryAddr, 
					sizeof(FsmItemDirEntryT)
					);

	if(ret != ERR_NONE)
		return ret;

	/* entry state to allocated */
	ItemEntry.Status = ENTRY_ALLOCATED;
	ret = DevWrite( DevP, 
					(uint8 *)&ItemEntry.Status, 
					NewEntryAddr + FIELD_OFFSET(FsmItemDirEntryT, Status), 
					FIELD_SIZE(FsmItemDirEntryT, 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;

	/* entry state to valid */
	ItemEntry.Status = ENTRY_VALID;
	ret = DevWrite( DevP, 
					(uint8 *)&ItemEntry.Status, 
					NewEntryAddr + FIELD_OFFSET(FsmItemDirEntryT, Status), 
					FIELD_SIZE(FsmItemDirEntryT, Status)
					);

	if(ret != ERR_NONE)
		return ret;

	return ERR_NONE;
}

static uint32 MultiInstanceAppend(
	FsmQueueItemT * ItemP, 
	FsmDevObjHdrT * DevP)
{
	uint32				temp;
	uint32				ret;
	uint8				MultiInstStatus;
	uint16				BlkNum;
	uint16				InstIndex;

	uint32				OldLsn, OldPsn;
	uint32				NewPsn;
	uint32				NewWriteOffset, OldWriteOffset;
	uint32				OldEntryAddr;
	uint32				NewEntryAddr;
	uint32				NewSectorAddr, OldSectorAddr;

	FsmFlashSectorHdrT	SectorHdr;
	FsmItemDirEntryT	ItemEntry;

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

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

	NewSectorAddr = DfsPsn2Addr(MediaObjP, NewPsn);

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

	if(ret != ERR_NONE)
		return ret;

	OldPsn = DfsLsn2Psn(MediaObjP, OldLsn);
	OldSectorAddr = DfsPsn2Addr(MediaObjP, OldPsn);

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

	if(ret != ERR_NONE)
		return ret;

	/* 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;

	/* write new sector informatiom. */
	ret = DevWrite( DevP, 
					(uint8 *)&SectorHdr, 
					NewSectorAddr, 
					sizeof(FsmFlashSectorHdrT)
					);

	if(ret != ERR_NONE)
		return ret;

	/* New instance status. */
	MultiInstStatus = INSTANCE_VALID;
	ret = DevWrite( DevP, 
					(uint8 *)&MultiInstStatus,
					NewSectorAddr + sizeof(FsmFlashSectorHdrT) 
						+ FIELD_OFFSET(FsmMultiInstanceT, Status[0]),
					FIELD_SIZE(FsmMultiInstanceT, Status)
					);

	if(ret != ERR_NONE)
		return ret;
	
	InstIndex = 0;

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

	/* temp is the total number of instances. */
	while (InstIndex < (uint16)temp)
	{
		MultiInstStatus = 0;

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

		if(ret != ERR_NONE)
			return ret;

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

	if (InstIndex >= (uint16)temp)
		return ERR_SYSTEM; /* ERR_FORMAT; */

	temp = MediaObjP->SectorSize - FIELD_SIZE(FsmMultiInstanceT, Length);

	/* ItemP->offset must be equal to instance data length. */
	temp = temp / (ItemP->offset + FIELD_SIZE(FsmMultiInstanceT, Status));
	temp = temp * FIELD_SIZE(FsmMultiInstanceT, Status);

	OldWriteOffset = temp + FIELD_SIZE(FsmMultiInstanceT, Length)
						+ InstIndex * ItemP->offset;

	temp = MediaObjP->SectorSize - FIELD_SIZE(FsmMultiInstanceT, Length);

	temp = temp / (ItemP->offset + ItemP->length + FIELD_SIZE(FsmMultiInstanceT, Status));
	temp = temp * FIELD_SIZE(FsmMultiInstanceT, Status);

	NewWriteOffset = temp  +  FIELD_SIZE(FsmMultiInstanceT, Length);

	/* Copy original data to new sector. */
	ret =  DevCopy( DevP, 
					NewSectorAddr + sizeof(FsmFlashSectorHdrT) + NewWriteOffset, 
					OldSectorAddr + sizeof(FsmFlashSectorHdrT) + OldWriteOffset, 
					ItemP->offset
					);

	if(ret != ERR_NONE)
		return ret;

	NewWriteOffset += ItemP->offset;

	/* Write appended data to new sector. */
	ret = DevWrite( DevP, 
					(uint8 *)(ItemP + 1), 
					NewSectorAddr + sizeof(FsmFlashSectorHdrT) + NewWriteOffset, 
					ItemP->length
					);

	if(ret != ERR_NONE)
		return ret;

	/* write instance length into sector. */
	InstIndex = (uint16)(ItemP->length + ItemP->offset);
	ret = DevWrite( DevP, 
					(uint8 *)&InstIndex, 
					NewSectorAddr + sizeof(FsmFlashSectorHdrT)	\
						+ FIELD_OFFSET(FsmMultiInstanceT, Length), 
					FIELD_SIZE(FsmMultiInstanceT, Length)
					);

	if(ret != ERR_NONE)
		return ret;

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

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

	if(ret != ERR_NONE)
		return ret;

	/* Red old entry information. */
	ret  =  DevRead( DevP, 
					 (uint8 *)&ItemEntry, 
					 OldEntryAddr, 
					 sizeof(FsmItemDirEntryT)
					 );

	if(ret != ERR_NONE)
		return ret;

	/* new entry state to writing */
	ItemEntry.Status = ENTRY_WRITING;
	ret = DevWrite( DevP,
					(uint8 *)&ItemEntry.Status, 
					NewEntryAddr + FIELD_OFFSET(FsmItemDirEntryT, Status),
					FIELD_SIZE(FsmItemDirEntryT, Status)
					);

	if(ret != ERR_NONE)
		return ret;

	ItemEntry.Status = ENTRY_WRITING;
	ItemEntry.Length = ItemP->length + ItemP->offset;

	ret = DevWrite( DevP, 
					(uint8 *)&ItemEntry,
					NewEntryAddr,
					sizeof(FsmItemDirEntryT)
					);

	if(ret != ERR_NONE)
		return ret;

	/* new entry state to updating */
	ItemEntry.Status = ENTRY_UPDATING;
	ret = DevWrite( DevP,
					(uint8 *)&ItemEntry.Status, 
					NewEntryAddr + FIELD_OFFSET(FsmItemDirEntryT, Status),
					FIELD_SIZE(FsmItemDirEntryT, 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;

	/* old entry state to invalid */
	ItemEntry.Status = ENTRY_INVALID;
	ret = DevWrite( DevP, 
					(uint8 *)&ItemEntry.Status, 
					OldEntryAddr + FIELD_OFFSET(FsmItemDirEntryT, Status), 
					FIELD_SIZE(FsmItemDirEntryT, Status)
					);

	if(ret != ERR_NONE)
		return ret;

	/* new entry state to valid */
	ItemEntry.Status = ENTRY_VALID;
	ret = DevWrite( DevP,
					(uint8*)&ItemEntry.Status,
					NewEntryAddr + FIELD_OFFSET(FsmItemDirEntryT, Status), 
					FIELD_SIZE(FsmItemDirEntryT, Status)
					);


	if(ret != ERR_NONE)
		return ret;

	/* updating block info */
	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;
	}

	return ERR_NONE;
}

static uint32 MultiInstanceModify(
	FsmQueueItemT * ItemP, 
	FsmDevObjHdrT * DevP)
{
	uint32				temp;
	uint32				ret;
	uint16				len;

	uint8				MultiInstStatus;
	uint16				InstIndex, Instances, BlkNum;
/*	uint16				NewFreeInstIndex; */

	uint32				lsn;
	uint32				NewWriteOffset, OldWriteOffset;
	uint32				NewSectorAddr, OldSectorAddr;
	uint32				NewPsn, OldPsn;

	uint32				OldEntryAddr;

	FsmFlashSectorHdrT	SectorHdr;

	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;

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

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

	if(ret != ERR_NONE)
		return ret;

	OldPsn = DfsLsn2Psn(MediaObjP, lsn);
	OldSectorAddr = DfsPsn2Addr(MediaObjP, OldPsn);

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

	if(ret != ERR_NONE)
		return ret;

	len = (uint16)temp;

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

	temp = OldSectorAddr + sizeof(FsmFlashSectorHdrT)		\
				+ FIELD_OFFSET(FsmMultiInstanceT, Status[0]);

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

		ret  =  DevRead( DevP, 
						 (uint8 *)&MultiInstStatus,
						 temp + InstIndex * FIELD_SIZE(FsmMultiInstanceT, Status), 
						 FIELD_SIZE(FsmMultiInstanceT, Status)
						 );

		if(ret != ERR_NONE)
			return ret;

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

	if (InstIndex >= Instances)
	{
		return ERR_SYSTEM;	/* ERR_FORMAT; */
	}

	if (InstIndex == (Instances - 1))
	{

Modify_Allocate_New:

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

		NewSectorAddr = DfsPsn2Addr(MediaObjP, NewPsn);

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

		if(ret != ERR_NONE)
			return ret;

		/* 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;

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

		if(ret != ERR_NONE)
			return ret;

		/* write instance length. */
		ret = DevWrite( DevP,
						(uint8 *)&len,
						NewSectorAddr + sizeof(FsmFlashSectorHdrT) + FIELD_OFFSET(FsmMultiInstanceT, Length), 
						FIELD_SIZE(FsmMultiInstanceT, Length)
						);

		if(ret != ERR_NONE)
			return ret;

		/* write instance state to valid. */
		MultiInstStatus = INSTANCE_VALID;
		ret = DevWrite( DevP, 
						(uint8 *)&MultiInstStatus, 
						NewSectorAddr + sizeof(FsmFlashSectorHdrT) + FIELD_OFFSET(FsmMultiInstanceT, Status[0]), 
						FIELD_SIZE(FsmMultiInstanceT, Status)
						);

		if(ret != ERR_NONE)
			return ret;

		NewWriteOffset = FIELD_SIZE(FsmMultiInstanceT, Length) 
							+ Instances * FIELD_SIZE(FsmMultiInstanceT, Status);

		OldWriteOffset = NewWriteOffset + InstIndex * len;

		/* copy data to the top of new instance. */
		ret =  DevCopy( DevP,
						NewSectorAddr + sizeof(FsmFlashSectorHdrT) + NewWriteOffset, 
						OldSectorAddr + sizeof(FsmFlashSectorHdrT) + OldWriteOffset,
						ItemP->offset /* ItemP->offset >= 0*/
						);

		if(ret != ERR_NONE)
			return ret;

		NewWriteOffset += ItemP->offset;
		OldWriteOffset += ItemP->offset;

		/* write modified data to new instance. */
		ret = DevWrite( DevP, 
						(uint8 *)(ItemP + 1), 
						NewSectorAddr + sizeof(FsmFlashSectorHdrT) + NewWriteOffset, 
						ItemP->length
						);

		if(ret != ERR_NONE)
			return ret;

		NewWriteOffset += ItemP->length;
		OldWriteOffset += ItemP->length;

		/* copy the remained data to the new instance. */
		ret =  DevCopy( DevP,
						NewSectorAddr + sizeof(FsmFlashSectorHdrT) + NewWriteOffset,
						OldSectorAddr + sizeof(FsmFlashSectorHdrT) + OldWriteOffset,
						len - (ItemP->offset + ItemP->length) 
						/* for modify len >= (ItemP->offset + ItemP->length)*/

⌨️ 快捷键说明

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