📄 flash_pb.c
字号:
//
// Try to write the new parameter block immediately after the most
// recent parameter block.
//
pucNew = g_pucFlashPBCurrent + g_ulFlashPBSize;
if(pucNew == g_pucFlashPBEnd)
{
pucNew = g_pucFlashPBStart;
}
}
else
{
//
// There is not a valid parameter block in flash, so set the sequence
// number of this parameter block to zero.
//
pucBuffer[0] = 0;
//
// Try to write the new parameter block at the beginning of the flash
// space for parameter blocks.
//
pucNew = g_pucFlashPBStart;
}
//
// Compute the checksum of the parameter block to be written.
//
for(ulIdx = 0, ulSum = 0; ulIdx < g_ulFlashPBSize; ulIdx++)
{
ulSum -= pucBuffer[ulIdx];
}
//
// Store the checksum into the parameter block.
//
pucBuffer[1] += ulSum;
//
// Look for a location to store this parameter block. This infinite loop
// will be explicitly broken out of when a valid location is found.
//
while(1)
{
//
// See if this location is at the start of an erase block.
//
if(((unsigned long)pucNew & 1023) == 0)
{
//
// Erase this block of the flash. This does not assume that the
// erase succeeded in case this block of the flash has become bad
// through too much use. Given the extremely low frequency that
// the parameter blocks are written, this will likely never fail.
// But, that assumption is not made in order to be safe.
//
FlashErase((unsigned long)pucNew);
}
//
// Loop through this portion of flash to see if is all ones (i.e. it
// is an erased portion of flash).
//
for(ulIdx = 0; ulIdx < g_ulFlashPBSize; ulIdx++)
{
if(pucNew[ulIdx] != 0xff)
{
break;
}
}
//
// If all bytes in this portion of flash are ones, then break out of
// the loop since this is a good location for storing the parameter
// block.
//
if(ulIdx == g_ulFlashPBSize)
{
break;
}
//
// Increment to the next parameter block location.
//
pucNew += g_ulFlashPBSize;
if(pucNew == g_pucFlashPBEnd)
{
pucNew = g_pucFlashPBStart;
}
//
// If every possible location has been checked and none are valid, then
// it will not be possible to write this parameter block. Simply
// return without writing it.
//
if((g_pucFlashPBCurrent && (pucNew == g_pucFlashPBCurrent)) ||
(!g_pucFlashPBCurrent && (pucNew == g_pucFlashPBStart)))
{
return;
}
}
//
// Write this parameter block to flash.
//
FlashProgram((unsigned long *)pucBuffer, (unsigned long)pucNew,
g_ulFlashPBSize);
//
// Compare the parameter block data to the data that should now be in
// flash. Return if any of the data does not compare, leaving the previous
// parameter block in flash as the most recent (since the current parameter
// block failed to properly program).
//
for(ulIdx = 0; ulIdx < g_ulFlashPBSize; ulIdx++)
{
if(pucNew[ulIdx] != pucBuffer[ulIdx])
{
return;
}
}
//
// The new parameter block becomes the most recent parameter block.
//
g_pucFlashPBCurrent = pucNew;
}
//*****************************************************************************
//
//! Initializes the flash parameter block.
//!
//! \param ulStart is the address of the flash memory to be used for storing
//! flash parameter blocks; this must be the start of an erase block in the
//! flash.
//! \param ulEnd is the address of the end of flash memory to be used for
//! storing flash parameter blocks; this must be the start of an erase block in
//! the flash (the first block that is NOT part of the flash memory to be
//! used), or the address of the first word after the flash array if the last
//! block of flash is to be used.
//! \param ulSize is the size of the parameter block when stored in flash;
//! this must be a power of two less than or equal to 1024.
//!
//! This function initializes the flash parameter block functions. It will
//! scan the portion of flash used for storing parameter blocks to find the
//! most recent valid parameter block. This function must be called before
//! any other flash parameter block functions are called.
//!
//! \return None.
//
//*****************************************************************************
void
FlashPBInit(unsigned long ulStart, unsigned long ulEnd, unsigned long ulSize)
{
unsigned char *pucOffset, *pucCurrent;
unsigned char ucOne, ucTwo;
//
// Set the number of clocks per microsecond to enable the flash controller
// to properly program the flash.
//
FlashUsecSet(SysCtlClockGet() / 1000000);
//
// Save the characteristics of the flash memory to be used for storing
// parameter blocks.
//
g_pucFlashPBStart = (unsigned char *)ulStart;
g_pucFlashPBEnd = (unsigned char *)ulEnd;
g_ulFlashPBSize = ulSize;
//
// Loop through the portion of flash memory used for storing parameter
// blocks.
//
for(pucOffset = g_pucFlashPBStart, pucCurrent = 0;
pucOffset < g_pucFlashPBEnd; pucOffset += g_ulFlashPBSize)
{
//
// See if this is a valid parameter block (i.e. the checksum is
// correct).
//
if(FlashPBIsValid(pucOffset))
{
//
// See if a valid parameter block has been previously found.
//
if(pucCurrent != 0)
{
//
// Get the sequence numbers for the current and new parameter
// blocks.
//
ucOne = pucCurrent[0];
ucTwo = pucOffset[0];
//
// See if the sequence number for the new parameter block is
// greater than the current block. The comparison isn't
// straightforward since the one byte sequence number will wrap
// after 256 parameter blocks.
//
if(((ucOne > ucTwo) && ((ucOne - ucTwo) < 128)) ||
((ucTwo > ucOne) && ((ucTwo - ucOne) > 128)))
{
//
// The new parameter block is older than the current
// parameter block, so skip the new parameter block and
// keep searching.
//
continue;
}
}
//
// The new parameter block is more recent than the current one, so
// make it the new current parameter block.
//
pucCurrent = pucOffset;
}
}
//
// Save the address of the most recent parameter block found. If no valid
// parameter blocks were found, this will be a NULL pointer.
//
g_pucFlashPBCurrent = pucCurrent;
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -