More MFS code.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9621 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
82631a20b9
commit
4379ef2278
|
@ -42,10 +42,6 @@
|
||||||
/* Driver local definitions. */
|
/* Driver local definitions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#define MFS_BANK_MAGIC1 0x35A1EC13
|
|
||||||
#define MFS_BANK_MAGIC2 0x0FE14991
|
|
||||||
#define MFS_HEADER_MAGIC 0x1AC7002E
|
|
||||||
|
|
||||||
#define PAIR(a, b) (((unsigned)(a) << 2U) | (unsigned)(b))
|
#define PAIR(a, b) (((unsigned)(a) << 2U) | (unsigned)(b))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,9 +93,122 @@ void mfs_cache_erase_id(MFSDriver *devp, uint32_t id) {
|
||||||
}
|
}
|
||||||
#endif /* MFS_CFG_ID_CACHE_SIZE > 0 */
|
#endif /* MFS_CFG_ID_CACHE_SIZE > 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erases and verifies all sectors belonging to a bank.
|
||||||
|
*
|
||||||
|
* @param[in] devp 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_FLASH_FAILURE if the flash memory is unusable because HW
|
||||||
|
* failures.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static mfs_error_t mfs_bank_erase(MFSDriver *devp, 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;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sector = devp->config->bank1_start;
|
||||||
|
end = devp->config->bank1_start + devp->config->bank1_sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sector < end) {
|
||||||
|
flash_error_t ferr;
|
||||||
|
|
||||||
|
ferr = flashStartEraseSector(devp->config->flashp, sector);
|
||||||
|
if (ferr != FLASH_NO_ERROR) {
|
||||||
|
return MFS_FLASH_FAILURE;
|
||||||
|
}
|
||||||
|
ferr = flashWaitErase(devp->config->flashp);
|
||||||
|
if (ferr != FLASH_NO_ERROR) {
|
||||||
|
return MFS_FLASH_FAILURE;
|
||||||
|
}
|
||||||
|
ferr = flashVerifyErase(devp->config->flashp, sector);
|
||||||
|
if (ferr != FLASH_NO_ERROR) {
|
||||||
|
return MFS_FLASH_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sector++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MFS_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes the validation header in a bank.
|
||||||
|
*
|
||||||
|
* @param[in] devp 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.
|
||||||
|
* @retval MFS_NO_ERROR if the operation has been successfully completed.
|
||||||
|
* @retval MFS_FLASH_FAILURE if the flash memory is unusable because HW
|
||||||
|
* failures.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static mfs_error_t mfs_validate(MFSDriver *devp,
|
||||||
|
mfs_bank_t bank,
|
||||||
|
uint32_t cnt) {
|
||||||
|
|
||||||
|
(void)devp;
|
||||||
|
(void)bank;
|
||||||
|
(void)cnt;
|
||||||
|
|
||||||
|
return MFS_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copies all records from a bank to another.
|
||||||
|
*
|
||||||
|
* @param[in] devp pointer to the @p MFSDriver object
|
||||||
|
* @param[in] sbank source bank
|
||||||
|
* @param[in] dbank destination bank
|
||||||
|
* @return The operation status.
|
||||||
|
* @retval MFS_NO_ERROR if the operation has been successfully completed.
|
||||||
|
* @retval MFS_FLASH_FAILURE if the flash memory is unusable because HW
|
||||||
|
* failures.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static mfs_error_t mfs_copy_bank(MFSDriver *devp,
|
||||||
|
mfs_bank_t sbank,
|
||||||
|
mfs_bank_t dbank) {
|
||||||
|
|
||||||
|
(void)devp;
|
||||||
|
(void)sbank;
|
||||||
|
(void)dbank;
|
||||||
|
|
||||||
|
return MFS_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Selects a bank as current.
|
||||||
|
*
|
||||||
|
* @param[in] devp 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_mount(MFSDriver *devp, mfs_bank_t bank) {
|
||||||
|
|
||||||
|
(void)devp;
|
||||||
|
(void)bank;
|
||||||
|
|
||||||
|
return MFS_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Determines the state of a flash bank.
|
* @brief Determines the state of a flash bank.
|
||||||
*
|
*
|
||||||
|
* @param[in] devp pointer to the @p MFSDriver object
|
||||||
* @param[in] bank the bank identifier
|
* @param[in] bank the bank identifier
|
||||||
* @param[out] cntp bank counter value, only valid if the bank is not
|
* @param[out] cntp bank counter value, only valid if the bank is not
|
||||||
* in the @p MFS_BANK_GARBAGE or @p MFS_BANK_ERASED
|
* in the @p MFS_BANK_GARBAGE or @p MFS_BANK_ERASED
|
||||||
|
@ -112,7 +221,13 @@ void mfs_cache_erase_id(MFSDriver *devp, uint32_t id) {
|
||||||
* readable.
|
* readable.
|
||||||
* @retval MFS_BANK_GARBAGE if the bank contains unreadable garbage.
|
* @retval MFS_BANK_GARBAGE if the bank contains unreadable garbage.
|
||||||
*/
|
*/
|
||||||
static mfs_bank_state_t mfs_get_bank_state(mfs_bank_t bank, uint32_t *cntp) {
|
static mfs_bank_state_t mfs_get_bank_state(MFSDriver *devp,
|
||||||
|
mfs_bank_t bank,
|
||||||
|
uint32_t *cntp) {
|
||||||
|
|
||||||
|
(void)devp;
|
||||||
|
(void)bank;
|
||||||
|
(void)cntp;
|
||||||
|
|
||||||
return MFS_BANK_OK;
|
return MFS_BANK_OK;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +237,7 @@ static mfs_bank_state_t mfs_get_bank_state(mfs_bank_t bank, uint32_t *cntp) {
|
||||||
*
|
*
|
||||||
* @param[in] devp pointer to the @p MFSDriver object
|
* @param[in] devp 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_REPAIR_WARNING if the operation has been completed but a
|
* @retval MFS_REPAIR_WARNING if the operation has been completed but a
|
||||||
* repair has been performed.
|
* repair has been performed.
|
||||||
* @retval MFS_FLASH_FAILURE if the flash memory is unusable because HW
|
* @retval MFS_FLASH_FAILURE if the flash memory is unusable because HW
|
||||||
|
@ -135,8 +250,8 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
|
||||||
uint32_t cnt0 = 0, cnt1 = 0;
|
uint32_t cnt0 = 0, cnt1 = 0;
|
||||||
|
|
||||||
/* Assessing the state of the two banks.*/
|
/* Assessing the state of the two banks.*/
|
||||||
sts0 = mfs_get_bank_state(MFS_BANK_0, &cnt0);
|
sts0 = mfs_get_bank_state(devp, MFS_BANK_0, &cnt0);
|
||||||
sts1 = mfs_get_bank_state(MFS_BANK_1, &cnt1);
|
sts1 = mfs_get_bank_state(devp, MFS_BANK_1, &cnt1);
|
||||||
|
|
||||||
/* Handling all possible scenarios, each one requires its own recovery
|
/* Handling all possible scenarios, each one requires its own recovery
|
||||||
strategy.*/
|
strategy.*/
|
||||||
|
@ -144,33 +259,33 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
|
||||||
|
|
||||||
case PAIR(MFS_BANK_ERASED, MFS_BANK_ERASED):
|
case PAIR(MFS_BANK_ERASED, MFS_BANK_ERASED):
|
||||||
/* Both banks erased, first initialization.*/
|
/* Both banks erased, first initialization.*/
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_0, 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_0, 1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
return MFS_NO_ERROR;
|
return MFS_NO_ERROR;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_ERASED, MFS_BANK_OK):
|
case PAIR(MFS_BANK_ERASED, MFS_BANK_OK):
|
||||||
/* Normal situation, bank one is used.*/
|
/* Normal situation, bank one is used.*/
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_1));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_1));
|
||||||
return MFS_NO_ERROR;
|
return MFS_NO_ERROR;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_ERASED, MFS_BANK_PARTIAL):
|
case PAIR(MFS_BANK_ERASED, MFS_BANK_PARTIAL):
|
||||||
/* Bank zero is erased, bank one has problems.*/
|
/* Bank zero is erased, bank one has problems.*/
|
||||||
RET_ON_ERROR(mfs_copy_bank(MFS_BANK_1, MFS_BANK_0));
|
RET_ON_ERROR(mfs_copy_bank(devp, MFS_BANK_1, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_0, cnt1 + 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_0, cnt1 + 1));
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_ERASED, MFS_BANK_GARBAGE):
|
case PAIR(MFS_BANK_ERASED, MFS_BANK_GARBAGE):
|
||||||
/* Bank zero is erased, bank one is not readable.*/
|
/* Bank zero is erased, bank one is not readable.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_0, 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_0, 1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_OK, MFS_BANK_ERASED):
|
case PAIR(MFS_BANK_OK, MFS_BANK_ERASED):
|
||||||
/* Normal situation, bank zero is used.*/
|
/* Normal situation, bank zero is used.*/
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
return MFS_NO_ERROR;
|
return MFS_NO_ERROR;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_OK, MFS_BANK_OK):
|
case PAIR(MFS_BANK_OK, MFS_BANK_OK):
|
||||||
|
@ -178,13 +293,13 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
|
||||||
older one.*/
|
older one.*/
|
||||||
if (cnt0 > cnt1) {
|
if (cnt0 > cnt1) {
|
||||||
/* Bank 0 is newer.*/
|
/* Bank 0 is newer.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Bank 1 is newer.*/
|
/* Bank 1 is newer.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_1));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_1));
|
||||||
}
|
}
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
|
@ -193,31 +308,31 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
|
||||||
if (cnt0 > cnt1) {
|
if (cnt0 > cnt1) {
|
||||||
/* Normal bank zero is more recent than the partial bank one, the
|
/* Normal bank zero is more recent than the partial bank one, the
|
||||||
partial bank needs to be erased.*/
|
partial bank needs to be erased.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Partial bank one is more recent than the normal bank zero.*/
|
/* Partial bank one is more recent than the normal bank zero.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_copy_bank(MFS_BANK_1, MFS_BANK_0));
|
RET_ON_ERROR(mfs_copy_bank(devp, MFS_BANK_1, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_0, cnt1 + 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_0, cnt1 + 1));
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
}
|
}
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_OK, MFS_BANK_GARBAGE):
|
case PAIR(MFS_BANK_OK, MFS_BANK_GARBAGE):
|
||||||
/* Bank zero is normal, bank one is unreadable.*/
|
/* Bank zero is normal, bank one is unreadable.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_PARTIAL, MFS_BANK_ERASED):
|
case PAIR(MFS_BANK_PARTIAL, MFS_BANK_ERASED):
|
||||||
/* Bank zero has problems, bank one is erased.*/
|
/* Bank zero has problems, bank one is erased.*/
|
||||||
RET_ON_ERROR(mfs_copy_bank(MFS_BANK_0, MFS_BANK_1));
|
RET_ON_ERROR(mfs_copy_bank(devp, MFS_BANK_0, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_1, cnt0 + 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_1, cnt0 + 1));
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_1));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_1));
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_PARTIAL, MFS_BANK_OK):
|
case PAIR(MFS_BANK_PARTIAL, MFS_BANK_OK):
|
||||||
|
@ -225,16 +340,16 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
|
||||||
if (cnt1 > cnt0) {
|
if (cnt1 > cnt0) {
|
||||||
/* Normal bank one is more recent than the partial bank zero, the
|
/* Normal bank one is more recent than the partial bank zero, the
|
||||||
partial bank has to be erased.*/
|
partial bank has to be erased.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_1));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Partial bank zero is more recent than the normal bank one.*/
|
/* Partial bank zero is more recent than the normal bank one.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_copy_bank(MFS_BANK_0, MFS_BANK_1));
|
RET_ON_ERROR(mfs_copy_bank(devp, MFS_BANK_0, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_1, cnt0 + 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_1, cnt0 + 1));
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_1));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_1));
|
||||||
}
|
}
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
|
@ -242,59 +357,59 @@ static mfs_error_t mfs_try_mount(MFSDriver *devp) {
|
||||||
/* Both banks have problems.*/
|
/* Both banks have problems.*/
|
||||||
if (cnt0 > cnt1) {
|
if (cnt0 > cnt1) {
|
||||||
/* Bank zero is newer, copying in bank one and using it.*/
|
/* Bank zero is newer, copying in bank one and using it.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_copy_bank(MFS_BANK_0, MFS_BANK_1));
|
RET_ON_ERROR(mfs_copy_bank(devp, MFS_BANK_0, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_1, cnt0 + 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_1, cnt0 + 1));
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_1));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Bank one is newer, copying in bank zero and using it.*/
|
/* Bank one is newer, copying in bank zero and using it.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_copy_bank(MFS_BANK_1, MFS_BANK_0));
|
RET_ON_ERROR(mfs_copy_bank(devp, MFS_BANK_1, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_0, cnt1 + 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_0, cnt1 + 1));
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
}
|
}
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_PARTIAL, MFS_BANK_GARBAGE):
|
case PAIR(MFS_BANK_PARTIAL, MFS_BANK_GARBAGE):
|
||||||
/* Bank zero has problems, bank one is unreadable.*/
|
/* Bank zero has problems, bank one is unreadable.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_copy_bank(MFS_BANK_0, MFS_BANK_1));
|
RET_ON_ERROR(mfs_copy_bank(devp, MFS_BANK_0, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_1, cnt0 + 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_1, cnt0 + 1));
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_1));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_1));
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_ERASED):
|
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_ERASED):
|
||||||
/* Bank zero is unreadable, bank one is erased.*/
|
/* Bank zero is unreadable, bank one is erased.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_0, 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_0, 1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_OK):
|
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_OK):
|
||||||
/* Bank zero is unreadable, bank one is normal.*/
|
/* Bank zero is unreadable, bank one is normal.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_1));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_1));
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_PARTIAL):
|
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_PARTIAL):
|
||||||
/* Bank zero is unreadable, bank one has problems.*/
|
/* Bank zero is unreadable, bank one has problems.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_copy_bank(MFS_BANK_1, MFS_BANK_0));
|
RET_ON_ERROR(mfs_copy_bank(devp, MFS_BANK_1, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_0, cnt0 + 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_0, cnt0 + 1));
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_GARBAGE):
|
case PAIR(MFS_BANK_GARBAGE, MFS_BANK_GARBAGE):
|
||||||
/* Both banks are unreadable, reinitializing.*/
|
/* Both banks are unreadable, reinitializing.*/
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_0));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_0));
|
||||||
RET_ON_ERROR(mfs_bank_erase(MFS_BANK_1));
|
RET_ON_ERROR(mfs_bank_erase(devp, MFS_BANK_1));
|
||||||
RET_ON_ERROR(mfs_validate(MFS_BANK_0, 1));
|
RET_ON_ERROR(mfs_validate(devp, MFS_BANK_0, 1));
|
||||||
RET_ON_ERROR(mfs_mount(MFS_BANK_0));
|
RET_ON_ERROR(mfs_mount(devp, MFS_BANK_0));
|
||||||
return MFS_REPAIR_WARNING;
|
return MFS_REPAIR_WARNING;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -369,7 +484,7 @@ void mfsStop(MFSDriver *devp) {
|
||||||
*
|
*
|
||||||
* @param[in] devp pointer to the @p MFSDriver object
|
* @param[in] devp 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_REPAIR_WARNING if the operation has been completed but a
|
* @retval MFS_REPAIR_WARNING if the operation has been completed but a
|
||||||
* repair has been performed.
|
* repair has been performed.
|
||||||
* @retval MFS_FLASH_FAILURE if the flash memory is unusable because HW
|
* @retval MFS_FLASH_FAILURE if the flash memory is unusable because HW
|
||||||
|
@ -410,6 +525,10 @@ mfs_error_t mfsUnmount(MFSDriver *devp) {
|
||||||
* @param[in,out] np on input is the maximum buffer size, on return it is
|
* @param[in,out] np on input is the maximum buffer size, on return it is
|
||||||
* the size of the data copied into the buffer
|
* the size of the data copied into the buffer
|
||||||
* @param[in] buffer pointer to a buffer for record data
|
* @param[in] buffer pointer to a buffer for record data
|
||||||
|
* @return The operation status.
|
||||||
|
* @retval MFS_NO_ERROR if the operation has been successfully completed.
|
||||||
|
* @retval MFS_ID_NOT_FOUND if the specified id does not exists.
|
||||||
|
* @retval MFS_CRC_ERROR if retrieved data has a CRC error.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -431,6 +550,10 @@ mfs_error_t mfsReadRecord(MFSDriver *devp, uint32_t id,
|
||||||
* @param[in] id record numeric identifier
|
* @param[in] id record numeric identifier
|
||||||
* @param[in] n size of data to be written, it cannot be zero
|
* @param[in] n size of data to be written, it cannot be zero
|
||||||
* @param[in] buffer pointer to a buffer for record data
|
* @param[in] buffer pointer to a buffer for record data
|
||||||
|
* @return The operation status.
|
||||||
|
* @retval MFS_NO_ERROR if the operation has been successfully completed.
|
||||||
|
* @retval MFS_FLASH_FAILURE if the flash memory is unusable because HW
|
||||||
|
* failures.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -450,6 +573,10 @@ mfs_error_t mfsUpdateRecord(MFSDriver *devp, uint32_t id,
|
||||||
*
|
*
|
||||||
* @param[in] devp pointer to the @p MFSDriver object
|
* @param[in] devp pointer to the @p MFSDriver object
|
||||||
* @param[in] id record numeric identifier
|
* @param[in] id record numeric identifier
|
||||||
|
* @return The operation status.
|
||||||
|
* @retval MFS_NO_ERROR if the operation has been successfully completed.
|
||||||
|
* @retval MFS_FLASH_FAILURE if the flash memory is unusable because HW
|
||||||
|
* failures.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#define MFS_BANK_MAGIC_0 0xEC705ADEU
|
#define MFS_BANK_MAGIC_0 0xEC705ADEU
|
||||||
#define MFS_BANK_MAGIC_1 0xF0339CC5U
|
#define MFS_BANK_MAGIC_1 0xF0339CC5U
|
||||||
#define MFS_HEADER_MAGIC 0x5FAEU
|
#define MFS_HEADER_MAGIC 0x5FAEU
|
||||||
#define MFS_FOOTER_MAGIC 0xEAF5U
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver pre-compile time settings. */
|
/* Driver pre-compile time settings. */
|
||||||
|
@ -157,35 +156,24 @@ typedef struct {
|
||||||
/**
|
/**
|
||||||
* @brief Data header magic.
|
* @brief Data header magic.
|
||||||
*/
|
*/
|
||||||
uint16_t magic;
|
uint16_t magic;
|
||||||
/**
|
|
||||||
* @brief Data identifier.
|
|
||||||
*/
|
|
||||||
uint32_t id;
|
|
||||||
/**
|
|
||||||
* @brief Data size for forward scan.
|
|
||||||
*/
|
|
||||||
uint32_t size;
|
|
||||||
} mfs_data_header_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Type of a data block footer.
|
|
||||||
* @details This structure is placed after each written data block.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
/**
|
|
||||||
* @brief Data size for backward scan.
|
|
||||||
*/
|
|
||||||
uint32_t size;
|
|
||||||
/**
|
/**
|
||||||
* @brief Data CRC.
|
* @brief Data CRC.
|
||||||
*/
|
*/
|
||||||
uint16_t crc;
|
uint16_t crc;
|
||||||
/**
|
/**
|
||||||
* @brief Data footer magic.
|
* @brief Data identifier.
|
||||||
*/
|
*/
|
||||||
uint16_t magic;
|
uint32_t id;
|
||||||
} mfs_data_footer_t;
|
/**
|
||||||
|
* @brief Data size for forward scan.
|
||||||
|
*/
|
||||||
|
uint32_t size;
|
||||||
|
/**
|
||||||
|
* @brief Address of the previous header or zero if none.
|
||||||
|
*/
|
||||||
|
flash_address_t prev_header;
|
||||||
|
} mfs_data_header_t;
|
||||||
|
|
||||||
#if (MFS_CFG_ID_CACHE_SIZE > 0) || defined(__DOXYGEN__)
|
#if (MFS_CFG_ID_CACHE_SIZE > 0) || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
|
@ -281,6 +269,10 @@ typedef struct {
|
||||||
* @brief Pointer to the next free position in the current bank.
|
* @brief Pointer to the next free position in the current bank.
|
||||||
*/
|
*/
|
||||||
flash_address_t next_position;
|
flash_address_t next_position;
|
||||||
|
/**
|
||||||
|
* @brief Pointer to the last header in the list or zero.
|
||||||
|
*/
|
||||||
|
flash_address_t last_header;
|
||||||
/**
|
/**
|
||||||
* @brief Used space in the current bank without considering erased records.
|
* @brief Used space in the current bank without considering erased records.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue