📄 fsmwritetask.c
字号:
(uint8 *)&SectorStatus,
OldSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
FIELD_SIZE(FsmFlashSectorHdrT, Status)
);
if(ret != ERR_NONE)
return ret;
/* appended sector state to valid */
SectorStatus = SECTOR_VALID;
ret = DevWrite( DevP,
(uint8 *)&SectorStatus,
AppendSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
FIELD_SIZE(FsmFlashSectorHdrT, Status)
);
if(ret != ERR_NONE)
return ret;
/* new sector state to valid */
SectorStatus = SECTOR_VALID;
ret = DevWrite( DevP,
(uint8 *)&SectorStatus,
NewSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
FIELD_SIZE(FsmFlashSectorHdrT, Status)
);
if(ret != ERR_NONE)
return ret;
/* old sector state to invalid */
SectorStatus = SECTOR_INVALID;
ret = DevWrite( DevP,
(uint8 *)&SectorStatus,
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++;
MediaObjP->BlockInfoP[BlkNum].UsedSectors--;
if (FsmReleaseMtxSem(MediaObjP->InfoLock) != ERR_NONE)
{
return ERR_SYSTEM;
}
return ERR_NONE;
}
/********************************************************************
* GetFreeEntry
* Find an available directory entry
* and return the address of the directory entry.
*
* Input:
*
* Output:
* The address of the free directory entry.
* return:
* success: ERR_NONE.
* failure: error code.
*********************************************************************/
static uint32 GetFreeEntry(
FsmQueueItemT * ItemP,
uint32 * AddrP
)
{
uint32 i;
uint32 ret;
uint16 EntryStatus;
uint16 EntrySize;
uint16 EntriesPerSector;
uint16 MaxDirtyCnt = 0;
uint16 CurDirtyCnt = 0;
uint32 offset;
uint32 size;
uint32 EntryAddr;
uint32 OldSectorAddr;
uint32 DirtiestLsn = (uint32)(-1);
uint32 TempPsn;
uint32 TempLsn;
uint32 PrntLsn;
FsmFlashMediaT * MediaObjP;
DEV_READ_FUNCPTR DevRead;
FsmDevObjHdrT * DevP;
ret = ERR_NONE;
if (ItemP->type == QUEUE_FILE_DIR)
{
FsmDfsFileDescriptorT * FdP;
FdP = &FsmDfsFds[ItemP->ItemFd.fd];
DevP = FdP->FdHdr.DevObjP;
MediaObjP = (FsmFlashMediaT * )DevP->MediaObjP;
PrntLsn = FdP->ParentDirFirstLsn;
EntrySize = sizeof(FsmFileDirEntryT);
offset = FIELD_OFFSET(FsmFileDirEntryT, Status);
size = FIELD_SIZE( FsmFileDirEntryT, Status);
}
else
{
DevP = FsmDataItemDevObjP;
MediaObjP = (FsmFlashMediaT * )DevP->MediaObjP;
PrntLsn = 1;
EntrySize = sizeof(FsmItemDirEntryT);
offset = FIELD_OFFSET(FsmItemDirEntryT, Status);
size = FIELD_SIZE( FsmItemDirEntryT, Status);
}
EntriesPerSector = (uint16)(MediaObjP->SectorSize / EntrySize);
DevRead = DevP->DevDrvP->FsmDevRead;
TempLsn = PrntLsn;
DirtiestLsn = (uint32)(-1);
for ( MaxDirtyCnt = 0; TempLsn != (uint32)(-1); )
{
CurDirtyCnt = 0;
TempPsn = DfsLsn2Psn(MediaObjP, TempLsn);
OldSectorAddr = DfsPsn2Addr(MediaObjP, TempPsn);
EntryAddr = OldSectorAddr+ sizeof(FsmFlashSectorHdrT);
for (i = 0; i < EntriesPerSector; i++, EntryAddr += EntrySize)
{
EntryStatus = 0;
ret = DevRead( DevP,
(uint8 *)&EntryStatus,
EntryAddr + offset,
size
);
if(ret != ERR_NONE)
return ret;
if (EntryStatus == ENTRY_EMPTY)
{
*AddrP = EntryAddr;
return ERR_NONE;
}
else if (EntryStatus == ENTRY_INVALID)
{
CurDirtyCnt++;
}
}
if (CurDirtyCnt > MaxDirtyCnt)
{
MaxDirtyCnt = CurDirtyCnt;
DirtiestLsn = TempLsn;
}
/* Get Next Lsn. */
ret = DevRead( DevP,
(uint8 *)&TempLsn,
OldSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
);
if(ret != ERR_NONE)
return ret;
}
if (MaxDirtyCnt != 0)
{
ret = DirModify(DevP, PrntLsn, AddrP, ItemP->type, DirtiestLsn);
}
else
{
ret = DirAppend(DevP, PrntLsn, AddrP, ItemP->type);
}
return ret;
}
/********************************************************************
* GetValidEntry
* Find the matched directory entry, matching pattern
* may be a file name or data item type-id pair.
*
* Input:
*
* Output:
* The address of the matched directory entry.
* return:
* success: ERR_NONE.
* failure: error code.
*********************************************************************/
static uint32 GetValidEntry(
FsmQueueItemT * ItemP,
uint32 * AddrP
)
{
uint32 i, j;
uint32 ret;
uint32 EntriesPerSector;
uint32 TempLsn;
uint32 TempPsn;
uint32 OldSectorAddr;
uint32 EntryAddr;
FsmDevObjHdrT * DevP;
FsmFlashMediaT * MediaObjP;
DEV_READ_FUNCPTR DevRead;
if (ItemP->type == QUEUE_FILE_DIR)
{
FsmDfsFileDescriptorT * FdP;
FsmFileDirEntryT FileEntry;
char * NameP;
FdP = &FsmDfsFds[ItemP->ItemFd.fd];
DevP = FdP->FdHdr.DevObjP;
MediaObjP = (FsmFlashMediaT * )DevP->MediaObjP;
TempLsn = FdP->ParentDirFirstLsn;
i = strlen(FdP->PathName);
while(i > 0)
{
if((FdP->PathName[i - 1] == '/') || (FdP->PathName[i - 1] == '\\'))
{
break;
}
i--;
}
NameP = ((char *)(&FdP->PathName[i]));
EntriesPerSector = MediaObjP->SectorSize / sizeof(FsmFileDirEntryT);
DevRead = DevP->DevDrvP->FsmDevRead;
for ( ; TempLsn != (uint32)(-1); )
{
TempPsn = DfsLsn2Psn(MediaObjP, TempLsn);
OldSectorAddr = DfsPsn2Addr(MediaObjP, TempPsn);
EntryAddr = OldSectorAddr + sizeof(FsmFlashSectorHdrT);
for ( i = 0; i < EntriesPerSector;
i++, EntryAddr += sizeof(FsmFileDirEntryT))
{
FileEntry.Status = 0;
ret = DevRead( DevP,
(uint8 *)&FileEntry,
EntryAddr,
sizeof(FsmFileDirEntryT)
);
if(ret != ERR_NONE)
return ret;
if (FileEntry.Status == ENTRY_VALID)
{
for ( j = 0; j < FIELD_SIZE(FsmFileDirEntryT, FileName); j++)
{
if (FileEntry.FileName[j] != NameP[j])
{
break;
}
else if (FileEntry.FileName[j] == '\0')
{
*AddrP = EntryAddr;
return ERR_NONE;
}
}
if(j == FIELD_SIZE(FsmFileDirEntryT, FileName))
{
if(NameP[j] == '\0')
{
*AddrP = EntryAddr;
return ERR_NONE;
}
}
}
else if (FileEntry.Status == ENTRY_EMPTY)
{
break;
}
}
ret = DevRead( DevP,
(uint8 *)&TempLsn,
OldSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
);
if(ret != ERR_NONE)
return ret;
}
}
else
{
FsmItemDirEntryT ItemEntry;
DevP = FsmDataItemDevObjP;
MediaObjP = (FsmFlashMediaT * )DevP->MediaObjP;
TempLsn = 1; /* ParentDir first lsn for data item; */
EntriesPerSector = MediaObjP->SectorSize / sizeof(FsmItemDirEntryT);
DevRead = DevP->DevDrvP->FsmDevRead;
for ( ; TempLsn != (uint32)(-1); )
{
TempPsn = DfsLsn2Psn(MediaObjP, TempLsn);
OldSectorAddr = DfsPsn2Addr(MediaObjP, TempPsn);
EntryAddr = OldSectorAddr + sizeof(FsmFlashSectorHdrT);
for ( i = 0; i < EntriesPerSector;
i++, EntryAddr += sizeof(FsmItemDirEntryT))
{
ItemEntry.Status = 0;
ret = DevRead( DevP,
(uint8 *)&ItemEntry,
EntryAddr,
sizeof(FsmItemDirEntryT)
);
if(ret != ERR_NONE)
return ret;
if (ItemEntry.Status == ENTRY_VALID)
{
if ((ItemEntry.ItemType == ItemP->ItemFd.Item.ItemType)
&& (ItemEntry.ItemId == ItemP->ItemFd.Item.ItemId))
{
*AddrP = EntryAddr;
return ERR_NONE;
}
}
else if (ItemEntry.Status == ENTRY_EMPTY)
{
break;
}
}
ret = DevRead( DevP,
(uint8 *)&TempLsn,
OldSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
);
if(ret != ERR_NONE)
return ret;
}
}
return ERR_NOTEXIST;
}
/********************************************************************
* MultiInstanceCreate
* Create a multi-instance data item.
*
* Input:
*
* Output:
*
* return:
* success: ERR_NONE.
* failure: error code.
*********************************************************************/
static uint32 MultiInstanceCreate(
FsmQueueItemT * ItemP,
FsmDevObjHdrT * DevP)
{
uint8 MultiInstStatus;
uint32 temp1;
uint16 temp2;
uint32 ret;
uint32 NewLsn;
uint32 NewPsn;
uint32 WriteOffset;
uint32 NewEntryAddr;
uint32 NewSectorAddr;
FsmFlashSectorHdrT SectorHdr;
FsmItemDirEntryT ItemEntry;
FsmFlashMediaT * MediaObjP;
DEV_WRITE_FUNCPTR DevWrite = DevP->DevDrvP->FsmDevWrite;
MediaObjP = (FsmFlashMediaT * )DevP->MediaObjP;
ret = GetFreeEntry(ItemP, &NewEntryAddr);
if (ret != ERR_NONE)
{
return ret;
}
ret = GetFreeLsn(DevP, &NewLsn);
if (ret != ERR_NONE)
{
return ret;
}
ret = GetFreePsn(DevP, &NewPsn);
if (ret != ERR_NONE)
{
return ret;
}
NewSectorAddr = DfsPsn2Addr(MediaObjP, NewPsn);
/* 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;
SectorHdr.Type = SECTOR_TYPE_MID;
SectorHdr.Lsn = NewLsn;
SectorHdr.NextLsn = (uint32)(-1); /* 0xFFFFFFFF */
/* building the new sector header. */
ret = DevWrite( DevP,
(uint8 *)&SectorHdr,
NewSectorAddr,
sizeof(FsmFlashSectorHdrT)
);
if(ret != ERR_NONE)
return ret;
temp1 = MediaObjP->SectorSize - FIELD_SIZE(FsmMultiInstanceT, Length);
temp2 = (uint16)(ItemP->length + (FIELD_SIZE(FsmMultiInstanceT, Status))); /* sizeof(uint8); */
temp1 = (temp1 / temp2) * (FIELD_SIZE(FsmMultiInstanceT, Status)/*sizeof(uint8)*/);
WriteOffset = temp1 + FIELD_SIZE(FsmMultiInstanceT, Length);
/* write data to flash. */
ret = DevWrite( DevP,
(uint8 *)(ItemP + 1),
NewSectorAddr + sizeof(FsmFlashSectorHdrT) + WriteOffset,
ItemP->length
);
if(ret != ERR_NONE)
return ret;
/* Multi-Instance data is ready now. */
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;
/* length of every instance. */
temp2 = (uint16)ItemP->length;
ret = DevWrite( DevP,
(uint8 *)&temp2,
NewSectorAddr + sizeof(FsmFlashSectorHdrT) \
+ FIELD_OFFSET(FsmMultiInstanceT, Length),
FIELD_SIZE(FsmMultiInstanceT, Length)
);
if(ret != ERR_NONE)
return ret;
/* Update the Lsn to Psn map information for the new sector. */
if (FsmGetMtxSem(MediaObjP->MapTblLock) != ERR_NONE)
{
return ERR_SYSTEM;
}
MediaObjP->Lsn2PsnP[NewLsn] = NewPsn;
if (FsmReleaseMtxSem(MediaObjP->MapTblLock) != ERR_NONE)
{
return ERR_SYSTEM;
}
/* sector state to allocated */
SectorHdr.Status = SECTOR_ALLOCATED;
ret = DevWrite( DevP,
(uint8 *)&SectorHdr.Status,
NewSectorAddr + FIELD_OFFSET(FsmFlashSectorHdrT, Status),
FIELD_SIZE(FsmFlashSectorHdrT, Status)
);
if(ret != ERR_NONE)
return ret;
/* 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.Type = ENTRY_TYPE_ITEM;
ItemEntry.ItemType = ItemP->ItemFd.Item.ItemType;
ItemEntry.ItemId = ItemP->ItemFd.Item.ItemId;
ItemEntry.Method = METHOD_MULTI;
ItemEntry.Length = ItemP->length;
ItemEntry.FirstLsn = NewLsn;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -