Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
strategy.c
00001 /* 00002 * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "flash-journal-strategy-sequential/flash_journal_crc.h" 00019 #include "flash-journal-strategy-sequential/flash_journal_private.h" 00020 #include "flash-journal-strategy-sequential/flash_journal_strategy_sequential.h" 00021 #include "support_funcs.h" 00022 #include <string.h> 00023 #include <stdio.h> 00024 00025 SequentialFlashJournal_t *activeJournal; 00026 00027 /* 00028 * forward declarations of static-inline helper functions. 00029 */ 00030 static inline int32_t mtdGetTotalCapacity(ARM_DRIVER_STORAGE *mtd, uint64_t *capacityP); 00031 static inline int32_t flashJournalStrategySequential_format_sanityChecks(ARM_DRIVER_STORAGE *mtd, uint32_t numSlots); 00032 static inline int32_t flashJournalStrategySequential_read_sanityChecks(SequentialFlashJournal_t *journal, const void *blob, size_t sizeofBlob); 00033 static inline int32_t flashJournalStrategySequential_log_sanityChecks(SequentialFlashJournal_t *journal, const void *blob, size_t sizeofBlob); 00034 static inline int32_t flashJournalStrategySequential_commit_sanityChecks(SequentialFlashJournal_t *journal); 00035 00036 00037 int32_t flashJournalStrategySequential_format(ARM_DRIVER_STORAGE *mtd, 00038 uint32_t numSlots, 00039 FlashJournal_Callback_t callback) 00040 { 00041 int32_t rc; 00042 if ((rc = flashJournalStrategySequential_format_sanityChecks(mtd, numSlots)) != JOURNAL_STATUS_OK) { 00043 return rc; 00044 } 00045 00046 ARM_STORAGE_INFO mtdInfo; 00047 if (mtd->GetInfo(&mtdInfo) < ARM_DRIVER_OK) { 00048 return JOURNAL_STATUS_STORAGE_API_ERROR; 00049 } 00050 uint64_t mtdAddr; 00051 if (mtdGetStartAddr(mtd, &mtdAddr) < JOURNAL_STATUS_OK) { 00052 return JOURNAL_STATUS_STORAGE_API_ERROR; 00053 } 00054 00055 formatInfoSingleton.mtd = mtd; 00056 formatInfoSingleton.mtdAddr = mtdAddr; 00057 formatInfoSingleton.callback = callback; 00058 formatInfoSingleton.mtdProgramUnit = mtdInfo.program_unit; 00059 00060 if ((rc = setupSequentialJournalHeader(&formatInfoSingleton.header, mtd, mtdInfo.total_storage, numSlots)) != JOURNAL_STATUS_OK) { 00061 return rc; 00062 } 00063 00064 /* initialize MTD */ 00065 rc = mtd->Initialize(formatHandler); 00066 if (rc < ARM_DRIVER_OK) { 00067 return JOURNAL_STATUS_STORAGE_API_ERROR; 00068 } else if (rc == ARM_DRIVER_OK) { 00069 return JOURNAL_STATUS_OK; /* An asynchronous operation is pending; it will result in a completion callback 00070 * where the rest of processing will take place. */ 00071 } 00072 if (rc != 1) { 00073 return JOURNAL_STATUS_STORAGE_API_ERROR; /* synchronous completion is expected to return 1 */ 00074 } 00075 00076 /* progress the rest of the create state-machine */ 00077 return flashJournalStrategySequential_format_progress(ARM_DRIVER_OK, ARM_STORAGE_OPERATION_INITIALIZE); 00078 } 00079 00080 /** 00081 * Validate a header at the start of the MTD. 00082 * 00083 * @param [in/out] headerP 00084 * Caller-allocated header which gets filled in during validation. 00085 00086 * @return JOURNAL_STATUS_OK if the header is sane. As a side-effect, the memory 00087 * pointed to by 'headerP' is initialized with the header. 00088 */ 00089 int32_t readAndVerifyJournalHeader(SequentialFlashJournal_t *journal, SequentialFlashJournalHeader_t *headerP) 00090 { 00091 if (headerP == NULL) { 00092 return JOURNAL_STATUS_PARAMETER; 00093 } 00094 00095 int32_t rc = journal->mtd->ReadData(journal->mtdStartOffset, headerP, sizeof(SequentialFlashJournalHeader_t)); 00096 if (rc < ARM_DRIVER_OK) { 00097 return JOURNAL_STATUS_STORAGE_IO_ERROR; 00098 } else if (rc == ARM_DRIVER_OK) { 00099 ARM_STORAGE_CAPABILITIES mtdCaps = journal->mtd->GetCapabilities(); 00100 if (!mtdCaps.asynchronous_ops) { 00101 return JOURNAL_STATUS_ERROR; /* asynchronous_ops must be set if MTD returns ARM_DRIVER_OK. */ 00102 } 00103 00104 return JOURNAL_STATUS_ERROR; /* TODO: handle init with pending asynchronous activity. */ 00105 } 00106 00107 if ((headerP->genericHeader.magic != FLASH_JOURNAL_HEADER_MAGIC) || 00108 (headerP->genericHeader.version != FLASH_JOURNAL_HEADER_VERSION) || 00109 (headerP->genericHeader.sizeofHeader != sizeof(SequentialFlashJournalHeader_t)) || 00110 (headerP->magic != SEQUENTIAL_FLASH_JOURNAL_HEADER_MAGIC) || 00111 (headerP->version != SEQUENTIAL_FLASH_JOURNAL_HEADER_VERSION)) { 00112 return JOURNAL_STATUS_NOT_FORMATTED; 00113 } 00114 00115 uint32_t expectedCRC = headerP->genericHeader.checksum; 00116 headerP->genericHeader.checksum = 0; 00117 flashJournalCrcReset(); 00118 uint32_t computedCRC = flashJournalCrcCummulative((const unsigned char *)&headerP->genericHeader, sizeof(SequentialFlashJournalLogHead_t)); 00119 if (computedCRC != expectedCRC) { 00120 //printf("readAndVerifyJournalHeader: checksum mismatch during header verification: expected = %u, computed = %u\n", (unsigned int) expectedCRC, (unsigned int) computedCRC); 00121 return JOURNAL_STATUS_METADATA_ERROR; 00122 } 00123 00124 return JOURNAL_STATUS_OK; 00125 } 00126 00127 int32_t flashJournalStrategySequential_initialize(FlashJournal_t *_journal, 00128 ARM_DRIVER_STORAGE *mtd, 00129 const FlashJournal_Ops_t *ops, 00130 FlashJournal_Callback_t callback) 00131 { 00132 int32_t rc; 00133 00134 /* initialize MTD */ 00135 rc = mtd->Initialize(mtdHandler); 00136 if (rc < ARM_DRIVER_OK) { 00137 memset(_journal, 0, sizeof(FlashJournal_t)); 00138 return JOURNAL_STATUS_STORAGE_API_ERROR; 00139 } 00140 if (rc == ARM_DRIVER_OK) { 00141 ARM_STORAGE_CAPABILITIES mtdCaps = mtd->GetCapabilities(); 00142 if (!mtdCaps.asynchronous_ops) { 00143 return JOURNAL_STATUS_ERROR; /* asynchronous_ops must be set if MTD returns ARM_DRIVER_OK. */ 00144 } 00145 00146 return JOURNAL_STATUS_ERROR; /* TODO: handle init with pending asynchronous activity. */ 00147 } 00148 00149 SequentialFlashJournal_t *journal; 00150 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00151 journal->state = SEQUENTIAL_JOURNAL_STATE_NOT_INITIALIZED; 00152 journal->mtd = mtd; 00153 00154 /* Setup start address within MTD. */ 00155 if ((rc = mtdGetStartAddr(journal->mtd, &journal->mtdStartOffset)) != JOURNAL_STATUS_OK) { 00156 return rc; 00157 } 00158 00159 /* fetch MTD's total capacity */ 00160 uint64_t mtdCapacity; 00161 if ((rc = mtdGetTotalCapacity(mtd, &mtdCapacity)) != JOURNAL_STATUS_OK) { 00162 return rc; 00163 } 00164 ARM_STORAGE_INFO mtdInfo; 00165 if ((rc = mtd->GetInfo(&mtdInfo)) != ARM_DRIVER_OK) { 00166 return JOURNAL_STATUS_STORAGE_API_ERROR; 00167 } 00168 00169 SequentialFlashJournalHeader_t journalHeader; 00170 if ((rc = readAndVerifyJournalHeader(journal, &journalHeader)) != JOURNAL_STATUS_OK) { 00171 return rc; 00172 } 00173 00174 /* initialize the journal structure */ 00175 memcpy(&journal->ops, ops, sizeof(FlashJournal_Ops_t)); 00176 journal->mtdCapabilities = mtd->GetCapabilities(); /* fetch MTD's capabilities */ 00177 00178 journal->firstSlotOffset = journalHeader.genericHeader.journalOffset; 00179 journal->numSlots = journalHeader.numSlots; 00180 journal->sizeofSlot = journalHeader.sizeofSlot; 00181 00182 /* effective capacity */ 00183 journal->info.capacity = journal->sizeofSlot 00184 - roundUp_uint32(sizeof(SequentialFlashJournalLogHead_t), mtdInfo.program_unit) 00185 - roundUp_uint32(sizeof(SequentialFlashJournalLogTail_t), mtdInfo.program_unit); 00186 journal->info.program_unit = mtdInfo.program_unit; 00187 journal->callback = callback; 00188 journal->prevCommand = FLASH_JOURNAL_OPCODE_INITIALIZE; 00189 00190 if ((rc = discoverLatestLoggedBlob(journal)) != JOURNAL_STATUS_OK) { 00191 return rc; 00192 } 00193 00194 return 1; /* synchronous completion */ 00195 } 00196 00197 FlashJournal_Status_t flashJournalStrategySequential_getInfo(FlashJournal_t *_journal, FlashJournal_Info_t *infoP) 00198 { 00199 SequentialFlashJournal_t *journal; 00200 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00201 00202 memcpy(infoP, &journal->info, sizeof(FlashJournal_Info_t)); 00203 return JOURNAL_STATUS_OK; 00204 } 00205 00206 int32_t flashJournalStrategySequential_read(FlashJournal_t *_journal, void *blob, size_t sizeofBlob) 00207 { 00208 SequentialFlashJournal_t *journal; 00209 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00210 00211 if (journal->prevCommand != FLASH_JOURNAL_OPCODE_READ_BLOB) { 00212 journal->read.logicalOffset = 0; 00213 } 00214 00215 int32_t rc; 00216 if ((rc = flashJournalStrategySequential_read_sanityChecks(journal, blob, sizeofBlob)) != JOURNAL_STATUS_OK) { 00217 return rc; 00218 } 00219 00220 journal->read.blob = blob; 00221 journal->read.sizeofBlob = sizeofBlob; 00222 00223 if (journal->read.logicalOffset == 0) { 00224 { /* Establish the sanity of this slot before proceeding with the read. */ 00225 uint32_t headSequenceNumber; 00226 SequentialFlashJournalLogTail_t tail; 00227 if (slotIsSane(journal, 00228 SLOT_ADDRESS(journal, journal->currentBlobIndex), 00229 &headSequenceNumber, 00230 &tail) != 1) { 00231 /* TODO: rollback to an older slot. */ 00232 return JOURNAL_STATUS_STORAGE_IO_ERROR; 00233 } 00234 } 00235 00236 journal->read.mtdOffset = SLOT_ADDRESS(journal, journal->currentBlobIndex) + sizeof(SequentialFlashJournalLogHead_t); 00237 } else { 00238 /* journal->read.offset is already set from the previous read execution */ 00239 // printf("flashJournalStrategySequential_read: continuing read of %lu from offset %lu\n", sizeofBlob, (uint32_t)journal->read.offset); 00240 } 00241 journal->read.dataBeingRead = blob; 00242 journal->read.amountLeftToRead = ((journal->info.sizeofJournaledBlob - journal->read.logicalOffset) < sizeofBlob) ? 00243 (journal->info.sizeofJournaledBlob - journal->read.logicalOffset) : sizeofBlob; 00244 // printf("amount left to read %u\n", journal->read.amountLeftToRead); 00245 00246 journal->state = SEQUENTIAL_JOURNAL_STATE_READING; 00247 journal->prevCommand = FLASH_JOURNAL_OPCODE_READ_BLOB; 00248 return flashJournalStrategySequential_read_progress(); 00249 } 00250 00251 int32_t flashJournalStrategySequential_readFrom(FlashJournal_t *_journal, size_t offset, void *blob, size_t sizeofBlob) 00252 { 00253 SequentialFlashJournal_t *journal; 00254 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00255 00256 journal->read.logicalOffset = offset; 00257 int32_t rc; 00258 if ((rc = flashJournalStrategySequential_read_sanityChecks(journal, blob, sizeofBlob)) != JOURNAL_STATUS_OK) { 00259 return rc; 00260 } 00261 00262 journal->read.blob = blob; 00263 journal->read.sizeofBlob = sizeofBlob; 00264 00265 journal->read.mtdOffset = SLOT_ADDRESS(journal, journal->currentBlobIndex) + sizeof(SequentialFlashJournalLogHead_t) + offset; 00266 00267 journal->read.dataBeingRead = blob; 00268 journal->read.amountLeftToRead = ((journal->info.sizeofJournaledBlob - journal->read.logicalOffset) < sizeofBlob) ? 00269 (journal->info.sizeofJournaledBlob - journal->read.logicalOffset) : sizeofBlob; 00270 // printf("amount left to read %u\n", journal->read.amountLeftToRead); 00271 00272 journal->state = SEQUENTIAL_JOURNAL_STATE_READING; 00273 journal->prevCommand = FLASH_JOURNAL_OPCODE_READ_BLOB; 00274 return flashJournalStrategySequential_read_progress(); 00275 } 00276 00277 int32_t flashJournalStrategySequential_log(FlashJournal_t *_journal, const void *blob, size_t size) 00278 { 00279 SequentialFlashJournal_t *journal; 00280 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00281 00282 int32_t rc; 00283 if ((rc = flashJournalStrategySequential_log_sanityChecks(journal, blob, size)) != JOURNAL_STATUS_OK) { 00284 return rc; 00285 } 00286 00287 journal->log.blob = blob; 00288 journal->log.sizeofBlob = size; 00289 00290 if (journal->prevCommand != FLASH_JOURNAL_OPCODE_LOG_BLOB) { 00291 /* 00292 * This is the first log in the sequence. We have to begin by identifying a new slot and erasing it. 00293 */ 00294 00295 /* choose the next slot */ 00296 uint32_t logBlobIndex = journal->currentBlobIndex + 1; 00297 if (logBlobIndex == journal->numSlots) { 00298 logBlobIndex = 0; 00299 } 00300 00301 /* setup an erase for the slot */ 00302 journal->log.mtdEraseOffset = SLOT_ADDRESS(journal, logBlobIndex); 00303 journal->state = SEQUENTIAL_JOURNAL_STATE_LOGGING_ERASE; /* start with erasing the log region */ 00304 journal->prevCommand = FLASH_JOURNAL_OPCODE_LOG_BLOB; 00305 } else { 00306 /* This is a continuation of an ongoing logging sequence. */ 00307 journal->log.dataBeingLogged = blob; 00308 journal->log.amountLeftToLog = size; 00309 } 00310 00311 /* progress the state machine for log() */ 00312 return flashJournalStrategySequential_log_progress(); 00313 } 00314 00315 int32_t flashJournalStrategySequential_commit(FlashJournal_t *_journal) 00316 { 00317 SequentialFlashJournal_t *journal; 00318 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00319 00320 int32_t rc; 00321 if ((rc = flashJournalStrategySequential_commit_sanityChecks(journal)) != JOURNAL_STATUS_OK) { 00322 return rc; 00323 } 00324 00325 if (journal->prevCommand == FLASH_JOURNAL_OPCODE_LOG_BLOB) { 00326 /* the tail has already been setup during previous calls to log(); we can now include it in the crc32. */ 00327 journal->log.tail.crc32 = flashJournalCrcCummulative((const unsigned char *)&journal->log.tail, sizeof(SequentialFlashJournalLogTail_t)); 00328 flashJournalCrcReset(); 00329 00330 journal->log.mtdOffset = journal->log.mtdTailOffset; 00331 journal->log.dataBeingLogged = (const uint8_t *)&journal->log.tail; 00332 journal->log.amountLeftToLog = sizeof(SequentialFlashJournalLogTail_t); 00333 journal->state = SEQUENTIAL_JOURNAL_STATE_LOGGING_TAIL; 00334 } else { 00335 uint32_t logBlobIndex = journal->currentBlobIndex + 1; 00336 if (logBlobIndex == journal->numSlots) { 00337 logBlobIndex = 0; 00338 } 00339 journal->log.mtdEraseOffset = SLOT_ADDRESS(journal, logBlobIndex); 00340 journal->state = SEQUENTIAL_JOURNAL_STATE_LOGGING_ERASE; 00341 } 00342 00343 journal->prevCommand = FLASH_JOURNAL_OPCODE_COMMIT; 00344 return flashJournalStrategySequential_log_progress(); 00345 } 00346 00347 int32_t flashJournalStrategySequential_reset(FlashJournal_t *_journal) 00348 { 00349 SequentialFlashJournal_t *journal; 00350 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00351 00352 journal->state = SEQUENTIAL_JOURNAL_STATE_RESETING; 00353 00354 journal->prevCommand = FLASH_JOURNAL_OPCODE_RESET; 00355 return flashJournalStrategySequential_reset_progress(); 00356 } 00357 00358 int32_t mtdGetTotalCapacity(ARM_DRIVER_STORAGE *mtd, uint64_t *capacityP) 00359 { 00360 /* fetch MTD's INFO */ 00361 ARM_STORAGE_INFO mtdInfo; 00362 int32_t rc = mtd->GetInfo(&mtdInfo); 00363 if (rc != ARM_DRIVER_OK) { 00364 return JOURNAL_STATUS_STORAGE_API_ERROR; 00365 } 00366 *capacityP = mtdInfo.total_storage; 00367 00368 return JOURNAL_STATUS_OK; 00369 } 00370 00371 int32_t flashJournalStrategySequential_format_sanityChecks(ARM_DRIVER_STORAGE *mtd, uint32_t numSlots) 00372 { 00373 /* 00374 * basic parameter checking 00375 */ 00376 if ((mtd == NULL) || (numSlots == 0)) { 00377 return JOURNAL_STATUS_PARAMETER; 00378 } 00379 00380 ARM_STORAGE_INFO mtdInfo; 00381 if (mtd->GetInfo(&mtdInfo) < ARM_DRIVER_OK) { 00382 return JOURNAL_STATUS_STORAGE_API_ERROR; 00383 } 00384 if (mtdInfo.total_storage == 0) { 00385 return JOURNAL_STATUS_STORAGE_API_ERROR; 00386 } 00387 00388 uint64_t mtdAddr; 00389 if (mtdGetStartAddr(mtd, &mtdAddr) < JOURNAL_STATUS_OK) { 00390 return JOURNAL_STATUS_STORAGE_API_ERROR; 00391 } 00392 if (mtd->GetBlock(mtdAddr, NULL) < ARM_DRIVER_OK) { /* check validity of journal's start address */ 00393 return JOURNAL_STATUS_PARAMETER; 00394 } 00395 if (mtd->GetBlock(mtdAddr + mtdInfo.total_storage - 1, NULL) < ARM_DRIVER_OK) { /* check validity of the journal's end address */ 00396 return JOURNAL_STATUS_PARAMETER; 00397 } 00398 00399 if ((mtdAddr % mtdInfo.program_unit) != 0) { /* ensure that the journal starts at a programmable unit */ 00400 return JOURNAL_STATUS_PARAMETER; 00401 } 00402 if ((mtdAddr % LCM_OF_ALL_ERASE_UNITS) != 0) { /* ensure that the journal starts and ends at an erase-boundary */ 00403 return JOURNAL_STATUS_PARAMETER; 00404 } 00405 00406 return JOURNAL_STATUS_OK; 00407 } 00408 00409 int32_t flashJournalStrategySequential_read_sanityChecks(SequentialFlashJournal_t *journal, const void *blob, size_t sizeofBlob) 00410 { 00411 if ((journal == NULL) || (blob == NULL) || (sizeofBlob == 0)) { 00412 return JOURNAL_STATUS_PARAMETER; 00413 } 00414 if ((journal->state == SEQUENTIAL_JOURNAL_STATE_NOT_INITIALIZED) || (journal->state == SEQUENTIAL_JOURNAL_STATE_INIT_SCANNING_LOG_HEADERS)) { 00415 return JOURNAL_STATUS_NOT_INITIALIZED; 00416 } 00417 if (journal->state != SEQUENTIAL_JOURNAL_STATE_INITIALIZED) { 00418 return JOURNAL_STATUS_ERROR; /* journal is in an un-expected state. */ 00419 } 00420 // printf("read sanity checks: logicalOffset = %lu, sizeofJournaledBlob = %lu\n", (uint32_t)journal->read.logicalOffset, (uint32_t)journal->info.sizeofJournaledBlob); 00421 if ((journal->info.sizeofJournaledBlob == 0) || (journal->read.logicalOffset >= journal->info.sizeofJournaledBlob)) { 00422 journal->read.logicalOffset = 0; 00423 return JOURNAL_STATUS_EMPTY; 00424 } 00425 00426 return JOURNAL_STATUS_OK; 00427 } 00428 00429 int32_t flashJournalStrategySequential_log_sanityChecks(SequentialFlashJournal_t *journal, const void *blob, size_t sizeofBlob) 00430 { 00431 if ((journal == NULL) || (blob == NULL) || (sizeofBlob == 0)) { 00432 return JOURNAL_STATUS_PARAMETER; 00433 } 00434 if ((journal->state == SEQUENTIAL_JOURNAL_STATE_NOT_INITIALIZED) || (journal->state == SEQUENTIAL_JOURNAL_STATE_INIT_SCANNING_LOG_HEADERS)) { 00435 return JOURNAL_STATUS_NOT_INITIALIZED; 00436 } 00437 if ((journal->state != SEQUENTIAL_JOURNAL_STATE_INITIALIZED) && (journal->state != SEQUENTIAL_JOURNAL_STATE_LOGGING_BODY)) { 00438 return JOURNAL_STATUS_ERROR; /* journal is in an un-expected state. */ 00439 } 00440 if (journal->state == SEQUENTIAL_JOURNAL_STATE_INITIALIZED) { 00441 if (sizeofBlob > journal->info.capacity) { 00442 return JOURNAL_STATUS_BOUNDED_CAPACITY; /* adding this log chunk would cause us to exceed capacity (write past the tail). */ 00443 } 00444 } else if (journal->state == SEQUENTIAL_JOURNAL_STATE_LOGGING_BODY) { 00445 if (journal->log.mtdOffset + sizeofBlob > journal->log.mtdTailOffset) { 00446 return JOURNAL_STATUS_BOUNDED_CAPACITY; /* adding this log chunk would cause us to exceed capacity (write past the tail). */ 00447 } 00448 } 00449 00450 /* ensure that the request is at least as large as the minimum program unit */ 00451 if (sizeofBlob < journal->info.program_unit) { 00452 return JOURNAL_STATUS_SMALL_LOG_REQUEST; 00453 } 00454 00455 return JOURNAL_STATUS_OK; 00456 } 00457 00458 int32_t flashJournalStrategySequential_commit_sanityChecks(SequentialFlashJournal_t *journal) 00459 { 00460 if (journal == NULL) { 00461 return JOURNAL_STATUS_PARAMETER; 00462 } 00463 if (journal->state == SEQUENTIAL_JOURNAL_STATE_LOGGING_BODY) { 00464 if (journal->prevCommand != FLASH_JOURNAL_OPCODE_LOG_BLOB) { 00465 return JOURNAL_STATUS_ERROR; 00466 } 00467 if ((journal->log.mtdOffset == ARM_STORAGE_INVALID_OFFSET) || 00468 (journal->log.mtdTailOffset == ARM_STORAGE_INVALID_OFFSET) || 00469 (journal->log.mtdTailOffset < journal->log.mtdOffset) || 00470 (journal->log.tail.sizeofBlob == 0) || 00471 (journal->log.tail.sizeofBlob > journal->info.capacity)) { 00472 return JOURNAL_STATUS_ERROR; /* journal is in an un-expected state. */ 00473 } 00474 } 00475 00476 return JOURNAL_STATUS_OK; 00477 }
Generated on Sun Jul 17 2022 08:25:31 by 1.7.2