From 5b1537fc2c331b2da9bc84913ca0748a56a8e9c7 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 13 Nov 2017 14:27:38 +0000 Subject: Complete, some settings missing, not tested. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10990 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/lib/complex/mfs/mfs.c | 124 +++++++++++++++++++++++++------------------ os/hal/lib/complex/mfs/mfs.h | 3 +- 2 files changed, 72 insertions(+), 55 deletions(-) (limited to 'os/hal/lib') 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; /** -- cgit v1.2.3