📄 flash_nvram56xx.c
字号:
if((DWORD)workingSector == FLASHUserPrefSectorStart)
alternateSector = (BYTE far *)(FLASHUserPrefSectorStart + FLASHUserPrefSectorSize);
else
alternateSector = (BYTE far *)FLASHUserPrefSectorStart;
msgx("Before FLASH_NV_SECTOR_ERASE = %d", 0);
// erase the alternate sector, just to make sure it's blank.
executeRamResidentCmd(FLASH_NV_SECTOR_ERASE, alternateSector, HUGE_OFF(FLASHUserPrefSectorSize), NULL_PTR);
msgx("After FLASH_NV_SECTOR_ERASE = %d", 1);
msgx("workingSector seg %x",FP_SEG(workingSector));
msgx("workingSector off %x",FP_OFF(workingSector));
WrAddr = workingSector;
LastAddress = (DWORD)workingSector + FLASHUserPrefSectorSize;
altPtr = alternateSector;
freeSpace = BUFFER_LENGTH;
offset = 0;
//build valid address table
do
{
blockType = WrAddr[0];
index = WrAddr[1];
if(IsValidBlockEntry(blockType, index)==gmd_TRUE)
{
if(!checkChecksum(WrAddr))
{
msgx("invalid block at offset: %d", offset);
}
else
{
pos = B_CountTable[blockType]+index;
W_AddrTable[pos] = offset;
msgx("blockType: %d", blockType);
msgx("index: %d", index);
msgx("positn: %d", pos);
msgx("offset: %d", offset);
}
}
length = getLength(WrAddr);
// if length > UserPrefSectorSize, than either it's 0xffff becuase the location is blank and
// we've reachd the end of our data, or it's corrupt, either case stop here.
if((length > HUGE_OFF(FLASHUserPrefSectorSize)) || (length == 0x00))
{
msgx("length out of range %d",length);
msgx("WrAddr seg %x",FP_SEG(WrAddr));
msgx("WrAddr off %x",FP_OFF(WrAddr));
msgx("WrAddr[0] %x",(WORD)WrAddr[0]);
msgx("WrAddr[1] %x",(WORD)WrAddr[1]);
msgx("blockType %x",(WORD)blockType);
msgx("blockIndex %x",(WORD)index);
break;
}
WrAddr += length;
offset += length;
}
while((HUGE(WrAddr) < HUGE(LastAddress)) && (HUGE(WrAddr) > HUGE(workingSector)));// make sure still in range.
//based W_AddrTable[], copy data to another sector
msgx("HUGE_OFF(FLASHUserPrefSectorSize): 0x%x", HUGE_OFF(FLASHUserPrefSectorSize));
for(i=0; i<MAX_TOTAL_INDICES; i++)
{
msgx("W_AddrTable[i]: 0x%x", W_AddrTable[i]);
if(W_AddrTable[i]>HUGE_OFF(FLASHUserPrefSectorSize))
continue; //skip invalid entry
WrAddr = workingSector + W_AddrTable[i];
length = getLength(WrAddr);
msgx("length: %d", length);
if (freeSpace)
{
offsetInBlock = 0;
while (length > freeSpace)
{
_fmemcpy((buff+BUFFER_LENGTH-freeSpace), WrAddr+offsetInBlock, freeSpace);
msgx("1.freeSpace: %d", freeSpace);
msgx("offsetInBlock %d",offsetInBlock);
msgx("altPtr seg 0x%x",FP_SEG(altPtr));
msgx("altPtr off 0x%x",FP_OFF(altPtr));
executeRamResidentCmd(FLASH_NV_WRITE, altPtr, BUFFER_LENGTH, buff);
//update variables
altPtr = (BYTE far *)((DWORD)altPtr + BUFFER_LENGTH);
length -= freeSpace;
offsetInBlock += freeSpace;
freeSpace = BUFFER_LENGTH;
}
if(length)
{//copy remaining data in current block
_fmemcpy((buff+BUFFER_LENGTH-freeSpace), WrAddr+offsetInBlock, length);
freeSpace -= length;
msgx("*freeSpace: %d", freeSpace);
if(!freeSpace) //just exactly 1 buffer data
{
msgx("2.freeSpace: %d", freeSpace);
msgx("altPtr seg 0x%x",FP_SEG(altPtr));
msgx("altPtr off 0x%x",FP_OFF(altPtr));
executeRamResidentCmd(FLASH_NV_WRITE, altPtr, BUFFER_LENGTH, buff);
altPtr = (BYTE far *)((DWORD)altPtr + BUFFER_LENGTH);
freeSpace = BUFFER_LENGTH;
}
}
}
}
// Check if last buffer not write to flash yet.
if (freeSpace>0 && freeSpace!=BUFFER_LENGTH)
{
// Write current buffer content to Flash first, then put this block to buffer.
msgx("3.freeSpace: %d", freeSpace);
msgx("altPtr seg 0x%x",FP_SEG(altPtr));
msgx("altPtr off 0x%x",FP_OFF(altPtr));
executeRamResidentCmd(FLASH_NV_WRITE, altPtr, BUFFER_LENGTH-freeSpace, buff);
altPtr = (BYTE far *)((DWORD)altPtr + BUFFER_LENGTH-freeSpace);
msgx("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", 0);
msgx("Last write to flash with length = %d", (BUFFER_LENGTH-freeSpace));
msgx("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", 0);
}
// swap current and working sectors and erase the new alternate sector,
// this is necessary else on start up we won't know which sector is the
// valid "working" sector if they both sectors contain data.
workingSector = alternateSector;
if((DWORD)workingSector == FLASHUserPrefSectorStart)
alternateSector = (BYTE far *)(FLASHUserPrefSectorStart + FLASHUserPrefSectorSize);
else
alternateSector = (BYTE far *)FLASHUserPrefSectorStart;
executeRamResidentCmd(FLASH_NV_SECTOR_ERASE, alternateSector, HUGE_OFF(FLASHUserPrefSectorSize), NULL_PTR);
//inp_msg("Move data to another bank ... finish ............ %d", 1);
return;
}
#else
void prune(void)
{
WORD BlockType, offset, length, cpyLength;
BYTE index, version;
BYTE far *alternateSector, far *altPtr;
BYTE far *GoodBlock;
BYTE buff[32];
if((DWORD)workingSector == FLASHUserPrefSectorStart)
alternateSector = (BYTE far *)(FLASHUserPrefSectorStart + FLASHUserPrefSectorSize);
else
alternateSector = (BYTE far *)FLASHUserPrefSectorStart;
// erase the alternate sector, just to make sure it's blank.
executeRamResidentCmd(FLASH_NV_SECTOR_ERASE, alternateSector, HUGE_OFF(FLASHUserPrefSectorSize), NULL_PTR);
BlockType = 0x00;
index = 0x00;
version = 0x00;
altPtr = alternateSector;
do
{
if((GoodBlock = findBlockType(BlockType,index,&version)) != NULL_PTR)
{// an entry was found, so copy it into the alternate sector.
// GoodBlock is pointing to the entry, get the length.
msgx(" found block %x", (WORD)BlockType);
msgx(" index %x", (WORD)index);
msgx(" version %x", (WORD)version);
if(checkChecksum(GoodBlock))
{// if checksum good, copy data...
length = getLength(GoodBlock);
offset = 0;
do
{
if(length > sizeof(buff))
cpyLength = sizeof(buff);
else
cpyLength = length;
// read data...
_fmemcpy(buff, &GoodBlock[offset], cpyLength);
// write data...
executeRamResidentCmd(FLASH_NV_WRITE, altPtr, cpyLength, buff);
length -= cpyLength;
offset += cpyLength;
altPtr = (BYTE far *)((DWORD)altPtr + cpyLength);
}while(length);
}
// else checksum bad, if another version exists, try that one.
else if(version > 1)
{
version--;
continue;
}
// increment index...
if(index < 0xff)
index++;
else
{
BlockType++;
index = 0;
}
version = 0;
}
else
{// block not found, increment to next block type.
BlockType++;
index = 0;
version = 0;
}
}while(BlockType <= LAST_BLOCK_ID);
// swap current and working sectors and erase the new alternate sector,
// this is necessary else on start up we won't know which sector is the
// valid "working" sector if they both sectors contain data.
workingSector = alternateSector;
if((DWORD)workingSector == FLASHUserPrefSectorStart)
alternateSector = (BYTE far *)(FLASHUserPrefSectorStart + FLASHUserPrefSectorSize);
else
alternateSector = (BYTE far *)FLASHUserPrefSectorStart;
executeRamResidentCmd(FLASH_NV_SECTOR_ERASE, alternateSector, HUGE_OFF(FLASHUserPrefSectorSize), NULL_PTR);
return;
}
#endif
//***************************************************************
// FUNCTION : checkChecksum
// DESCRIPTION : validates checksum for entire block.
// INPUT : addr, pointer to start of a block header
// OUTPUT : TRUE/FALSE based on if CRC is good or bad.
//***************************************************************
static BYTE checkChecksum(BYTE far * blockAddr)
{
BYTE chksum = 0;
WORD count = getLength(blockAddr) - sizeof(block_hdr_type);
// perform checksum on entire block, even if only copying a small portion.
while(count--)
{
chksum += blockAddr[BLOCK_DATA_OFFSET + count];
}
if(chksum != blockAddr[BLOCK_CHECKSUM_OFFSET])
{
msg("checksum bad",0);
return gmd_FALSE;
}
return gmd_TRUE;
}
//***************************************************************
// FUNCTION : getLength
// DESCRIPTION : addr points to the start of a block header.
// This function will extract the length field out
// INPUT : addr, pointer to start of a block header.
// OUTPUT : NONE
//***************************************************************
static WORD getLength(BYTE far *addr)
{
WORD length;
length = addr[3];
length <<= 8;
length += addr[2];
return length;
}
//***************************************************************
// FUNCTION : findWorkingSector
// USAGE :
// DESCRIPTION : find sector that is currently being used.
// Looks at how much room is left in each sector. The one with
// the least amount of room is the one that's being used.
// The idea being if the power goes out during a prune, you'll
// be left with two sectors with data. The one with the most
// data is the origional working sector.
// INPUT : None
// OUTPUT : FlashCmd.Cmd.working_sector and WrAddr will
// be pointing to the 'working' sector.
//***************************************************************
static void findWorkingSector(void)
{
WORD Size0, Size1;
BYTE far * WrAddr;
workingSector = (BYTE far *)FLASHUserPrefSectorStart;
WrAddr = findBlockType(0xff, 0xff, NULL_PTR);
if(WrAddr != NULL_PTR)
Size0 = (WORD)(HUGE(FLASHUserPrefSectorStart + FLASHUserPrefSectorSize) - HUGE(WrAddr));
else
Size0 = (WORD)(HUGE(FLASHUserPrefSectorSize));
workingSector = (BYTE far *)(FLASHUserPrefSectorStart + FLASHUserPrefSectorSize);
WrAddr = findBlockType(0xff, 0xff, NULL_PTR);
if(WrAddr != NULL_PTR)
Size1 = (WORD)(HUGE(FLASHUserPrefSectorStart + 2 * FLASHUserPrefSectorSize) - HUGE(WrAddr));
else
Size1 = (WORD)(HUGE(FLASHUserPrefSectorSize));
msg("Size0 %d",Size0);
msg("Size1 %d",Size1);
msg("flash_nvram: working sector is",0);
if(Size1 >= Size0)
{// 2nd sector has more room, so 1st sector has more data.
workingSector = (BYTE far *)FLASHUserPrefSectorStart;
msg("1st sector",0);
}
else
{// 1st sector has more room, so 2nd sector has more data.
workingSector = (BYTE far *)(FLASHUserPrefSectorStart + FLASHUserPrefSectorSize);
msg("2nd sector",0);
}
msgx("workingSector seg %x",FP_SEG(workingSector));
msgx("workingSector off %x",FP_OFF(workingSector));
}
#endif //NVRAM_USE_FLASH
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -