STM32F7 Ethernet interface for nucleo STM32F767

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers flash_journal.h Source File

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__ */