aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2017-11-09 13:37:47 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2017-11-09 13:37:47 +0000
commitf16a0581cec5a807fa09b3ac15fbe75c447536a6 (patch)
tree93ae30401fac7bf47e8438190dce666c59f324c2 /os
parent8f814aba602e2e672b6a306e693cc6e3be178563 (diff)
downloadChibiOS-f16a0581cec5a807fa09b3ac15fbe75c447536a6.tar.gz
ChibiOS-f16a0581cec5a807fa09b3ac15fbe75c447536a6.tar.bz2
ChibiOS-f16a0581cec5a807fa09b3ac15fbe75c447536a6.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10978 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/ex/subsystems/mfs/mfs.c366
-rw-r--r--os/ex/subsystems/mfs/mfs.h19
-rw-r--r--os/hal/lib/peripherals/flash/hal_flash.c1
-rw-r--r--os/hal/lib/peripherals/flash/hal_flash.h8
4 files changed, 248 insertions, 146 deletions
diff --git a/os/ex/subsystems/mfs/mfs.c b/os/ex/subsystems/mfs/mfs.c
index ee65f8585..5fce43e1b 100644
--- a/os/ex/subsystems/mfs/mfs.c
+++ b/os/ex/subsystems/mfs/mfs.c
@@ -112,15 +112,49 @@ uint16_t crc16(uint16_t crc, const uint8_t *data, size_t n) {
return crc;
}
+static flash_offset_t mfs_get_bank_offset(MFSDriver *mfsp, mfs_bank_t bank) {
+
+ return bank == MFS_BANK_0 ? flashGetSectorOffset(mfsp->config->flashp,
+ mfsp->config->bank0_start) :
+ flashGetSectorOffset(mfsp->config->flashp,
+ mfsp->config->bank1_start);
+}
+
+/**
+ * @brief Flash read.
+ *
+ * @param[in] mfsp pointer to the @p MFSDriver object
+ * @param[in] offset flash offset
+ * @param[in] n number of bytes to be read
+ * @param[in] rp pointer to the data buffer
+ * @return The operation status.
+ * @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.
+ *
+ * @notapi
+ */
+static mfs_error_t mfs_flash_read(MFSDriver *mfsp, flash_offset_t offset,
+ size_t n, const uint8_t *rp) {
+ flash_error_t ferr;
+
+ ferr = flashRead(mfsp->config->flashp, offset, n, rp);
+ if (ferr != FLASH_NO_ERROR) {
+ return MFS_ERR_FLASH_FAILURE;
+ }
+
+ return MFS_NO_ERROR;
+}
+
/**
* @brief Flash write.
* @note If the option @p MFS_CFG_WRITE_VERIFY is enabled then the flash
* is also read back for verification.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] offset flash offset
- * @param[in] n number of bytes to be read
- * @param[out] rp pointer to the data buffer
+ * @param[in] n number of bytes to be writen
+ * @param[out] wp pointer to the data buffer
* @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
@@ -128,13 +162,13 @@ uint16_t crc16(uint16_t crc, const uint8_t *data, size_t n) {
*
* @notapi
*/
-static mfs_error_t mfs_flash_write(MFSDriver *devp,
+static mfs_error_t mfs_flash_write(MFSDriver *mfsp,
flash_offset_t offset,
- size_t n, const
- uint8_t *p) {
+ size_t n,
+ uint8_t *wp) {
flash_error_t ferr;
- ferr = flashProgram(devp->config->flashp, offset, n, p);
+ ferr = flashProgram(mfsp->config->flashp, offset, n, wp);
if (ferr != FLASH_NO_ERROR) {
return MFS_ERR_FLASH_FAILURE;
}
@@ -145,7 +179,7 @@ static mfs_error_t mfs_flash_write(MFSDriver *devp,
/**
* @brief Erases and verifies all sectors belonging to a bank.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] bank bank to be erased
* @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed.
@@ -154,30 +188,72 @@ static mfs_error_t mfs_flash_write(MFSDriver *devp,
*
* @notapi
*/
-static mfs_error_t mfs_bank_erase(MFSDriver *devp, mfs_bank_t bank) {
+static mfs_error_t mfs_bank_erase(MFSDriver *mfsp, mfs_bank_t bank) {
flash_sector_t sector, end;
if (bank == MFS_BANK_0) {
- sector = devp->config->bank0_start;
- end = devp->config->bank0_start + devp->config->bank0_sectors;
+ sector = mfsp->config->bank0_start;
+ end = mfsp->config->bank0_start + mfsp->config->bank0_sectors;
}
else {
- sector = devp->config->bank1_start;
- end = devp->config->bank1_start + devp->config->bank1_sectors;
+ sector = mfsp->config->bank1_start;
+ end = mfsp->config->bank1_start + mfsp->config->bank1_sectors;
}
while (sector < end) {
flash_error_t ferr;
- ferr = flashStartEraseSector(devp->config->flashp, sector);
+ ferr = flashStartEraseSector(mfsp->config->flashp, sector);
if (ferr != FLASH_NO_ERROR) {
return MFS_ERR_FLASH_FAILURE;
}
- ferr = flashWaitErase(devp->config->flashp);
+ ferr = flashWaitErase(mfsp->config->flashp);
if (ferr != FLASH_NO_ERROR) {
return MFS_ERR_FLASH_FAILURE;
}
- ferr = flashVerifyErase(devp->config->flashp, sector);
+ ferr = flashVerifyErase(mfsp->config->flashp, sector);
+ if (ferr != FLASH_NO_ERROR) {
+ return MFS_ERR_FLASH_FAILURE;
+ }
+
+ sector++;
+ }
+
+ return MFS_NO_ERROR;
+}
+
+/**
+ * @brief Erases and verifies all sectors belonging to a bank.
+ *
+ * @param[in] mfsp pointer to the @p MFSDriver object
+ * @param[in] bank bank to be erased
+ * @return The operation status.
+ * @retval MFS_NO_ERROR if the operation has been successfully completed.
+ * @retval MFS_ERR_NOT_ERASED if the bank is not erased
+ * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
+ * failures.
+ *
+ * @notapi
+ */
+static mfs_error_t mfs_bank_verify_erase(MFSDriver *mfsp, mfs_bank_t bank) {
+ flash_sector_t sector, end;
+
+ if (bank == MFS_BANK_0) {
+ sector = mfsp->config->bank0_start;
+ end = mfsp->config->bank0_start + mfsp->config->bank0_sectors;
+ }
+ else {
+ sector = mfsp->config->bank1_start;
+ end = mfsp->config->bank1_start + mfsp->config->bank1_sectors;
+ }
+
+ while (sector < end) {
+ flash_error_t ferr;
+
+ ferr = flashVerifyErase(mfsp->config->flashp, sector);
+ if (ferr == FLASH_ERROR_VERIFY) {
+ return MFS_ERR_NOT_ERASED;
+ }
if (ferr != FLASH_NO_ERROR) {
return MFS_ERR_FLASH_FAILURE;
}
@@ -191,7 +267,7 @@ static mfs_error_t mfs_bank_erase(MFSDriver *devp, mfs_bank_t bank) {
/**
* @brief Writes the validation header in a bank.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] bank bank to be validated
* @param[in] cnt value for the flash usage counter
* @return The operation status.
@@ -201,17 +277,17 @@ static mfs_error_t mfs_bank_erase(MFSDriver *devp, mfs_bank_t bank) {
*
* @notapi
*/
-static mfs_error_t mfs_bank_set_header(MFSDriver *devp,
+static mfs_error_t mfs_bank_set_header(MFSDriver *mfsp,
mfs_bank_t bank,
uint32_t cnt) {
flash_sector_t sector;
mfs_bank_header_t header;
if (bank == MFS_BANK_0) {
- sector = devp->config->bank0_start;
+ sector = mfsp->config->bank0_start;
}
else {
- sector = devp->config->bank1_start;
+ sector = mfsp->config->bank1_start;
}
header.magic1 = MFS_BANK_MAGIC_1;
@@ -222,8 +298,8 @@ static mfs_error_t mfs_bank_set_header(MFSDriver *devp,
(const uint8_t *)&header,
sizeof (flash_sector_t) - sizeof (uint16_t));
- return mfs_flash_write(devp,
- flashGetSectorOffset(devp->config->flashp, sector),
+ return mfs_flash_write(mfsp,
+ flashGetSectorOffset(mfsp->config->flashp, sector),
sizeof (mfs_bank_header_t),
(const uint8_t *)&header);
}
@@ -231,7 +307,7 @@ static mfs_error_t mfs_bank_set_header(MFSDriver *devp,
/**
* @brief Copies all records from a bank to another.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] sbank source bank
* @param[in] dbank destination bank
* @return The operation status.
@@ -241,11 +317,11 @@ static mfs_error_t mfs_bank_set_header(MFSDriver *devp,
*
* @notapi
*/
-static mfs_error_t mfs_bank_copy(MFSDriver *devp,
+static mfs_error_t mfs_bank_copy(MFSDriver *mfsp,
mfs_bank_t sbank,
mfs_bank_t dbank) {
- (void)devp;
+ (void)mfsp;
(void)sbank;
(void)dbank;
@@ -255,16 +331,16 @@ static mfs_error_t mfs_bank_copy(MFSDriver *devp,
/**
* @brief Selects a bank as current.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] bank bank to be erased
* @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed.
*
* @notapi
*/
-static mfs_error_t mfs_bank_mount(MFSDriver *devp, mfs_bank_t bank) {
+static mfs_error_t mfs_bank_mount(MFSDriver *mfsp, mfs_bank_t bank) {
- (void)devp;
+ (void)mfsp;
(void)bank;
return MFS_NO_ERROR;
@@ -273,26 +349,36 @@ static mfs_error_t mfs_bank_mount(MFSDriver *devp, mfs_bank_t bank) {
/**
* @brief Determines the state of a flash bank.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] bank the bank identifier
+ * @param[out[ statep bank state
* @param[out] cntp bank counter value, only valid if the bank is not
* in the @p MFS_BANK_GARBAGE or @p MFS_BANK_ERASED
* states.
*
* @return The bank state.
- * @retval MFS_BANK_ERASED if the bank is fully erased.
- * @retval MFS_BANK_OK if the bank contains valid data.
- * @retval MFS_BANK_PARTIAL if the bank contains errors but the data is still
- * readable.
- * @retval MFS_BANK_GARBAGE if the bank contains unreadable garbage.
+ * @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.
*/
-static mfs_bank_state_t mfs_get_bank_state(MFSDriver *devp,
- mfs_bank_t bank,
- uint32_t *cntp) {
+static mfs_error_t mfs_get_bank_state(MFSDriver *mfsp,
+ mfs_bank_t bank,
+ mfs_bank_state_t *statep,
+ uint32_t *cntp) {
+ mfs_error_t err;
+
+ /* Special case where the block is fully erased.*/
+ err = mfs_bank_verify_erase(mfsp, bank);
+ if (err == MFS_NO_ERROR) {
+ *statep = MFS_BANK_ERASED;
+ return MFS_BANK_OK;
+ }
- (void)devp;
- (void)bank;
- (void)cntp;
+ /* Reading the header of the current bank into the transient buffer.*/
+ RET_ON_ERROR(mfs_flash_read(mfsp,
+ mfs_get_bank_offset(mfsp, bank),
+ sizeof (mfs_bank_header_t),
+ (void *)&mfsp->buffer.bhdr));
return MFS_BANK_OK;
}
@@ -300,7 +386,7 @@ static mfs_bank_state_t mfs_get_bank_state(MFSDriver *devp,
/**
* @brief Performs a flash partition mount attempt.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @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
@@ -310,13 +396,13 @@ static mfs_bank_state_t mfs_get_bank_state(MFSDriver *devp,
*
* @api
*/
-static mfs_error_t mfs_try_mount(MFSDriver *devp) {
+static mfs_error_t mfs_try_mount(MFSDriver *mfsp) {
mfs_bank_state_t sts0, sts1;
uint32_t cnt0 = 0, cnt1 = 0;
/* Assessing the state of the two banks.*/
- sts0 = mfs_get_bank_state(devp, MFS_BANK_0, &cnt0);
- sts1 = mfs_get_bank_state(devp, MFS_BANK_1, &cnt1);
+ RET_ON_ERROR(mfs_get_bank_state(mfsp, MFS_BANK_0, &sts0, &cnt0));
+ RET_ON_ERROR(mfs_get_bank_state(mfsp, MFS_BANK_1, &sts1, &cnt1));
/* Handling all possible scenarios, each one requires its own recovery
strategy.*/
@@ -324,33 +410,33 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
case PAIR(MFS_BANK_ERASED, MFS_BANK_ERASED):
/* Both banks erased, first initialization.*/
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_0, 1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_0, 1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
return MFS_NO_ERROR;
case PAIR(MFS_BANK_ERASED, MFS_BANK_OK):
/* Normal situation, bank one is used.*/
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_1));
return MFS_NO_ERROR;
case PAIR(MFS_BANK_ERASED, MFS_BANK_PARTIAL):
/* Bank zero is erased, bank one has problems.*/
- RET_ON_ERROR(mfs_bank_copy(devp, MFS_BANK_1, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_0, cnt1 + 1));
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_copy(mfsp, MFS_BANK_1, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_0, cnt1 + 1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
return MFS_WARN_REPAIR;
case PAIR(MFS_BANK_ERASED, MFS_BANK_GARBAGE):
/* Bank zero is erased, bank one is not readable.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_0, 1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_0, 1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
return MFS_WARN_REPAIR;
case PAIR(MFS_BANK_OK, MFS_BANK_ERASED):
/* Normal situation, bank zero is used.*/
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
return MFS_NO_ERROR;
case PAIR(MFS_BANK_OK, MFS_BANK_OK):
@@ -358,13 +444,13 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
older one.*/
if (cnt0 > cnt1) {
/* Bank 0 is newer.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
}
else {
/* Bank 1 is newer.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_1));
}
return MFS_WARN_REPAIR;
@@ -373,31 +459,31 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
if (cnt0 > cnt1) {
/* Normal bank zero is more recent than the partial bank one, the
partial bank needs to be erased.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
}
else {
/* Partial bank one is more recent than the normal bank zero.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_copy(devp, MFS_BANK_1, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_0, cnt1 + 1));
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_copy(mfsp, MFS_BANK_1, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_0, cnt1 + 1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
}
return MFS_WARN_REPAIR;
case PAIR(MFS_BANK_OK, MFS_BANK_GARBAGE):
/* Bank zero is normal, bank one is unreadable.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
return MFS_WARN_REPAIR;
case PAIR(MFS_BANK_PARTIAL, MFS_BANK_ERASED):
/* Bank zero has problems, bank one is erased.*/
- RET_ON_ERROR(mfs_bank_copy(devp, MFS_BANK_0, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_1, cnt0 + 1));
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_copy(mfsp, MFS_BANK_0, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_1, cnt0 + 1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_1));
return MFS_WARN_REPAIR;
case PAIR(MFS_BANK_PARTIAL, MFS_BANK_OK):
@@ -405,16 +491,16 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
if (cnt1 > cnt0) {
/* Normal bank one is more recent than the partial bank zero, the
partial bank has to be erased.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_1));
}
else {
/* Partial bank zero is more recent than the normal bank one.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_copy(devp, MFS_BANK_0, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_1, cnt0 + 1));
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_copy(mfsp, MFS_BANK_0, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_1, cnt0 + 1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_1));
}
return MFS_WARN_REPAIR;
@@ -422,59 +508,59 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
/* Both banks have problems.*/
if (cnt0 > cnt1) {
/* Bank zero is newer, copying in bank one and using it.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_copy(devp, MFS_BANK_0, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_1, cnt0 + 1));
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_copy(mfsp, MFS_BANK_0, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_1, cnt0 + 1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_1));
}
else {
/* Bank one is newer, copying in bank zero and using it.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_copy(devp, MFS_BANK_1, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_0, cnt1 + 1));
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_copy(mfsp, MFS_BANK_1, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_0, cnt1 + 1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
}
return MFS_WARN_REPAIR;
case PAIR(MFS_BANK_PARTIAL, MFS_BANK_GARBAGE):
/* Bank zero has problems, bank one is unreadable.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_copy(devp, MFS_BANK_0, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_1, cnt0 + 1));
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_copy(mfsp, MFS_BANK_0, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_1, cnt0 + 1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_1));
return MFS_WARN_REPAIR;
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_ERASED):
/* Bank zero is unreadable, bank one is erased.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_0, 1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_0, 1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
return MFS_WARN_REPAIR;
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_OK):
/* Bank zero is unreadable, bank one is normal.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_1));
return MFS_WARN_REPAIR;
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_PARTIAL):
/* Bank zero is unreadable, bank one has problems.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_copy(devp, MFS_BANK_1, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_0, cnt0 + 1));
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_copy(mfsp, MFS_BANK_1, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_0, cnt0 + 1));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
return MFS_WARN_REPAIR;
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_GARBAGE):
/* Both banks are unreadable, reinitializing.*/
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
- RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
- RET_ON_ERROR(mfs_bank_set_header(devp, MFS_BANK_0, 1));
- RET_ON_ERROR(mfs_bank_mount(devp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
+ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
+ RET_ON_ERROR(mfs_bank_set_header(mfsp, MFS_BANK_0, 1));
+ RET_ON_ERROR(mfs_bank_mount(mfsp, MFS_BANK_0));
return MFS_WARN_REPAIR;
default:
@@ -492,53 +578,53 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
/**
* @brief Initializes an instance.
*
- * @param[out] devp pointer to the @p MFSDriver object
+ * @param[out] mfsp pointer to the @p MFSDriver object
*
* @init
*/
-void mfsObjectInit(MFSDriver *devp) {
+void mfsObjectInit(MFSDriver *mfsp) {
- osalDbgCheck(devp != NULL);
+ osalDbgCheck(mfsp != NULL);
- devp->state = MFS_STOP;
- devp->config = NULL;
+ mfsp->state = MFS_STOP;
+ mfsp->config = NULL;
}
/**
* @brief Configures and activates a MFS driver.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] config pointer to the configuration
*
* @api
*/
-void mfsStart(MFSDriver *devp, const MFSConfig *config) {
+void mfsStart(MFSDriver *mfsp, const MFSConfig *config) {
- osalDbgCheck((devp != NULL) && (config != NULL));
- osalDbgAssert(devp->state != MFS_UNINIT, "invalid state");
+ osalDbgCheck((mfsp != NULL) && (config != NULL));
+ osalDbgAssert(mfsp->state != MFS_UNINIT, "invalid state");
- if (devp->state == MFS_STOP) {
+ if (mfsp->state == MFS_STOP) {
- devp->config = config;
- devp->state = MFS_READY;
+ mfsp->config = config;
+ mfsp->state = MFS_READY;
}
}
/**
* @brief Deactivates a MFS driver.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
*
* @api
*/
-void mfsStop(MFSDriver *devp) {
+void mfsStop(MFSDriver *mfsp) {
- osalDbgCheck(devp != NULL);
- osalDbgAssert(devp->state != MFS_UNINIT, "invalid state");
+ osalDbgCheck(mfsp != NULL);
+ osalDbgAssert(mfsp->state != MFS_UNINIT, "invalid state");
- if (devp->state != MFS_STOP) {
+ if (mfsp->state != MFS_STOP) {
- devp->state = MFS_STOP;
+ mfsp->state = MFS_STOP;
}
}
@@ -547,7 +633,7 @@ void mfsStop(MFSDriver *devp) {
* @details This functions checks the storage internal state and eventually
* performs the required initialization or repair operations.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @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
@@ -557,14 +643,14 @@ void mfsStop(MFSDriver *devp) {
*
* @api
*/
-mfs_error_t mfsMount(MFSDriver *devp) {
+mfs_error_t mfsMount(MFSDriver *mfsp) {
unsigned i;
/* Attempting to mount the managed partition.*/
for (i = 0; i < MFS_CFG_MAX_REPAIR_ATTEMPTS; i++) {
mfs_error_t err;
- err = mfs_try_mount(devp);
+ err = mfs_try_mount(mfsp);
if (!MFS_IS_ERROR(err))
return err;
}
@@ -575,9 +661,9 @@ mfs_error_t mfsMount(MFSDriver *devp) {
/**
* @brief Unmounts a manage flash storage.
*/
-mfs_error_t mfsUnmount(MFSDriver *devp) {
+mfs_error_t mfsUnmount(MFSDriver *mfsp) {
- (void)devp;
+ (void)mfsp;
return MFS_NO_ERROR;
}
@@ -585,7 +671,7 @@ mfs_error_t mfsUnmount(MFSDriver *devp) {
/**
* @brief Retrieves and reads a data record.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] id record numeric identifier
* @param[in,out] np on input is the maximum buffer size, on return it is
* the size of the data copied into the buffer
@@ -597,10 +683,10 @@ mfs_error_t mfsUnmount(MFSDriver *devp) {
*
* @api
*/
-mfs_error_t mfsReadRecord(MFSDriver *devp, uint32_t id,
+mfs_error_t mfsReadRecord(MFSDriver *mfsp, uint32_t id,
uint32_t *np, uint8_t *buffer) {
- (void)devp;
+ (void)mfsp;
(void)id;
(void)np;
(void)buffer;
@@ -611,7 +697,7 @@ mfs_error_t mfsReadRecord(MFSDriver *devp, uint32_t id,
/**
* @brief Creates or updates a data record.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] id record numeric identifier
* @param[in] n size of data to be written, it cannot be zero
* @param[in] buffer pointer to a buffer for record data
@@ -622,10 +708,10 @@ mfs_error_t mfsReadRecord(MFSDriver *devp, uint32_t id,
*
* @api
*/
-mfs_error_t mfsWriteRecord(MFSDriver *devp, uint32_t id,
+mfs_error_t mfsWriteRecord(MFSDriver *mfsp, uint32_t id,
uint32_t n, const uint8_t *buffer) {
- (void)devp;
+ (void)mfsp;
(void)id;
(void)n;
(void)buffer;
@@ -636,7 +722,7 @@ mfs_error_t mfsWriteRecord(MFSDriver *devp, uint32_t id,
/**
* @brief Erases a data record.
*
- * @param[in] devp pointer to the @p MFSDriver object
+ * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] id record numeric identifier
* @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed.
@@ -645,9 +731,9 @@ mfs_error_t mfsWriteRecord(MFSDriver *devp, uint32_t id,
*
* @api
*/
-mfs_error_t mfsEraseRecord(MFSDriver *devp, uint32_t id) {
+mfs_error_t mfsEraseRecord(MFSDriver *mfsp, uint32_t id) {
- (void)devp;
+ (void)mfsp;
(void)id;
return MFS_NO_ERROR;
diff --git a/os/ex/subsystems/mfs/mfs.h b/os/ex/subsystems/mfs/mfs.h
index 2e11ebeac..8dd05a48f 100644
--- a/os/ex/subsystems/mfs/mfs.h
+++ b/os/ex/subsystems/mfs/mfs.h
@@ -112,10 +112,11 @@ typedef enum {
MFS_NO_ERROR = 0,
MFS_WARN_REPAIR = 1,
MFS_WARN_GC = 2,
- MFS_ERR_NOT_FOUND = -1,
- MFS_ERR_CRC = -2,
- MFS_ERR_FLASH_FAILURE = -3,
- MFS_ERR_INTERNAL = -4
+ MFS_ERR_NOT_ERASED = -1,
+ MFS_ERR_NOT_FOUND = -2,
+ MFS_ERR_CRC = -3,
+ MFS_ERR_FLASH_FAILURE = -4,
+ MFS_ERR_INTERNAL = -5
} mfs_error_t;
/**
@@ -206,7 +207,7 @@ typedef struct {
*/
flash_sector_t bank1_start;
/**
- * #brief Number of sectors for bank 1.
+ * @brief Number of sectors for bank 1.
*/
flash_sector_t bank1_sectors;
} MFSConfig;
@@ -246,6 +247,14 @@ typedef struct {
* @note Zero means that ther is not a record with that id.
*/
flash_offset_t instances[MFS_CFG_MAX_RECORDS];
+ /**
+ * @brief Transient buffer.
+ */
+ union {
+ mfs_data_header_t dhdr;
+ mfs_bank_header_t bhdr;
+ uint8_t data[32];
+ } buffer;
} MFSDriver;
/*===========================================================================*/
diff --git a/os/hal/lib/peripherals/flash/hal_flash.c b/os/hal/lib/peripherals/flash/hal_flash.c
index 7bc0845bb..4ae5211d4 100644
--- a/os/hal/lib/peripherals/flash/hal_flash.c
+++ b/os/hal/lib/peripherals/flash/hal_flash.c
@@ -54,6 +54,7 @@
* @return An error code.
* @retval FLASH_NO_ERROR if there is no erase operation in progress.
* @retval FLASH_ERROR_ERASE if the erase operation failed.
+ * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
*/
flash_error_t flashWaitErase(BaseFlash *devp) {
diff --git a/os/hal/lib/peripherals/flash/hal_flash.h b/os/hal/lib/peripherals/flash/hal_flash.h
index f6e83d580..bfd1974c5 100644
--- a/os/hal/lib/peripherals/flash/hal_flash.h
+++ b/os/hal/lib/peripherals/flash/hal_flash.h
@@ -218,6 +218,7 @@ typedef struct {
* @retval FLASH_NO_ERROR if there is no erase operation in progress.
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
* @retval FLASH_ERROR_READ if the read operation failed.
+ * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
*
* @api
*/
@@ -235,6 +236,7 @@ typedef struct {
* @retval FLASH_NO_ERROR if there is no erase operation in progress.
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
* @retval FLASH_ERROR_PROGRAM if the program operation failed.
+ * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
*
* @api
*/
@@ -248,6 +250,7 @@ typedef struct {
* @return An error code.
* @retval FLASH_NO_ERROR if there is no erase operation in progress.
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
+ * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
*
* @api
*/
@@ -262,6 +265,7 @@ typedef struct {
* @return An error code.
* @retval FLASH_NO_ERROR if there is no erase operation in progress.
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
+ * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
*
* @api
*/
@@ -278,6 +282,7 @@ typedef struct {
* @retval FLASH_NO_ERROR if there is no erase operation in progress.
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
* @retval FLASH_ERROR_ERASE if the erase operation failed.
+ * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
*
* @api
*/
@@ -290,9 +295,10 @@ typedef struct {
* @param[in] ip pointer to a @p BaseFlash or derived class
* @param[in] sector sector to be verified
* @return An error code.
- * @retval FLASH_NO_ERROR if there is no erase operation in progress.
+ * @retval FLASH_NO_ERROR if the sector is erased.
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
* @retval FLASH_ERROR_VERIFY if the verify operation failed.
+ * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
*
* @api
*/