Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 Tue Jul 12 2022 12:45:49 by
