Complete, some settings missing, not tested.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10990 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
Giovanni Di Sirio 2017-11-13 14:27:38 +00:00
parent 42cdb703e7
commit 5b1537fc2c
2 changed files with 73 additions and 56 deletions

View File

@ -1015,46 +1015,36 @@ mfs_error_t mfsErase(MFSDriver *mfsp) {
*/ */
mfs_error_t mfsReadRecord(MFSDriver *mfsp, uint32_t id, mfs_error_t mfsReadRecord(MFSDriver *mfsp, uint32_t id,
size_t *np, uint8_t *buffer) { size_t *np, uint8_t *buffer) {
mfs_error_t err; uint16_t crc;
osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS) && osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS) &&
(np != NULL) && (buffer != NULL)); (np != NULL) && (buffer != NULL));
osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state"); osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state");
/* Marking the start of the operation.*/
mfsp->state = MFS_ACTIVE;
/* Checking if the requested record actually exists.*/ /* Checking if the requested record actually exists.*/
if (mfsp->descriptors[id].offset != 0U) { if (mfsp->descriptors[id].offset != 0U) {
/* Making sure to not overflow the buffer.*/ return MFS_ERR_NOT_FOUND;
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;
}
}
}
}
else {
err = MFS_ERR_NOT_FOUND;
} }
/* Operation over.*/ /* Making sure to not overflow the buffer.*/
mfsp->state = MFS_MOUNTED; if (*np < mfsp->descriptors[id].size) {
return MFS_ERR_INV_SIZE;
}
return err; /* 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 MFS_NO_ERROR;
} }
/** /**
@ -1085,9 +1075,6 @@ mfs_error_t mfsWriteRecord(MFSDriver *mfsp, uint32_t id,
(n > 0U) && (buffer != NULL)); (n > 0U) && (buffer != NULL));
osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state"); 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 /* If the required space is beyond the available (compacted) block
size then an error is returned. size then an error is returned.
NOTE: The space for one extra header is reserved in order to allow 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), sizeof (uint32_t),
mfsp->buffer.data)); 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.*/ /* 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->next_offset += sizeof (mfs_data_header_t) + n;
mfsp->used_space -= 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; 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_NO_ERROR if the operation has been successfully completed.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures. * failures.
* @retval MFS_ERR_INTERNAL if an internal logic failure is detected.
* *
* @api * @api
*/ */
mfs_error_t mfsEraseRecord(MFSDriver *mfsp, uint32_t id) { 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"); osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state");
/* Marking the start of the operation.*/ /* Checking if the requested record actually exists.*/
mfsp->state = MFS_ACTIVE; if (mfsp->descriptors[id].offset == 0U) {
return MFS_ERR_NOT_FOUND;
}
(void)id; /* 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;
}
/* Operation over.*/ /* Checking for immediately (not compacted) available space.*/
mfsp->state = MFS_MOUNTED; 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));
}
return MFS_NO_ERROR; /* 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));
/* 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 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 * @param[in] mfsp pointer to the @p MFSDriver object
* @return The operation status. * @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed. * @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 * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures. * failures.
* *
* @api * @api
*/ */
mfs_error_t mfsPerformGarbageCollection(MFSDriver *mfsp) { mfs_error_t mfsPerformGarbageCollection(MFSDriver *mfsp) {
mfs_error_t err;
mfs_bank_state_t sts; mfs_bank_state_t sts;
osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state"); osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state");
/* Marking the start of the operation.*/ return mfs_garbage_collect(mfsp, &sts);
mfsp->state = MFS_ACTIVE;
err = mfs_garbage_collect(mfsp, &sts);
/* Operation over.*/
mfsp->state = MFS_MOUNTED;
return err;
} }
/** @} */ /** @} */

View File

@ -132,8 +132,7 @@ typedef enum {
MFS_UNINIT = 0, MFS_UNINIT = 0,
MFS_STOP = 1, MFS_STOP = 1,
MFS_READY = 2, MFS_READY = 2,
MFS_MOUNTED = 3, MFS_MOUNTED = 3
MFS_ACTIVE = 4
} mfs_state_t; } mfs_state_t;
/** /**