aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/lib/complex/mfs/hal_mfs.h
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/lib/complex/mfs/hal_mfs.h')
-rw-r--r--os/hal/lib/complex/mfs/hal_mfs.h100
1 files changed, 70 insertions, 30 deletions
diff --git a/os/hal/lib/complex/mfs/hal_mfs.h b/os/hal/lib/complex/mfs/hal_mfs.h
index 56ff0b966..14dfc75ee 100644
--- a/os/hal/lib/complex/mfs/hal_mfs.h
+++ b/os/hal/lib/complex/mfs/hal_mfs.h
@@ -48,7 +48,7 @@
*/
/**
* @brief Maximum number of indexed records in the managed storage.
- * @note Record indexes go from 0 to @p MFS_CFG_MAX_RECORDS - 1.
+ * @note Record indexes go from 1 to @p MFS_CFG_MAX_RECORDS.
*/
#if !defined(MFS_CFG_MAX_RECORDS) || defined(__DOXYGEN__)
#define MFS_CFG_MAX_RECORDS 32
@@ -95,15 +95,16 @@
* for records in the flash array. This is required when alignment
* constraints exist, for example when using a DTR mode on OSPI
* devices.
- * @note When enforcing an alignment you need to use buffers with size
- * aligned to the specified value. For example, if you need to
- * write a 5 bytes object with alignment of 4 then you need to
- * use a 8 bytes data buffer, the last 3 bytes are used as filler
- * so ==initialize== those to zero (buffer->DDDDD000) or garbage
- * will be written after data.
*/
#if !defined(MFS_CFG_MEMORY_ALIGNMENT) || defined(__DOXYGEN__)
-#define MFS_CFG_MEMORY_ALIGNMENT 1
+#define MFS_CFG_MEMORY_ALIGNMENT 2
+#endif
+
+/**
+ * @brief Maximum number of objects writable in a single transaction.
+ */
+#if !defined(MFS_CFG_TRANSACTION_MAX) || defined(__DOXYGEN__)
+#define MFS_CFG_TRANSACTION_MAX 16
#endif
/** @} */
@@ -115,7 +116,8 @@
#error "invalid MFS_CFG_MAX_RECORDS value"
#endif
-#if (MFS_CFG_MAX_REPAIR_ATTEMPTS < 1) || (MFS_CFG_MAX_REPAIR_ATTEMPTS > 10)
+#if (MFS_CFG_MAX_REPAIR_ATTEMPTS < 1) || \
+ (MFS_CFG_MAX_REPAIR_ATTEMPTS > 10)
#error "invalid MFS_MAX_REPAIR_ATTEMPTS value"
#endif
@@ -127,7 +129,8 @@
#error "MFS_CFG_BUFFER_SIZE is not a power of two"
#endif
-#if MFS_CFG_MEMORY_ALIGNMENT < 1
+#if (MFS_CFG_MEMORY_ALIGNMENT < 1) || \
+ (MFS_CFG_MEMORY_ALIGNMENT > MFS_CFG_BUFFER_SIZE)
#error "invalid MFS_CFG_MEMORY_ALIGNMENT value"
#endif
@@ -135,6 +138,11 @@
#error "MFS_CFG_MEMORY_ALIGNMENT is not a power of two"
#endif
+#if (MFS_CFG_TRANSACTION_MAX < 0) || \
+ (MFS_CFG_TRANSACTION_MAX > MFS_CFG_MAX_RECORDS)
+#error "invalid MFS_CFG_TRANSACTION_MAX value"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -154,7 +162,8 @@ typedef enum {
MFS_UNINIT = 0,
MFS_STOP = 1,
MFS_READY = 2,
- MFS_ERROR = 3
+ MFS_TRANSACTION = 3,
+ MFS_ERROR = 4
} mfs_state_t;
/**
@@ -170,9 +179,11 @@ typedef enum {
MFS_ERR_INV_SIZE = -2,
MFS_ERR_NOT_FOUND = -3,
MFS_ERR_OUT_OF_MEM = -4,
- MFS_ERR_NOT_ERASED = -5,
- MFS_ERR_FLASH_FAILURE = -6,
- MFS_ERR_INTERNAL = -7
+ MFS_ERR_TRANSACTION_NUM = -5,
+ MFS_ERR_TRANSACTION_SIZE = -6,
+ MFS_ERR_NOT_ERASED = -7,
+ MFS_ERR_FLASH_FAILURE = -8,
+ MFS_ERR_INTERNAL = -9
} mfs_error_t;
/**
@@ -181,21 +192,10 @@ typedef enum {
typedef enum {
MFS_BANK_ERASED = 0,
MFS_BANK_OK = 1,
- MFS_BANK_PARTIAL = 2,
- MFS_BANK_GARBAGE = 3
+ MFS_BANK_GARBAGE = 2
} mfs_bank_state_t;
/**
- * @brief Type of a record state assessment.
- */
-typedef enum {
- MFS_RECORD_ERASED = 0,
- MFS_RECORD_OK = 1,
- MFS_RECORD_CRC = 2,
- MFS_RECORD_GARBAGE = 3
-} mfs_record_state_t;
-
-/**
* @brief Type of a record identifier.
*/
typedef uint32_t mfs_id_t;
@@ -244,7 +244,7 @@ typedef union {
*/
uint32_t magic;
/**
- * @brief Data identifier.
+ * @brief Record identifier.
*/
uint16_t id;
/**
@@ -311,8 +311,24 @@ typedef struct {
} MFSConfig;
/**
- * @extends BaseFlash
- *
+ * @brief Type of a buffered write/erase operation within a transaction.
+ */
+typedef struct {
+ /**
+ * @brief Written header offset.
+ */
+ flash_offset_t offset;
+ /**
+ * @brief Written data size.
+ */
+ size_t size;
+ /**
+ * @brief Record identifier.
+ */
+ mfs_id_t id;
+} mfs_transaction_op_t;
+
+/**
* @brief Type of an MFS instance.
*/
typedef struct {
@@ -345,6 +361,24 @@ typedef struct {
* @note Zero means that there is not a record with that id.
*/
mfs_record_descriptor_t descriptors[MFS_CFG_MAX_RECORDS];
+#if (MFS_CFG_TRANSACTION_MAX > 0) || defined(__DOXYGEN__)
+ /**
+ * @brief Next write offset for current transaction.
+ */
+ flash_offset_t tr_next_offset;
+ /**
+ * @brief Maximum offset for the transaction.
+ */
+ flash_offset_t tr_limit_offet;
+ /**
+ * @brief Number of buffered operations in current transaction.
+ */
+ uint32_t tr_nops;
+ /**
+ * @brief Buffered operations in current transaction.
+ */
+ mfs_transaction_op_t tr_ops[MFS_CFG_TRANSACTION_MAX];
+#endif
/**
* @brief Transient buffer.
*/
@@ -376,7 +410,8 @@ typedef struct {
#define MFS_ALIGN_MASK ((uint32_t)MFS_CFG_MEMORY_ALIGNMENT - 1U)
#define MFS_IS_ALIGNED(v) (((uint32_t)(v) & MFS_ALIGN_MASK) == 0U)
#define MFS_ALIGN_PREV(v) ((uint32_t)(v) & ~MFS_ALIGN_MASK)
-#define MFS_ALIGN_NEXT(v) MFS_ALIGN_PREV((size_t)(v) + MFS_ALIGN_MASK)
+#define MFS_ALIGN_NEXT(v) (MFS_ALIGN_PREV(((uint32_t)(v) - 1U)) + \
+ MFS_CFG_MEMORY_ALIGNMENT)
/** @} */
/*===========================================================================*/
@@ -396,6 +431,11 @@ extern "C" {
size_t n, const uint8_t *buffer);
mfs_error_t mfsEraseRecord(MFSDriver *devp, mfs_id_t id);
mfs_error_t mfsPerformGarbageCollection(MFSDriver *mfsp);
+#if MFS_CFG_TRANSACTION_MAX > 0
+ mfs_error_t mfsStartTransaction(MFSDriver *mfsp, size_t size);
+ mfs_error_t mfsCommitTransaction(MFSDriver *mfsp);
+ mfs_error_t mfsRollbackTransaction(MFSDriver *mfsp);
+#endif /* MFS_CFG_TRANSACTION_MAX > 0 */
#ifdef __cplusplus
}
#endif