/***************************************************************************** * 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; }
/***************************************************************************** * 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; }