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