aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2017-11-13 14:27:38 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2017-11-13 14:27:38 +0000
commit5b1537fc2c331b2da9bc84913ca0748a56a8e9c7 (patch)
tree001e3027e9e75ab75ed48666bac07b49f43f5607
parent42cdb703e7fd3b3d8c0d5773615f8206bef4605a (diff)
downloadChibiOS-5b1537fc2c331b2da9bc84913ca0748a56a8e9c7.tar.gz
ChibiOS-5b1537fc2c331b2da9bc84913ca0748a56a8e9c7.tar.bz2
ChibiOS-5b1537fc2c331b2da9bc84913ca0748a56a8e9c7.zip
Complete, some settings missing, not tested.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10990 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/hal/lib/complex/mfs/mfs.c124
-rw-r--r--os/hal/lib/complex/mfs/mfs.h3
2 files changed, 72 insertions, 55 deletions
diff --git a/os/hal/lib/complex/mfs/mfs.c b/os/hal/lib/complex/mfs/mfs.c
index 6f44032ce..f17cb9055 100644
--- a/os/hal/lib/complex/mfs/mfs.c
+++ b/os/hal/lib/complex/mfs/mfs.c
@@ -1015,46 +1015,36 @@ mfs_error_t mfsErase(MFSDriver *mfsp) {
*/
mfs_error_t mfsReadRecord(MFSDriver *mfsp, uint32_t id,
size_t *np, uint8_t *buffer) {
- mfs_error_t err;
+ uint16_t crc;
osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS) &&
(np != NULL) && (buffer != NULL));
osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state");
- /* Marking the start of the operation.*/
- mfsp->state = MFS_ACTIVE;
-
/* Checking if the requested record actually exists.*/
if (mfsp->descriptors[id].offset != 0U) {
- /* Making sure to not overflow the buffer.*/
- if (*np < mfsp->descriptors[id].size) {
- err = MFS_ERR_INV_SIZE;
- }
- else {
- /* Data read from flash.*/
- *np = mfsp->descriptors[id].size;
- err = mfs_flash_read(mfsp,
- mfsp->descriptors[id].offset + sizeof (mfs_data_header_t),
- *np,
- buffer);
-
- /* Checking CRC.*/
- if (err == MFS_NO_ERROR) {
- uint16_t crc = crc16(0xFFFFU, buffer, *np);
- if (crc != mfsp->buffer.dhdr.fields.crc) {
- err = MFS_ERR_CRC;
- }
- }
- }
+ return MFS_ERR_NOT_FOUND;
}
- else {
- err = MFS_ERR_NOT_FOUND;
+
+ /* Making sure to not overflow the buffer.*/
+ if (*np < mfsp->descriptors[id].size) {
+ return MFS_ERR_INV_SIZE;
}
- /* Operation over.*/
- mfsp->state = MFS_MOUNTED;
+ /* Data read from flash.*/
+ *np = mfsp->descriptors[id].size;
+ RET_ON_ERROR(mfs_flash_read(mfsp,
+ mfsp->descriptors[id].offset + sizeof (mfs_data_header_t),
+ *np,
+ buffer));
+
+ /* Checking CRC.*/
+ crc = crc16(0xFFFFU, buffer, *np);
+ if (crc != mfsp->buffer.dhdr.fields.crc) {
+ return MFS_ERR_CRC;
+ }
- return err;
+ return MFS_NO_ERROR;
}
/**
@@ -1085,9 +1075,6 @@ mfs_error_t mfsWriteRecord(MFSDriver *mfsp, uint32_t id,
(n > 0U) && (buffer != NULL));
osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state");
- /* Marking the start of the operation.*/
- mfsp->state = MFS_ACTIVE;
-
/* If the required space is beyond the available (compacted) block
size then an error is returned.
NOTE: The space for one extra header is reserved in order to allow
@@ -1130,13 +1117,19 @@ mfs_error_t mfsWriteRecord(MFSDriver *mfsp, uint32_t id,
sizeof (uint32_t),
mfsp->buffer.data));
+ /* The size of the old record instance, if present, must be subtracted
+ to the total used size.*/
+ if (mfsp->descriptors[id].offset != 0U) {
+ mfsp->used_space -= sizeof (mfs_data_header_t) +
+ mfsp->descriptors[id].size;
+ }
+
/* Adjusting bank-related metadata.*/
+ mfsp->descriptors[id].offset = mfsp->next_offset;
+ mfsp->descriptors[id].size = (uint32_t)n;
mfsp->next_offset += sizeof (mfs_data_header_t) + n;
mfsp->used_space -= sizeof (mfs_data_header_t) + n;
- /* Operation over.*/
- mfsp->state = MFS_MOUNTED;
-
return warning ? MFS_WARN_GC : MFS_NO_ERROR;
}
@@ -1150,22 +1143,58 @@ mfs_error_t mfsWriteRecord(MFSDriver *mfsp, uint32_t id,
* @retval MFS_NO_ERROR if the operation has been successfully completed.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures.
+ * @retval MFS_ERR_INTERNAL if an internal logic failure is detected.
*
* @api
*/
mfs_error_t mfsEraseRecord(MFSDriver *mfsp, uint32_t id) {
+ flash_offset_t free, required;
+ mfs_bank_state_t sts;
+ bool warning = false;
+ osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS));
osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state");
- /* Marking the start of the operation.*/
- mfsp->state = MFS_ACTIVE;
+ /* Checking if the requested record actually exists.*/
+ if (mfsp->descriptors[id].offset == 0U) {
+ return MFS_ERR_NOT_FOUND;
+ }
+
+ /* If the required space is beyond the available (compacted) block
+ size then an internal error is returned, it should never happen.*/
+ required = (flash_offset_t)sizeof (mfs_data_header_t);
+ if (required > mfsp->config->bank_size - mfsp->used_space) {
+ return MFS_ERR_INTERNAL;
+ }
+
+ /* Checking for immediately (not compacted) available space.*/
+ free = mfsp->config->bank_size - mfsp->next_offset;
+ if (required > free) {
+ /* We need to perform a garbage collection, there is enough space
+ but it has to be freed.*/
+ warning = true;
+ RET_ON_ERROR(mfs_garbage_collect(mfsp, &sts));
+ }
- (void)id;
+ /* Writing the data header with size set to zero, it means that the
+ record is logically erased.*/
+ mfsp->buffer.dhdr.fields.magic = (uint32_t)MFS_HEADER_MAGIC;
+ mfsp->buffer.dhdr.fields.id = (uint16_t)id;
+ mfsp->buffer.dhdr.fields.size = (uint32_t)0;
+ mfsp->buffer.dhdr.fields.crc = (uint16_t)0;
+ RET_ON_ERROR(mfs_flash_write(mfsp,
+ mfsp->next_offset,
+ sizeof (mfs_data_header_t),
+ mfsp->buffer.data));
- /* Operation over.*/
- mfsp->state = MFS_MOUNTED;
+ /* Adjusting bank-related metadata.*/
+ mfsp->used_space -= sizeof (mfs_data_header_t) +
+ mfsp->descriptors[id].size;
+ mfsp->next_offset += sizeof (mfs_data_header_t);
+ mfsp->descriptors[id].offset = 0U;
+ mfsp->descriptors[id].size = 0U;
- return MFS_NO_ERROR;
+ return warning ? MFS_WARN_GC : MFS_NO_ERROR;
}
/**
@@ -1176,28 +1205,17 @@ mfs_error_t mfsEraseRecord(MFSDriver *mfsp, uint32_t id) {
* @param[in] mfsp pointer to the @p MFSDriver object
* @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed.
- * @retval MFS_WARN_REPAIR if the operation has been completed but a
- * repair has been performed.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures.
*
* @api
*/
mfs_error_t mfsPerformGarbageCollection(MFSDriver *mfsp) {
- mfs_error_t err;
mfs_bank_state_t sts;
osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state");
- /* Marking the start of the operation.*/
- mfsp->state = MFS_ACTIVE;
-
- err = mfs_garbage_collect(mfsp, &sts);
-
- /* Operation over.*/
- mfsp->state = MFS_MOUNTED;
-
- return err;
+ return mfs_garbage_collect(mfsp, &sts);
}
/** @} */
diff --git a/os/hal/lib/complex/mfs/mfs.h b/os/hal/lib/complex/mfs/mfs.h
index bfaa92681..103890462 100644
--- a/os/hal/lib/complex/mfs/mfs.h
+++ b/os/hal/lib/complex/mfs/mfs.h
@@ -132,8 +132,7 @@ typedef enum {
MFS_UNINIT = 0,
MFS_STOP = 1,
MFS_READY = 2,
- MFS_MOUNTED = 3,
- MFS_ACTIVE = 4
+ MFS_MOUNTED = 3
} mfs_state_t;
/**