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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
flash_journal.h
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 #ifndef __FLASH_JOURNAL_H__ 00019 #define __FLASH_JOURNAL_H__ 00020 00021 #ifdef __cplusplus 00022 extern "C" { 00023 #endif // __cplusplus 00024 00025 #include "storage_abstraction/Driver_Storage.h" 00026 #include <stdint.h> 00027 00028 /** 00029 * General return codes. All Flash-Journal APIs return an int32_t to allow for 00030 * both error and success status returns. This enumeration contains all 00031 * possible error status values. 00032 */ 00033 typedef enum _FlashJournal_Status 00034 { 00035 JOURNAL_STATUS_OK = 0, 00036 JOURNAL_STATUS_ERROR = -1, ///< Unspecified error 00037 JOURNAL_STATUS_BUSY = -2, ///< Underlying storage is currently unavailable 00038 JOURNAL_STATUS_TIMEOUT = -3, ///< Timeout occurred 00039 JOURNAL_STATUS_UNSUPPORTED = -4, ///< Operation not supported 00040 JOURNAL_STATUS_PARAMETER = -5, ///< Parameter error 00041 JOURNAL_STATUS_BOUNDED_CAPACITY = -6, ///< Attempt to write larger than available capacity 00042 JOURNAL_STATUS_STORAGE_API_ERROR = -7, ///< Failure from some Storage API 00043 JOURNAL_STATUS_STORAGE_IO_ERROR = -8, ///< Failure from underlying storage during an IO operation. 00044 JOURNAL_STATUS_NOT_INITIALIZED = -9, ///< journal not initialized 00045 JOURNAL_STATUS_EMPTY = -10, ///< There is no further data to read 00046 JOURNAL_STATUS_SMALL_LOG_REQUEST = -11, ///< log request is smaller than the program_unit of the underlying MTD block. 00047 } FlashJournal_Status_t; 00048 00049 /** 00050 * Command opcodes for flash. Completion callbacks use these codes to refer to 00051 * completing commands. Refer to \ref ARM_Flash_Callback_t. 00052 */ 00053 typedef enum _FlashJournal_OpCode { 00054 FLASH_JOURNAL_OPCODE_INITIALIZE, 00055 FLASH_JOURNAL_OPCODE_GET_INFO, 00056 FLASH_JOURNAL_OPCODE_READ_BLOB, 00057 FLASH_JOURNAL_OPCODE_LOG_BLOB, 00058 FLASH_JOURNAL_OPCODE_COMMIT, 00059 FLASH_JOURNAL_OPCODE_RESET, 00060 } FlashJournal_OpCode_t; 00061 00062 /** 00063 * @brief Flash Journal information. This contains journal-metadata, and is the 00064 * return value from calling GetInfo() on the journal driver. 00065 */ 00066 typedef struct _FlashJournal_Info { 00067 uint64_t capacity; ///< Maximum capacity (in octets) of the flash journal--i.e. the largest 'blob' which can be contained as payload. 00068 uint64_t sizeofJournaledBlob; ///< size (in octets) of the most recently logged blob. 00069 uint32_t program_unit; ///< Minimum programming size (in units of octets) for 00070 ///< the current storage block--the one which will be used 00071 ///< for the next log() operation. This value may change as we 00072 ///< cycle through the blocks of the underlying MTD. 00073 ///< Callers of FlashJournal_log() should refer to this field 00074 ///< upon receiving the error JOURNAL_STATUS_SMALL_LOG_REQUEST 00075 ///< (of when the actual amount of data logged is smaller than 00076 ///< the requested amount). 00077 } FlashJournal_Info_t; 00078 00079 /** 00080 * This is the type of the command completion callback handler for the 00081 * asynchronous flash-journal APIs: initialize(), read(), log(), commit() and 00082 * reset() (which is nearly all APIs). 00083 * 00084 * @param status 00085 * A code to indicate the status of the completed operation. For data 00086 * transfer operations, the status field is overloaded in case of 00087 * success to return the amount of data successfully transferred; this 00088 * can be done safely because error codes are negative values. 00089 * 00090 * @param cmd_code 00091 * The command op-code of type FlashJournal_OpCode_t. This value isn't 00092 * essential for the callback, but it is expected that this information 00093 * could be a quick and useful filter. 00094 */ 00095 typedef void (*FlashJournal_Callback_t)(int32_t status, FlashJournal_OpCode_t cmd_code); 00096 00097 /* forward declarations. */ 00098 typedef struct _FlashJournal_t FlashJournal_t; 00099 typedef struct _FlashJournal_Ops_t FlashJournal_Ops_t; 00100 00101 /** 00102 * @ref FlashJournal_t is an abstraction implemented by a table of generic 00103 * operations (i.e. strategy) together with an opaque, strategy-specific 00104 * data. Taken together, the FlashJournal_t is an opaque handle containing 00105 * such top-level metadata. 00106 * 00107 * Algorithms depending on the FlashJournal can be generic (i.e. independent of 00108 * the strategy) in their use of the Flash-Journal APIs. For the sake of being 00109 * able to allocate a FlashJournal_t for use in such generic algorithms, the 00110 * FlashJournal_t contains a MAX_SIZE to accommodate the largest of the 00111 * strategy-specific metadata. The value of this MAX_SIZE may need to be 00112 * increased if some future journal-strategy needs more metadata. 00113 */ 00114 #define FLASH_JOURNAL_HANDLE_MAX_SIZE 140 00115 00116 /** 00117 * This is the set of operations offered by the flash-journal abstraction. A set 00118 * of implementations for these operations defines a logging strategy. 00119 */ 00120 typedef struct _FlashJournal_Ops_t { 00121 /** 00122 * \brief Initialize the flash journal. Refer to @ref FlashJournal_initialize. 00123 */ 00124 int32_t (*initialize)(FlashJournal_t *journal, ARM_DRIVER_STORAGE *mtd, const FlashJournal_Ops_t *ops, FlashJournal_Callback_t callback); 00125 00126 /** 00127 * \brief fetch journal metadata. Refer to @ref FlashJournal_getInfo. 00128 */ 00129 FlashJournal_Status_t (*getInfo) (FlashJournal_t *journal, FlashJournal_Info_t *info); 00130 00131 /** 00132 * @brief Read from the most recently logged blob. Refer to @ref FlashJournal_read. 00133 */ 00134 int32_t (*read) (FlashJournal_t *journal, void *buffer, size_t size); 00135 00136 /** 00137 * @brief Start logging a new blob or append to the one currently being logged. Refer to @ref FlashJournal_log. 00138 */ 00139 int32_t (*log) (FlashJournal_t *journal, const void *blob, size_t size); 00140 00141 /** 00142 * @brief commit a blob accumulated through a non-empty sequence of 00143 * previously successful log() operations. Refer to @ref FlashJournal_commit. 00144 */ 00145 int32_t (*commit) (FlashJournal_t *journal); 00146 00147 /** 00148 * @brief Reset the journal. This has the effect of erasing all valid blobs. 00149 * Refer to @ref FlashJournal_reset. 00150 */ 00151 int32_t (*reset) (FlashJournal_t *journal); 00152 } FlashJournal_Ops_t; 00153 00154 /** 00155 * @brief An opaque handle constituting the Flash Journal. 00156 * 00157 * @details This structure is intentionally opaque to avoid exposing data 00158 * internal to an implementation strategy; this prevents accesses through any 00159 * means other than through the defined API. 00160 * 00161 * Having a known size for the handle allows the caller to remain malloc-free. 00162 * 00163 * @note: There should be static asserts in the code to verify our assumption 00164 * that the real FlashJournal handle fits within FLASH_JOURNAL_HANDLE_MAX_SIZE 00165 * bytes. 00166 * 00167 * @note: there is a risk of overallocation in case an implementation doesn't 00168 * need FLASH_JOURNAL_HANDLE_MAX_SIZE bytes, but the impact should be small. 00169 */ 00170 typedef struct _FlashJournal_t { 00171 FlashJournal_Ops_t ops; 00172 00173 union { 00174 ARM_DRIVER_STORAGE *mtd; 00175 FlashJournal_Info_t info; 00176 void *pointer; 00177 uint8_t octet; 00178 uint32_t data[FLASH_JOURNAL_HANDLE_MAX_SIZE / sizeof(uint32_t)]; 00179 } opaque; 00180 } FlashJournal_t; 00181 00182 /** 00183 * @brief Initialize a flash journal. 00184 * 00185 * This is a front-end for @ref FlashJournal_Ops_t::initialize() of the 00186 * underlying strategy. 00187 * 00188 * This function must be called *before* the middle-ware component starts 00189 * using a journal. As a part of bringing the journal to a ready state, it 00190 * also discovers the most recently logged blob. 00191 * 00192 * Initialize() receives a callback handler to be invoked upon completion of 00193 * asynchronous operations. 00194 * 00195 * @param [out] journal 00196 * A caller-supplied buffer large enough to hold an 00197 * initialized journal. The internals of the actual journal 00198 * are opaque to the caller and depend on the logging 00199 * strategy (as defined by the parameter 'ops'). This memory 00200 * should be at least as large as 'FLASH_JOURNAL_HANDLE_MAX_SIZE'. 00201 * Upon successful return, the journal is setup in an 00202 * initialized state. 00203 * 00204 * @param [in] mtd 00205 * The underlying Storage_Driver targeted by the journal. MTD 00206 * stands for Memory-Technology-Device. 00207 * 00208 * @param [in] ops 00209 * This is the set of operations which define the logging strategy. 00210 * 00211 * @param [in] callback 00212 * Caller-defined callback to be invoked upon command completion of 00213 * initialization; and also for all future invocations of 00214 * asynchronous APIs. Use a NULL pointer when no 00215 * callback signals are required. 00216 * 00217 * @note: this is an asynchronous operation, but it can finish 00218 * synchronously if the underlying MTD supports that. 00219 * 00220 * @return 00221 * The function executes in the following ways: 00222 * - When the operation is asynchronous, the function only starts the 00223 * initialization and control returns to the caller with an 00224 * JOURNAL_STATUS_OK before the actual completion of the operation (or 00225 * with an appropriate error code in case of failure). When the 00226 * operation is completed the command callback is invoked with 00227 * JOURNAL_STATUS_OK passed in as the 'status' parameter of the 00228 * callback. In case of errors, the completion callback is invoked with 00229 * an error status. 00230 * - When the operation is executed by the journal in a blocking (i.e. 00231 * synchronous) manner, control returns to the caller only upon the actual 00232 * completion of the operation or the discovery of a failure condition. In 00233 * this case, the function returns 1 to signal successful synchronous 00234 * completion or an appropriate error code, and no further 00235 * invocation of the completion callback should be expected at a later time. 00236 * 00237 * Here's a code snippet to suggest how this API might be used by callers: 00238 * \code 00239 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00240 * int32_t returnValue = FlashJournal_initialize(&journal, MTD, &STRATEGY_SEQUENTIAL, callbackHandler); 00241 * if (returnValue < JOURNAL_STATUS_OK) { 00242 * // handle error 00243 * } else if (returnValue == JOURNAL_STATUS_OK) { 00244 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00245 * // handle early return from asynchronous execution 00246 * } else { 00247 * ASSERT(returnValue == 1); 00248 * // handle synchronous completion 00249 * } 00250 * \endcode 00251 */ 00252 static inline int32_t FlashJournal_initialize(FlashJournal_t *journal, 00253 ARM_DRIVER_STORAGE *mtd, 00254 const FlashJournal_Ops_t *ops, 00255 FlashJournal_Callback_t callback) 00256 { 00257 return ops->initialize(journal, mtd, ops, callback); 00258 } 00259 00260 /** 00261 * @brief Fetch journal metadata. A front-end for @ref FlashJournal_Ops_t::getInfo(). 00262 * 00263 * @param [in] journal 00264 * A previously initialized journal. 00265 * 00266 * @param [out] info 00267 * A caller-supplied buffer capable of being filled in with an 00268 * FlashJournal_Info_t. 00269 * 00270 * @return JOURNAL_STATUS_OK if a FlashJournal_Info_t structure containing 00271 * top level metadata about the journal is filled into the supplied 00272 * buffer, else an appropriate error value. 00273 * 00274 * @note It is the caller's responsibility to ensure that the buffer passed in 00275 * is able to be initialized with a FlashJournal_Info_t. 00276 * 00277 * @note getInfo()s can still be called during a sequence of 00278 * log()s. 00279 * 00280 * @note This API returns synchronously--it does not result in an invocation 00281 * of a completion callback. 00282 * 00283 * Here's a code snippet to suggest how this API might be used by callers: 00284 * \code 00285 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00286 * FlashJournal_Info_t info; 00287 * int32_t returnValue = FlashJournal_getInfo(&journal, &info); 00288 * if (returnValue < JOURNAL_STATUS_OK) { 00289 * // handle error 00290 * } else { 00291 * ASSERT(returnValue == JOURNAL_STATUS_OK); 00292 * // work with the 'info'. 00293 * } 00294 * \endcode 00295 */ 00296 static inline FlashJournal_Status_t FlashJournal_getInfo(FlashJournal_t *journal, FlashJournal_Info_t *info) 00297 { 00298 return journal->ops.getInfo(journal, info); 00299 } 00300 00301 /** 00302 * @brief Read from the most recently logged blob. A front-end for @ref 00303 * FlashJournal_Ops_t::read(). 00304 * 00305 * @details Read off a chunk of the logged blob sequentially. The blob may 00306 * be larger than the size of the read (or even of available SRAM), so 00307 * multiple calls to read() could be necessary before the entire blob is 00308 * read off. The journal maintains a read-pointer internally to allow 00309 * reads to continue where the previous one left off. 00310 * 00311 * @note: Once the entire blob is read, the final read() returns the error 00312 * JOURNAL_STATUS_EMPTY (or passes that value as the status of a 00313 * completion callback) and resets the read-pointer to allow re-reading 00314 * the blob from the start. 00315 * 00316 * @param [in] journal 00317 * A previously initialized journal. 00318 * 00319 * @param [out] buffer 00320 * The destination of the read operation. The memory is owned 00321 * by the caller and should remain valid for the lifetime 00322 * of this operation. 00323 * 00324 * @param [in] size 00325 * The maximum amount of data which can be read in this 00326 * operation. The memory pointed to by 'buffer' should be as 00327 * large as this amount. 00328 * 00329 * @return 00330 * The function executes in the following ways: 00331 * - When the operation is asynchronous--i.e. when the underlying MTD's 00332 * ARM_STOR_CAPABILITIES::asynchronous_ops is set to 1--and the operation 00333 * executed by the journal in a non-blocking (i.e. asynchronous) manner, 00334 * control returns to the caller with JOURNAL_STATUS_OK before the actual 00335 * completion of the operation (or with an appropriate error code in case of 00336 * failure). When the operation completes, the command callback is 00337 * invoked with the number of successfully transferred bytes passed in as 00338 * the 'status' parameter of the callback. If any error is encountered 00339 * after the launch of an asynchronous operation, the completion callback 00340 * is invoked with an error status. 00341 * - When the operation is executed by the journal in a blocking (i.e. 00342 * synchronous) manner, control returns to the caller only upon the 00343 * actual completion of the operation, or the discovery of a failure 00344 * condition. In synchronous mode, the function returns the number 00345 * of data items read or an appropriate error code. 00346 * 00347 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00348 * is set then this operation may execute asynchronously. In the case of 00349 * asynchronous operation, the invocation returns early (with 00350 * JOURNAL_STATUS_OK) and results in a completion callback later. 00351 * 00352 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00353 * is set, the journal is not required to operate asynchronously. A Read 00354 * operation can be finished synchronously in spite of 00355 * ARM_STORAGE_CAPABILITIES::asynchronous_ops being set, returning the 00356 * number of data items read to indicate successful completion, or an 00357 * appropriate error code. In this case no further invocation of a 00358 * completion callback should be expected at a later time. 00359 * 00360 * Here's a code snippet to suggest how this API might be used by callers: 00361 * \code 00362 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00363 * int32_t returnValue = FlashJournal_read(&journal, buffer, size); 00364 * if (returnValue < JOURNAL_STATUS_OK) { 00365 * // handle error 00366 * } else if (returnValue == JOURNAL_STATUS_OK) { 00367 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00368 * // handle early return from asynchronous execution 00369 * } else { 00370 * ASSERT(returnValue == size); 00371 * // handle synchronous completion 00372 * } 00373 * \endcode 00374 */ 00375 static inline int32_t FlashJournal_read(FlashJournal_t *journal, void *blob, size_t n) 00376 { 00377 return journal->ops.read(journal, blob, n); 00378 } 00379 00380 /** 00381 * @brief Start logging a new blob or append to the one currently being logged. 00382 * A front-end for @ref FlashJournal_Ops_t::log(). 00383 * 00384 * @details Extend (or start off) the currently logged blob sequentially. 00385 * There could be several calls to log() before the entire blob is 00386 * accumulated. A sequence of one or more log() must be terminated by a 00387 * commit() before the state of the blob is sealed and made persistent. 00388 * The journal maintains a log-pointer internally to allow 00389 * log()s to continue where the previous one left off. 00390 * 00391 * @param [in] journal 00392 * A previously initialized journal. 00393 * 00394 * @param [in] blob 00395 * The source of the log operation. The memory is owned 00396 * by the caller and should remain valid for the lifetime 00397 * of this operation. 00398 * 00399 * @param [in] size 00400 * The amount of data being logged in this operation. The 00401 * buffer pointed to by 'blob' should be as large as this 00402 * amount. 00403 * 00404 * @return [please be sure to read notes (below) regarding other return values] 00405 * The function executes in the following ways: 00406 * - When the operation is asynchronous--i.e. when the underlying MTD's 00407 * ARM_STOR_CAPABILITIES::asynchronous_ops is set to 1--and the operation 00408 * executed by the journal in a non-blocking (i.e. asynchronous) manner, 00409 * control returns to the caller with JOURNAL_STATUS_OK before the actual 00410 * completion of the operation (or with an appropriate error code in case of 00411 * failure). When the operation completes, the command callback is 00412 * invoked with the number of successfully transferred bytes passed in as 00413 * the 'status' parameter of the callback. If any error is encountered 00414 * after the launch of an asynchronous operation, the completion callback 00415 * is invoked with an error status. 00416 * - When the operation is executed by the journal in a blocking (i.e. 00417 * synchronous) manner, control returns to the caller only upon the actual 00418 * completion of the operation, or the discovery of a failure condition. In 00419 * synchronous mode, the function returns the number of data items 00420 * logged, or an appropriate error code. 00421 * 00422 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00423 * is set then this operation may execute asynchronously. In the case of 00424 * asynchronous operation, the invocation returns early (with 00425 * JOURNAL_STATUS_OK) and results in a completion callback later. 00426 * 00427 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00428 * is set, the journal is not required to operate asynchronously. A log 00429 * operation can be finished synchronously in spite of 00430 * ARM_STORAGE_CAPABILITIES::asynchronous_ops being set, returning the 00431 * number of data items logged to indicate successful completion, or an 00432 * appropriate error code. In this case no further invocation of a 00433 * completion callback should be expected at a later time. 00434 * 00435 * @note If a log operation will exceed available capacity, it fails with the 00436 * error JOURNAL_STATUS_BOUNDED_CAPACITY. 00437 * 00438 * @note The actual size of data transfer (as reported by the status 00439 * parameter of the callback or the return value from log() in case of 00440 * synchronous operation) may be smaller than the amount requested. This 00441 * could be due to the 'program_unit' of the underlying storage block-- 00442 * i.e. the minimum programmable size. Refer to @ref 00443 * FlashJournal_Info_t::program_unit. It is the caller's responsibility 00444 * for resubmitting this left-over data in a subsequent call to log. 00445 * When logging an arbitrary amount of data, the last of a sequence of 00446 * logs may need to be padded in order to align with the 00447 * programming unit. 00448 * 00449 * @note If the total size requested to be logged is smaller 00450 * than the MTD's program_unit, log() fails with an error value of 00451 * JOURNAL_STATUS_SMALL_LOG_REQUEST. 00452 * 00453 * @note the data being logged isn't made persistent (or available for read- 00454 * backs) until a commit. A sequence of log() operations is expected to end 00455 * in a commit(). A new sequence of log()s should be initiated by the caller 00456 * only after a commit() has completed. If a sequence of logs() is followed 00457 * by an operation other than a commit, that operation will very likely 00458 * return an error code. getInfo()s can still be called during a sequence of 00459 * log()s. 00460 * 00461 * Here's a code snippet to suggest how this API might be used by callers: 00462 * \code 00463 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00464 * int32_t returnValue = FlashJournal_log(&journal, buffer, size); 00465 * if (returnValue < JOURNAL_STATUS_OK) { 00466 * // handle error 00467 * } else if (returnValue == JOURNAL_STATUS_OK) { 00468 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00469 * // handle early return from asynchronous execution 00470 * } else { 00471 * ASSERT(returnValue <= size); 00472 * // handle synchronous completion 00473 * 00474 * if (returnValue < size) { 00475 * #if DEBUG 00476 * FlashJournal_Info_t info; 00477 * int32_t rc = FlashJournal_getInfo(&journal, &info); 00478 * ASSERT(rc == JOURNAL_STATUS_OK); 00479 * ASSERT(returnValue == (size - (size % info.program_unit))); 00480 * #endif 00481 * // move the last (size - returnValue) bytes of the buffer to the 00482 * // beginning of the buffer to be used for the successive request. 00483 * } 00484 * } 00485 * \endcode 00486 */ 00487 static inline int32_t FlashJournal_log(FlashJournal_t *journal, const void *blob, size_t n) 00488 { 00489 return journal->ops.log(journal, blob, n); 00490 } 00491 00492 /** 00493 * @brief Commit a blob accumulated through a (possibly empty) sequence of previously 00494 * successful log() operations. A front-end for @ref FlashJournal_Ops_t::commit(). 00495 * 00496 * @param [in] journal 00497 * A previously initialized journal. 00498 * 00499 * @return 00500 * The function executes in the following ways: 00501 * - When the operation is asynchronous--i.e. when the underlying MTD's 00502 * ARM_STOR_CAPABILITIES::asynchronous_ops is set to 1--and the operation 00503 * executed by the journal in a non-blocking (i.e. asynchronous) manner, 00504 * control returns to the caller with JOURNAL_STATUS_OK before the actual 00505 * completion of the operation (or with an appropriate error code in case of 00506 * failure). When the operation completes, the command callback is invoked 00507 * with 1 passed in as the 'status' parameter of the callback to indicate 00508 * success. If any error is encountered after the launch of an asynchronous 00509 * operation, the completion callback is invoked with an error status. 00510 * - When the operation is executed by the journal in a blocking (i.e. 00511 * synchronous) manner, control returns to the caller only upon the actual 00512 * completion of the operation, or the discovery of a failure condition. In 00513 * synchronous mode, the function returns 1 to indicate success, or an 00514 * appropriate error code. 00515 * 00516 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00517 * is set then this operation may execute asynchronously. In the case of 00518 * asynchronous operation, the invocation returns early (with 00519 * JOURNAL_STATUS_OK) and results in a completion callback later. 00520 * 00521 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00522 * is set, the journal is not required to operate asynchronously. A 00523 * commit operation can be finished synchronously in spite of 00524 * ARM_STORAGE_CAPABILITIES::asynchronous_ops being set, returning the 00525 * total size of the committed blob to indicate successful completion, 00526 * or an appropriate error code. In this case no further invocation of a 00527 * completion callback should be expected at a later time. 00528 * 00529 * Here's a code snippet to suggest how this API might be used by callers: 00530 * \code 00531 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00532 * int32_t returnValue = FlashJournal_commit(&journal); 00533 * if (returnValue < JOURNAL_STATUS_OK) { 00534 * // handle error 00535 * } else if (returnValue == JOURNAL_STATUS_OK) { 00536 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00537 * // handle early return from asynchronous execution 00538 * } else { 00539 * // handle synchronous completion 00540 * ASSERT(returnValue == 1); 00541 * ... 00542 * } 00543 * \endcode 00544 * 00545 * @note A sequence of log() operations is expected to end in a commit(). A new 00546 * sequence of log()s should be initiated by the caller only after a 00547 * commit() has completed. If a sequence of logs() is followed 00548 * by an operation other than a commit, that operation will very likely 00549 * return an error code. 00550 */ 00551 static inline int32_t FlashJournal_commit(FlashJournal_t *journal) 00552 { 00553 return journal->ops.commit(journal); 00554 } 00555 00556 /** 00557 * @brief Reset the journal. This has the effect of erasing all valid blobs. A 00558 * front-end for @ref FlashJournal_Ops_t::reset(). 00559 * 00560 * @param [in] journal 00561 * A previously initialized journal. 00562 * 00563 * @return 00564 * The function executes in the following ways: 00565 * - When the operation is asynchronous--i.e. when the underlying MTD's 00566 * ARM_STOR_CAPABILITIES::asynchronous_ops is set to 1--and the 00567 * operation executed by the journal in a non-blocking (i.e. 00568 * asynchronous) manner, control returns to the caller with 00569 * JOURNAL_STATUS_OK before the actual completion of the operation (or 00570 * with an appropriate error code in case of failure). When the 00571 * operation completes, the command callback is invoked with 00572 * JOURNAL_STATUS_OK passed in as the 'status' parameter of the 00573 * callback. If any error is encountered after the launch of an 00574 * asynchronous operation, the completion callback is invoked with an 00575 * error status. 00576 * - When the operation is executed by the journal in a blocking (i.e. 00577 * synchronous) manner, control returns to the caller only upon the 00578 * actual completion of the operation, or the discovery of a failure 00579 * condition. In synchronous mode, the function returns 1 to signal 00580 * successful completion, or an appropriate error code. 00581 * 00582 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00583 * is set then this operation may execute asynchronously. In the case of 00584 * asynchronous operation, the invocation returns early (with 00585 * JOURNAL_STATUS_OK) and results in a completion callback later. 00586 * 00587 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00588 * is set, the journal is not required to operate asynchronously. A 00589 * reset operation can be finished synchronously in spite of 00590 * ARM_STORAGE_CAPABILITIES::asynchronous_ops being set, returning 1 to 00591 * indicate successful completion, or an appropriate error code. In this 00592 * case no further invocation of a completion callback should be 00593 * expected at a later time. 00594 * 00595 * Here's a code snippet to suggest how this API might be used by callers: 00596 * \code 00597 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00598 * int32_t returnValue = FlashJournal_reset(&journal); 00599 * if (returnValue < JOURNAL_STATUS_OK) { 00600 * // handle error 00601 * } else if (returnValue == JOURNAL_STATUS_OK) { 00602 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00603 * // handle early return from asynchronous execution 00604 * } else { 00605 * ASSERT(returnValue == 1); 00606 * // handle synchronous completion 00607 * } 00608 * \endcode 00609 */ 00610 static inline int32_t FlashJournal_reset(FlashJournal_t *journal) 00611 { 00612 return journal->ops.reset(journal); 00613 } 00614 00615 #ifdef __cplusplus 00616 } 00617 #endif // __cplusplus 00618 00619 #endif /* __FLASH_JOURNAL_H__ */
Generated on Tue Jul 12 2022 12:28:31 by
1.7.2
