📄 fsmwritetask.c
字号:
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 + -