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

📄 flash_nvram56xx.c

📁 GM5621原代码
💻 C
📖 第 1 页 / 共 4 页
字号:


   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 + -