示例#1
0
/*****************************************************************************
 * FUNCTION - LoadAllSubjectsFromCache
 * DESCRIPTION:
 * Loads all subjects from cache (calls LoadFromFlash on each subject)
 ****************************************************************************/
bool FlashBlock::LoadAllSubjectsFromCache(void)
{
  bool success = true;
  Subject* pSubject;
  SUBJECT_FLASH_HEADER_TYPE* pSubjectHdr;
  U32 startReadPos;

  // reset read position
  mReadPos = 0;

  // read all subjects
  for (int i = 0; i < mpBlockHdr->subjectCount; i++)
  {
    // get pointer to subject header
    pSubjectHdr = (SUBJECT_FLASH_HEADER_TYPE*)(mpBlockData + mReadPos);

    // get subject - we need to search to ensure that the subject
    // is still in the list for this block
    pSubject = NULL;
    for (int j = 0; j < mSubjectCount; j++)
    {
      if (mpSubjects[j].subjectId == pSubjectHdr->subjectId)
      {
        pSubject = mpConfigControl->GetSubject(pSubjectHdr->subjectId);
        break;
      }
    }

    // subject found?
    if (pSubject)
    {
      // set read pos to start of data
      mReadPos += SUBJECT_FLASH_HEADER_SIZE;

      // verify flash ID
      if (pSubjectHdr->flashId == pSubject->GetFlashId())
      {
        // store start read pos, set number of bytes available for read and clear read error flag
        startReadPos = mReadPos;
        mReadAvailable = pSubjectHdr->dataLength;
        mReadError = false;

        // load subject
        pSubject->LoadFromFlash(this, (FLASH_SAVE_TYPE)pSubjectHdr->saveType);

        // verify number of bytes read by the subject
        if (mReadError || ((mReadPos - startReadPos) != pSubjectHdr->dataLength))
        {
          // adjust read pos to get back on track
          mReadPos = startReadPos + pSubjectHdr->dataLength;

          // clear success flag
          success = false;
        }
      }
      else
      {
        // subject type has changed, adjust read position to get back on track
        mReadPos += pSubjectHdr->dataLength;

        // This is ok in case the pc edition of the controller loads an old configuration file 
        // that contains subjects which have been removed in the current version.
        #ifndef __PC__
        // clear success flag
        success = false;
        #endif
      }
    }
    else
    {
      // subject not found (no longer in DB or moved to another block)
      // adjust read position to get back on track
      mReadPos += (SUBJECT_FLASH_HEADER_SIZE + pSubjectHdr->dataLength);
    }
  }

  return success;
}
示例#2
0
/*****************************************************************************
 * FUNCTION - SaveAllSubjectsToCache
 * DESCRIPTION: Saves all subjects to the cache which also re-organizes
 * the flash block if necessary
 ****************************************************************************/
void FlashBlock::SaveAllSubjectsToCache(void)
{
  Subject* pSubject;
  U32 startWritePos;
  SUBJECT_FLASH_HEADER_TYPE* pSubjectHdr;

  // reset
  mpBlockHdr->blockSize = FLASH_BLOCK_HEADER_SIZE;
  mpBlockHdr->subjectCount = 0;
  mWritePos = 0;
  memset(mpBlockData, 0xCC, mMaxBlockSize - FLASH_BLOCK_HEADER_SIZE);
  mErrorFlags = 0;

  // save all subjects
  for (int i = 0; i < mSubjectCount; i++)
  {
    pSubject = mpConfigControl->GetSubject(mpSubjects[i].subjectId);

    if (pSubject)
    {
      // set subject header pointer and store write pos
      pSubjectHdr = (SUBJECT_FLASH_HEADER_TYPE*)(mpBlockData + mWritePos);
      startWritePos = mWritePos;

      // store write pos and save type, first time only
      SUBJECT_FLASH_INFO_TYPE sfi;
      sfi.writePos = mWritePos;
      sfi.saveType = mpSubjects[i].saveType;
      mSubjectInfo[pSubject->GetSubjectId()] = sfi;

      // set subject id, flash id and reset data length
      pSubjectHdr->subjectId = pSubject->GetSubjectId();
      pSubjectHdr->flashId = pSubject->GetFlashId();
      pSubjectHdr->saveType = mpSubjects[i].saveType;
      pSubjectHdr->dataLength = 0;

      // advance to data
      mWritePos += SUBJECT_FLASH_HEADER_SIZE;

      // reset write error and calculate write available
      mWriteError = false;
      mWriteAvailable = mMaxBlockSize - FLASH_BLOCK_HEADER_SIZE - mWritePos;

      // save subject
      pSubject->SaveToFlash(this, mpSubjects[i].saveType);

      // check for write error
      if (mWriteError)
      {
        FatalErrorOccured("FLASH block too small!");
        mErrorFlags |= ERROR_FLAG_FLASH_BLOCK_TOO_SMALL;
      }
      else
      {
        // set subject header data length
        pSubjectHdr->dataLength = mWritePos - startWritePos - SUBJECT_FLASH_HEADER_SIZE;

        // increment subject count
        mpBlockHdr->subjectCount++;
      }
    }
    else
    {
      FatalErrorOccured("FLASH - no subject!");
      mErrorFlags |= ERROR_FLAG_SUBJECT_NOT_FOUND;
    }
	}

	// set block size
	mpBlockHdr->blockSize = FLASH_BLOCK_HEADER_SIZE + mWritePos;
}