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.
Fork of OmniWheels 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 "mbed_toolchain.h" /* required for MBED_DEPRECATED_SINCE */ 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 JOURNAL_STATUS_NOT_FORMATTED = -12, ///< need to call xxx_format() before using the journal. 00048 JOURNAL_STATUS_METADATA_ERROR = -13, ///< sanity checks for the journal metadata failed. 00049 JOURNAL_STATUS_STORAGE_RUNTIME_OR_INTEGRITY_FAILURE = -14, ///< validation or run-time errors arising from the badkend media. 00050 } FlashJournal_Status_t; 00051 00052 /** 00053 * Command opcodes for flash. Completion callbacks use these codes to refer to 00054 * completing commands. Refer to \ref ARM_Flash_Callback_t. 00055 */ 00056 typedef enum _FlashJournal_OpCode { 00057 FLASH_JOURNAL_OPCODE_FORMAT, 00058 FLASH_JOURNAL_OPCODE_INITIALIZE, 00059 FLASH_JOURNAL_OPCODE_GET_INFO, 00060 FLASH_JOURNAL_OPCODE_READ_BLOB, 00061 FLASH_JOURNAL_OPCODE_LOG_BLOB, 00062 FLASH_JOURNAL_OPCODE_COMMIT, 00063 FLASH_JOURNAL_OPCODE_RESET, 00064 } FlashJournal_OpCode_t; 00065 00066 /** 00067 * @brief Flash Journal information. This contains journal-metadata, and is the 00068 * return value from calling GetInfo() on the journal driver. 00069 */ 00070 typedef struct _FlashJournal_Info { 00071 uint64_t capacity; ///< Maximum capacity (in octets) of the flash journal--i.e. the largest 'blob' which can be contained as payload. 00072 uint64_t sizeofJournaledBlob; ///< size (in octets) of the most recently logged blob. 00073 uint32_t program_unit; ///< Minimum programming size (in units of octets) for 00074 ///< the current storage block--the one which will be used 00075 ///< for the next log() operation. This value may change as we 00076 ///< cycle through the blocks of the underlying MTD. 00077 ///< Callers of FlashJournal_log() should refer to this field 00078 ///< upon receiving the error JOURNAL_STATUS_SMALL_LOG_REQUEST 00079 ///< (of when the actual amount of data logged is smaller than 00080 ///< the requested amount). 00081 } FlashJournal_Info_t; 00082 00083 00084 static const uint32_t FLASH_JOURNAL_HEADER_MAGIC = 0xA00AEE1DUL; 00085 static const uint32_t FLASH_JOURNAL_HEADER_VERSION = 1; 00086 00087 /** 00088 * Meta-data placed at the head of a Journal. The actual header would be an 00089 * extension of this generic header, and would depend on the implementation 00090 * strategy. Initialization algorithms can expect to find this generic header at 00091 * the start of every Journal. 00092 */ 00093 typedef struct _FlashJournalHeader { 00094 uint32_t magic; /** Journal-header specific magic code */ 00095 uint32_t version; /** Revision number for this generic journal header. */ 00096 uint64_t totalSize; /** Total space (in bytes) occupied by the journal, including the header. 00097 * Both 'mtdOffset' and 'mtdOffset + totalSize' should 00098 * lie on erase boundaries. */ 00099 uint32_t sizeofHeader; /** The size of the journal header; this is expected to be larger than this generic header. */ 00100 uint32_t journalOffset; /** Offset from the start of the journal header to the actual logged journal. */ 00101 uint32_t checksum; /** CRC32 over the entire flash-journal-header, including the implementation 00102 * specific extension (i.e. over 'sizeofHeader' bytes). The value of the 00103 * field is taken to be 0 for the purpose of computing the checksum. */ 00104 } FlashJournalHeader_t; 00105 00106 /** 00107 * This is the type of the command completion callback handler for the 00108 * asynchronous flash-journal APIs: initialize(), read(), log(), commit() and 00109 * reset() (which is nearly all APIs). 00110 * 00111 * @param status 00112 * A code to indicate the status of the completed operation. For data 00113 * transfer operations, the status field is overloaded in case of 00114 * success to return the amount of data successfully transferred; this 00115 * can be done safely because error codes are negative values. 00116 * 00117 * @param cmd_code 00118 * The command op-code of type FlashJournal_OpCode_t. This value isn't 00119 * essential for the callback, but it is expected that this information 00120 * could be a quick and useful filter. 00121 */ 00122 typedef void (*FlashJournal_Callback_t)(int32_t status, FlashJournal_OpCode_t cmd_code); 00123 00124 /* forward declarations. */ 00125 struct FlashJournal_t; 00126 00127 /** 00128 * @ref FlashJournal_t is an abstraction implemented by a table of generic 00129 * operations (i.e. strategy) together with an opaque, strategy-specific 00130 * data. Taken together, the FlashJournal_t is an opaque handle containing 00131 * such top-level metadata. 00132 * 00133 * Algorithms depending on the FlashJournal can be generic (i.e. independent of 00134 * the strategy) in their use of the Flash-Journal APIs. For the sake of being 00135 * able to allocate a FlashJournal_t for use in such generic algorithms, the 00136 * FlashJournal_t contains a MAX_SIZE to accommodate the largest of the 00137 * strategy-specific metadata. The value of this MAX_SIZE may need to be 00138 * increased if some future journal-strategy needs more metadata. 00139 */ 00140 #define FLASH_JOURNAL_HANDLE_MAX_SIZE 160 00141 00142 /** 00143 * This is the set of operations offered by the flash-journal abstraction. A set 00144 * of implementations for these operations defines a logging strategy. 00145 */ 00146 00147 typedef struct FlashJournal_Ops_t { 00148 /** 00149 * \brief Initialize the flash journal. Refer to @ref FlashJournal_initialize. 00150 */ 00151 int32_t (*initialize)(struct FlashJournal_t *journal, 00152 ARM_DRIVER_STORAGE *mtd, 00153 const struct FlashJournal_Ops_t *ops, 00154 FlashJournal_Callback_t callback); 00155 00156 /** 00157 * \brief fetch journal metadata. Refer to @ref FlashJournal_getInfo. 00158 */ 00159 FlashJournal_Status_t (*getInfo) (struct FlashJournal_t *journal, FlashJournal_Info_t *info); 00160 00161 /** 00162 * @brief Read from the most recently logged blob. Refer to @ref FlashJournal_read. 00163 */ 00164 int32_t (*read) (struct FlashJournal_t *journal, void *buffer, size_t size); 00165 00166 /** 00167 * @brief Read from the most recently logged blob from a particular offset. Refer to @ref FlashJournal_readFrom. 00168 */ 00169 int32_t (*readFrom) (struct FlashJournal_t *journal, size_t offset, void *buffer, size_t size); 00170 00171 /** 00172 * @brief Start logging a new blob or append to the one currently being logged. Refer to @ref FlashJournal_log. 00173 */ 00174 int32_t (*log) (struct FlashJournal_t *journal, const void *blob, size_t size); 00175 00176 /** 00177 * @brief commit a blob accumulated through a non-empty sequence of 00178 * previously successful log() operations. Refer to @ref FlashJournal_commit. 00179 */ 00180 int32_t (*commit) (struct FlashJournal_t *journal); 00181 00182 /** 00183 * @brief Reset the journal. This has the effect of erasing all valid blobs. 00184 * Refer to @ref FlashJournal_reset. 00185 */ 00186 int32_t (*reset) (struct FlashJournal_t *journal); 00187 } FlashJournal_Ops_t; 00188 00189 /** 00190 * @brief An opaque handle constituting the Flash Journal. 00191 * 00192 * @details This structure is intentionally opaque to avoid exposing data 00193 * internal to an implementation strategy; this prevents accesses through any 00194 * means other than through the defined API. 00195 * 00196 * Having a known size for the handle allows the caller to remain malloc-free. 00197 * 00198 * @note: There should be static asserts in the code to verify our assumption 00199 * that the real FlashJournal handle fits within FLASH_JOURNAL_HANDLE_MAX_SIZE 00200 * bytes. 00201 * 00202 * @note: there is a risk of overallocation in case an implementation doesn't 00203 * need FLASH_JOURNAL_HANDLE_MAX_SIZE bytes, but the impact should be small. 00204 */ 00205 typedef struct FlashJournal_t { 00206 FlashJournal_Ops_t ops; 00207 00208 union { 00209 ARM_DRIVER_STORAGE *mtd; 00210 FlashJournal_Info_t info; 00211 void *pointer; 00212 uint8_t octet; 00213 uint32_t data[FLASH_JOURNAL_HANDLE_MAX_SIZE / sizeof(uint32_t)]; 00214 } opaque; 00215 } FlashJournal_t; 00216 00217 /** 00218 * @brief Initialize a flash journal. 00219 * 00220 * This is a front-end for @ref FlashJournal_Ops_t::initialize() of the 00221 * underlying strategy. 00222 * 00223 * This function must be called *before* the middle-ware component starts 00224 * using a journal. As a part of bringing the journal to a ready state, it 00225 * also discovers the most recently logged blob. 00226 * 00227 * Initialize() receives a callback handler to be invoked upon completion of 00228 * asynchronous operations. 00229 * 00230 * @param [out] journal 00231 * A caller-supplied buffer large enough to hold an 00232 * initialized journal. The internals of the actual journal 00233 * are opaque to the caller and depend on the logging 00234 * strategy (as defined by the parameter 'ops'). This memory 00235 * should be at least as large as 'FLASH_JOURNAL_HANDLE_MAX_SIZE'. 00236 * Upon successful return, the journal is setup in an 00237 * initialized state. 00238 * 00239 * @param [in] mtd 00240 * The underlying Storage_Driver targeted by the journal. MTD 00241 * stands for Memory-Technology-Device. 00242 * 00243 * @param [in] ops 00244 * This is the set of operations which define the logging strategy. 00245 * 00246 * @param [in] callback 00247 * Caller-defined callback to be invoked upon command completion of 00248 * initialization; and also for all future invocations of 00249 * asynchronous APIs. Use a NULL pointer when no 00250 * callback signals are required. 00251 * 00252 * @note: this is an asynchronous operation, but it can finish 00253 * synchronously if the underlying MTD supports that. 00254 * 00255 * @return 00256 * The function executes in the following ways: 00257 * - When the operation is asynchronous, the function only starts the 00258 * initialization and control returns to the caller with an 00259 * JOURNAL_STATUS_OK before the actual completion of the operation (or 00260 * with an appropriate error code in case of failure). When the 00261 * operation is completed the command callback is invoked with 00262 * 1 passed in as the 'status' parameter of the 00263 * callback. In case of errors, the completion callback is invoked with 00264 * an error status. 00265 * - When the operation is executed by the journal in a blocking (i.e. 00266 * synchronous) manner, control returns to the caller only upon the actual 00267 * completion of the operation or the discovery of a failure condition. In 00268 * this case, the function returns 1 to signal successful synchronous 00269 * completion or an appropriate error code, and no further 00270 * invocation of the completion callback should be expected at a later time. 00271 * 00272 * @note The user must call an appropriate xxx_format() to format underlying 00273 * storage before initializing it for use. If Initialize() is called on 00274 * unformatted storage, an error value of JOURNAL_STATUS_NOT_FORMATTED will be 00275 * returned. 00276 * 00277 * Here's a code snippet to suggest how this API might be used by callers: 00278 * \code 00279 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00280 * int32_t returnValue = FlashJournal_initialize(&journal, MTD, &STRATEGY_SEQUENTIAL, callbackHandler); 00281 * if (returnValue < JOURNAL_STATUS_OK) { 00282 * // handle error 00283 * } else if (returnValue == JOURNAL_STATUS_OK) { 00284 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00285 * // handle early return from asynchronous execution 00286 * } else { 00287 * ASSERT(returnValue == 1); 00288 * // handle synchronous completion 00289 * } 00290 * \endcode 00291 */ 00292 MBED_DEPRECATED_SINCE("mbed-os-5.5", "FlashJournal is deprecated. " 00293 "Use a BlockDevice or filesystem instead") 00294 static inline int32_t FlashJournal_initialize(FlashJournal_t *journal, 00295 ARM_DRIVER_STORAGE *mtd, 00296 const FlashJournal_Ops_t *ops, 00297 FlashJournal_Callback_t callback) 00298 { 00299 return ops->initialize(journal, mtd, ops, callback); 00300 } 00301 00302 /** 00303 * @brief Fetch journal metadata. A front-end for @ref FlashJournal_Ops_t::getInfo(). 00304 * 00305 * @param [in] journal 00306 * A previously initialized journal. 00307 * 00308 * @param [out] info 00309 * A caller-supplied buffer capable of being filled in with an 00310 * FlashJournal_Info_t. 00311 * 00312 * @return JOURNAL_STATUS_OK if a FlashJournal_Info_t structure containing 00313 * top level metadata about the journal is filled into the supplied 00314 * buffer, else an appropriate error value. 00315 * 00316 * @note It is the caller's responsibility to ensure that the buffer passed in 00317 * is able to be initialized with a FlashJournal_Info_t. 00318 * 00319 * @note getInfo()s can still be called during a sequence of 00320 * log()s. 00321 * 00322 * @note This API returns synchronously--it does not result in an invocation 00323 * of a completion callback. 00324 * 00325 * Here's a code snippet to suggest how this API might be used by callers: 00326 * \code 00327 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00328 * FlashJournal_Info_t info; 00329 * int32_t returnValue = FlashJournal_getInfo(&journal, &info); 00330 * if (returnValue < JOURNAL_STATUS_OK) { 00331 * // handle error 00332 * } else { 00333 * ASSERT(returnValue == JOURNAL_STATUS_OK); 00334 * // work with the 'info'. 00335 * } 00336 * \endcode 00337 */ 00338 MBED_DEPRECATED_SINCE("mbed-os-5.5", "FlashJournal is deprecated. " 00339 "Use a BlockDevice or filesystem instead") 00340 static inline FlashJournal_Status_t FlashJournal_getInfo(FlashJournal_t *journal, FlashJournal_Info_t *info) 00341 { 00342 return journal->ops.getInfo(journal, info); 00343 } 00344 00345 /** 00346 * @brief Read from the most recently logged blob. A front-end for @ref 00347 * FlashJournal_Ops_t::read(). 00348 * 00349 * @details Read off a chunk of the logged blob sequentially. The blob may 00350 * be larger than the size of the read (or even of available SRAM), so 00351 * multiple calls to read() could be necessary before the entire blob is 00352 * read off. The journal maintains a read-pointer internally to allow 00353 * reads to continue where the previous one left off. 00354 * 00355 * @note: Once the entire blob is read, the final read() returns the error 00356 * JOURNAL_STATUS_EMPTY (or passes that value as the status of a 00357 * completion callback) and resets the read-pointer to allow re-reading 00358 * the blob from the start. 00359 * 00360 * @param [in] journal 00361 * A previously initialized journal. 00362 * 00363 * @param [out] buffer 00364 * The destination of the read operation. The memory is owned 00365 * by the caller and should remain valid for the lifetime 00366 * of this operation. 00367 * 00368 * @param [in] size 00369 * The maximum amount of data which can be read in this 00370 * operation. The memory pointed to by 'buffer' should be as 00371 * large as this amount. 00372 * 00373 * @return 00374 * The function executes in the following ways: 00375 * - When the operation is asynchronous--i.e. when the underlying MTD's 00376 * ARM_STOR_CAPABILITIES::asynchronous_ops is set to 1--and the operation 00377 * executed by the journal in a non-blocking (i.e. asynchronous) manner, 00378 * control returns to the caller with JOURNAL_STATUS_OK before the actual 00379 * completion of the operation (or with an appropriate error code in case of 00380 * failure). When the operation completes, the command callback is 00381 * invoked with the number of successfully transferred bytes passed in as 00382 * the 'status' parameter of the callback. If any error is encountered 00383 * after the launch of an asynchronous operation, the completion callback 00384 * is invoked with an error status. 00385 * - When the operation is executed by the journal in a blocking (i.e. 00386 * synchronous) manner, control returns to the caller only upon the 00387 * actual completion of the operation, or the discovery of a failure 00388 * condition. In synchronous mode, the function returns the number 00389 * of data items read or an appropriate error code. 00390 * 00391 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00392 * is set then this operation may execute asynchronously. In the case of 00393 * asynchronous operation, the invocation returns early (with 00394 * JOURNAL_STATUS_OK) and results in a completion callback later. 00395 * 00396 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00397 * is set, the journal is not required to operate asynchronously. A Read 00398 * operation can be finished synchronously in spite of 00399 * ARM_STORAGE_CAPABILITIES::asynchronous_ops being set, returning the 00400 * number of data items read to indicate successful completion, or an 00401 * appropriate error code. In this case no further invocation of a 00402 * completion callback should be expected at a later time. 00403 * 00404 * Here's a code snippet to suggest how this API might be used by callers: 00405 * \code 00406 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00407 * int32_t returnValue = FlashJournal_read(&journal, buffer, size); 00408 * if (returnValue < JOURNAL_STATUS_OK) { 00409 * // handle error 00410 * } else if (returnValue == JOURNAL_STATUS_OK) { 00411 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00412 * // handle early return from asynchronous execution 00413 * } else { 00414 * ASSERT(returnValue == size); 00415 * // handle synchronous completion 00416 * } 00417 * \endcode 00418 */ 00419 MBED_DEPRECATED_SINCE("mbed-os-5.5", "FlashJournal is deprecated. " 00420 "Use a BlockDevice or filesystem instead") 00421 static inline int32_t FlashJournal_read(FlashJournal_t *journal, void *blob, size_t n) 00422 { 00423 return journal->ops.read(journal, blob, n); 00424 } 00425 00426 /** 00427 * @brief Read from the most recently logged blob at a given offset. A front-end 00428 * for @ref FlashJournal_Ops_t::readFrom(). 00429 * 00430 * @details Read off a chunk of the logged blob from a given offset. The journal 00431 * maintains a read-pointer internally to allow reads to continue where the 00432 * previous one left off. This call effectively sets the read-counter before 00433 * fetching data. Subsequent reads continue sequentially from where the 00434 * readFrom() left off. 00435 * 00436 * @note: If the given offset stands at (or is beyond) the end of the previously 00437 * logged blob, readFrom() returns the error JOURNAL_STATUS_EMPTY (or passes 00438 * that value as the status of a completion callback) and resets the read- 00439 * pointer to allow re-reading the blob from the start. 00440 * 00441 * @param [in] journal 00442 * A previously initialized journal. 00443 * 00444 * @param [in] offset 00445 * The logical offset (within the blob) at which to read data from. 00446 * 00447 * @param [out] buffer 00448 * The destination of the read operation. The memory is owned 00449 * by the caller and should remain valid for the lifetime 00450 * of this operation. 00451 * 00452 * @param [in] size 00453 * The maximum amount of data which can be read in this 00454 * operation. The memory pointed to by 'buffer' should be as 00455 * large as this amount. 00456 * 00457 * @return 00458 * The function executes in the following ways: 00459 * - When the operation is asynchronous--i.e. when the underlying MTD's 00460 * ARM_STOR_CAPABILITIES::asynchronous_ops is set to 1--and the operation 00461 * executed by the journal in a non-blocking (i.e. asynchronous) manner, 00462 * control returns to the caller with JOURNAL_STATUS_OK before the actual 00463 * completion of the operation (or with an appropriate error code in case of 00464 * failure). When the operation completes, the command callback is 00465 * invoked with the number of successfully transferred bytes passed in as 00466 * the 'status' parameter of the callback. If any error is encountered 00467 * after the launch of an asynchronous operation, the completion callback 00468 * is invoked with an error status. 00469 * - When the operation is executed by the journal in a blocking (i.e. 00470 * synchronous) manner, control returns to the caller only upon the 00471 * actual completion of the operation, or the discovery of a failure 00472 * condition. In synchronous mode, the function returns the number 00473 * of data items read or an appropriate error code. 00474 * 00475 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00476 * is set then this operation may execute asynchronously. In the case of 00477 * asynchronous operation, the invocation returns early (with 00478 * JOURNAL_STATUS_OK) and results in a completion callback later. 00479 * 00480 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00481 * is set, the journal is not required to operate asynchronously. A Read 00482 * operation can be finished synchronously in spite of 00483 * ARM_STORAGE_CAPABILITIES::asynchronous_ops being set, returning the 00484 * number of data items read to indicate successful completion, or an 00485 * appropriate error code. In this case no further invocation of a 00486 * completion callback should be expected at a later time. 00487 * 00488 * Here's a code snippet to suggest how this API might be used by callers: 00489 * \code 00490 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00491 * int32_t returnValue = FlashJournal_readFrom(&journal, offset, buffer, size); 00492 * if (returnValue < JOURNAL_STATUS_OK) { 00493 * // handle error 00494 * } else if (returnValue == JOURNAL_STATUS_OK) { 00495 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00496 * // handle early return from asynchronous execution 00497 * } else { 00498 * ASSERT(returnValue == size); 00499 * // handle synchronous completion 00500 * } 00501 * \endcode 00502 */ 00503 MBED_DEPRECATED_SINCE("mbed-os-5.5", "FlashJournal is deprecated. " 00504 "Use a BlockDevice or filesystem instead") 00505 static inline int32_t FlashJournal_readFrom(struct FlashJournal_t *journal, size_t offset, void *blob, size_t n) 00506 { 00507 return journal->ops.readFrom(journal, offset, blob, n); 00508 } 00509 00510 /** 00511 * @brief Start logging a new blob or append to the one currently being logged. 00512 * A front-end for @ref FlashJournal_Ops_t::log(). 00513 * 00514 * @details Extend (or start off) the currently logged blob sequentially. 00515 * There could be several calls to log() before the entire blob is 00516 * accumulated. A sequence of one or more log() must be terminated by a 00517 * commit() before the state of the blob is sealed and made persistent. 00518 * The journal maintains a log-pointer internally to allow 00519 * log()s to continue where the previous one left off. 00520 * 00521 * @param [in] journal 00522 * A previously initialized journal. 00523 * 00524 * @param [in] blob 00525 * The source of the log operation. The memory is owned 00526 * by the caller and should remain valid for the lifetime 00527 * of this operation. 00528 * 00529 * @param [in] size 00530 * The amount of data being logged in this operation. The 00531 * buffer pointed to by 'blob' should be as large as this 00532 * amount. 00533 * 00534 * @return [please be sure to read notes (below) regarding other return values] 00535 * The function executes in the following ways: 00536 * - When the operation is asynchronous--i.e. when the underlying MTD's 00537 * ARM_STOR_CAPABILITIES::asynchronous_ops is set to 1--and the operation 00538 * executed by the journal in a non-blocking (i.e. asynchronous) manner, 00539 * control returns to the caller with JOURNAL_STATUS_OK before the actual 00540 * completion of the operation (or with an appropriate error code in case of 00541 * failure). When the operation completes, the command callback is 00542 * invoked with the number of successfully transferred bytes passed in as 00543 * the 'status' parameter of the callback. If any error is encountered 00544 * after the launch of an asynchronous operation, the completion callback 00545 * is invoked with an error status. 00546 * - When the operation is executed by the journal in a blocking (i.e. 00547 * synchronous) manner, control returns to the caller only upon the actual 00548 * completion of the operation, or the discovery of a failure condition. In 00549 * synchronous mode, the function returns the number of data items 00550 * logged, or an appropriate error code. 00551 * 00552 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00553 * is set then this operation may execute asynchronously. In the case of 00554 * asynchronous operation, the invocation returns early (with 00555 * JOURNAL_STATUS_OK) and results in a completion callback later. 00556 * 00557 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00558 * is set, the journal is not required to operate asynchronously. A log 00559 * operation can be finished synchronously in spite of 00560 * ARM_STORAGE_CAPABILITIES::asynchronous_ops being set, returning the 00561 * number of data items logged to indicate successful completion, or an 00562 * appropriate error code. In this case no further invocation of a 00563 * completion callback should be expected at a later time. 00564 * 00565 * @note If a log operation will exceed available capacity, it fails with the 00566 * error JOURNAL_STATUS_BOUNDED_CAPACITY. 00567 * 00568 * @note The actual size of data transfer (as reported by the status 00569 * parameter of the callback or the return value from log() in case of 00570 * synchronous operation) may be smaller than the amount requested. This 00571 * could be due to the 'program_unit' of the underlying storage block-- 00572 * i.e. the minimum programmable size. Refer to @ref 00573 * FlashJournal_Info_t::program_unit. It is the caller's responsibility 00574 * for resubmitting this left-over data in a subsequent call to log. 00575 * When logging an arbitrary amount of data, the last of a sequence of 00576 * logs may need to be padded in order to align with the 00577 * programming unit. 00578 * 00579 * @note If the total size requested to be logged is smaller 00580 * than the MTD's program_unit, log() fails with an error value of 00581 * JOURNAL_STATUS_SMALL_LOG_REQUEST. 00582 * 00583 * @note the data being logged isn't made persistent (or available for read- 00584 * backs) until a commit. A sequence of log() operations is expected to end 00585 * in a commit(). A new sequence of log()s should be initiated by the caller 00586 * only after a commit() has completed. If a sequence of logs() is followed 00587 * by an operation other than a commit, that operation will very likely 00588 * return an error code. getInfo()s can still be called during a sequence of 00589 * log()s. 00590 * 00591 * Here's a code snippet to suggest how this API might be used by callers: 00592 * \code 00593 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00594 * int32_t returnValue = FlashJournal_log(&journal, buffer, size); 00595 * if (returnValue < JOURNAL_STATUS_OK) { 00596 * // handle error 00597 * } else if (returnValue == JOURNAL_STATUS_OK) { 00598 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00599 * // handle early return from asynchronous execution 00600 * } else { 00601 * ASSERT(returnValue <= size); 00602 * // handle synchronous completion 00603 * 00604 * if (returnValue < size) { 00605 * #if DEBUG 00606 * FlashJournal_Info_t info; 00607 * int32_t rc = FlashJournal_getInfo(&journal, &info); 00608 * ASSERT(rc == JOURNAL_STATUS_OK); 00609 * ASSERT(returnValue == (size - (size % info.program_unit))); 00610 * #endif 00611 * // move the last (size - returnValue) bytes of the buffer to the 00612 * // beginning of the buffer to be used for the successive request. 00613 * } 00614 * } 00615 * \endcode 00616 */ 00617 MBED_DEPRECATED_SINCE("mbed-os-5.5", "FlashJournal is deprecated. " 00618 "Use a BlockDevice or filesystem instead") 00619 static inline int32_t FlashJournal_log(FlashJournal_t *journal, const void *blob, size_t n) 00620 { 00621 return journal->ops.log(journal, blob, n); 00622 } 00623 00624 /** 00625 * @brief Commit a blob accumulated through a (possibly empty) sequence of previously 00626 * successful log() operations. A front-end for @ref FlashJournal_Ops_t::commit(). 00627 * 00628 * @param [in] journal 00629 * A previously initialized journal. 00630 * 00631 * @return 00632 * The function executes in the following ways: 00633 * - When the operation is asynchronous--i.e. when the underlying MTD's 00634 * ARM_STOR_CAPABILITIES::asynchronous_ops is set to 1--and the operation 00635 * executed by the journal in a non-blocking (i.e. asynchronous) manner, 00636 * control returns to the caller with JOURNAL_STATUS_OK before the actual 00637 * completion of the operation (or with an appropriate error code in case of 00638 * failure). When the operation completes, the command callback is invoked 00639 * with 1 passed in as the 'status' parameter of the callback to indicate 00640 * success. If any error is encountered after the launch of an asynchronous 00641 * operation, the completion callback is invoked with an error status. 00642 * - When the operation is executed by the journal in a blocking (i.e. 00643 * synchronous) manner, control returns to the caller only upon the actual 00644 * completion of the operation, or the discovery of a failure condition. In 00645 * synchronous mode, the function returns 1 to indicate success, or an 00646 * appropriate error code. 00647 * 00648 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00649 * is set then this operation may execute asynchronously. In the case of 00650 * asynchronous operation, the invocation returns early (with 00651 * JOURNAL_STATUS_OK) and results in a completion callback later. 00652 * 00653 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00654 * is set, the journal is not required to operate asynchronously. A 00655 * commit operation can be finished synchronously in spite of 00656 * ARM_STORAGE_CAPABILITIES::asynchronous_ops being set, returning the 00657 * total size of the committed blob to indicate successful completion, 00658 * or an appropriate error code. In this case no further invocation of a 00659 * completion callback should be expected at a later time. 00660 * 00661 * Here's a code snippet to suggest how this API might be used by callers: 00662 * \code 00663 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00664 * int32_t returnValue = FlashJournal_commit(&journal); 00665 * if (returnValue < JOURNAL_STATUS_OK) { 00666 * // handle error 00667 * } else if (returnValue == JOURNAL_STATUS_OK) { 00668 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00669 * // handle early return from asynchronous execution 00670 * } else { 00671 * // handle synchronous completion 00672 * ASSERT(returnValue == 1); 00673 * ... 00674 * } 00675 * \endcode 00676 * 00677 * @note A sequence of log() operations is expected to end in a commit(). A new 00678 * sequence of log()s should be initiated by the caller only after a 00679 * commit() has completed. If a sequence of logs() is followed 00680 * by an operation other than a commit, that operation will very likely 00681 * return an error code. 00682 */ 00683 MBED_DEPRECATED_SINCE("mbed-os-5.5", "FlashJournal is deprecated. " 00684 "Use a BlockDevice or filesystem instead") 00685 static inline int32_t FlashJournal_commit(FlashJournal_t *journal) 00686 { 00687 return journal->ops.commit(journal); 00688 } 00689 00690 /** 00691 * @brief Reset the journal. This has the effect of erasing all valid blobs. A 00692 * front-end for @ref FlashJournal_Ops_t::reset(). 00693 * 00694 * @param [in] journal 00695 * A previously initialized journal. 00696 * 00697 * @return 00698 * The function executes in the following ways: 00699 * - When the operation is asynchronous--i.e. when the underlying MTD's 00700 * ARM_STOR_CAPABILITIES::asynchronous_ops is set to 1--and the 00701 * operation executed by the journal in a non-blocking (i.e. 00702 * asynchronous) manner, control returns to the caller with 00703 * JOURNAL_STATUS_OK before the actual completion of the operation (or 00704 * with an appropriate error code in case of failure). When the 00705 * operation completes, the command callback is invoked with 00706 * JOURNAL_STATUS_OK passed in as the 'status' parameter of the 00707 * callback. If any error is encountered after the launch of an 00708 * asynchronous operation, the completion callback is invoked with an 00709 * error status. 00710 * - When the operation is executed by the journal in a blocking (i.e. 00711 * synchronous) manner, control returns to the caller only upon the 00712 * actual completion of the operation, or the discovery of a failure 00713 * condition. In synchronous mode, the function returns 1 to signal 00714 * successful completion, or an appropriate error code. 00715 * 00716 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00717 * is set then this operation may execute asynchronously. In the case of 00718 * asynchronous operation, the invocation returns early (with 00719 * JOURNAL_STATUS_OK) and results in a completion callback later. 00720 * 00721 * @note If the underlying MTD's ARM_STORAGE_CAPABILITIES::asynchronous_ops 00722 * is set, the journal is not required to operate asynchronously. A 00723 * reset operation can be finished synchronously in spite of 00724 * ARM_STORAGE_CAPABILITIES::asynchronous_ops being set, returning 1 to 00725 * indicate successful completion, or an appropriate error code. In this 00726 * case no further invocation of a completion callback should be 00727 * expected at a later time. 00728 * 00729 * Here's a code snippet to suggest how this API might be used by callers: 00730 * \code 00731 * ASSERT(JOURNAL_STATUS_OK == 0); // this is a precondition; it doesn't need to be put in code 00732 * int32_t returnValue = FlashJournal_reset(&journal); 00733 * if (returnValue < JOURNAL_STATUS_OK) { 00734 * // handle error 00735 * } else if (returnValue == JOURNAL_STATUS_OK) { 00736 * ASSERT(MTD->GetCapabilities().asynchronous_ops == 1); 00737 * // handle early return from asynchronous execution 00738 * } else { 00739 * ASSERT(returnValue == 1); 00740 * // handle synchronous completion 00741 * } 00742 * \endcode 00743 */ 00744 MBED_DEPRECATED_SINCE("mbed-os-5.5", "FlashJournal is deprecated. " 00745 "Use a BlockDevice or filesystem instead") 00746 static inline int32_t FlashJournal_reset(FlashJournal_t *journal) 00747 { 00748 return journal->ops.reset(journal); 00749 } 00750 00751 #ifdef __cplusplus 00752 } 00753 #endif // __cplusplus 00754 00755 #endif /* __FLASH_JOURNAL_H__ */
Generated on Fri Jul 22 2022 04:53:49 by
