Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 Sun Jul 17 2022 08:25:23 by 1.7.2