From 172d281e84c6f095ea642e925424104aeec60702 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 14 Nov 2017 10:34:18 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10995 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/lib/complex/mfs/mfs.c | 151 ++++++++++++--------- os/hal/lib/complex/mfs/mfs.h | 13 +- .../multi/QSPI-MFS/Makefile-stm32l476_discovery | 2 +- testhal/STM32/multi/QSPI-MFS/main.c | 26 +++- 4 files changed, 117 insertions(+), 75 deletions(-) diff --git a/os/hal/lib/complex/mfs/mfs.c b/os/hal/lib/complex/mfs/mfs.c index f28080d31..11c829eb4 100644 --- a/os/hal/lib/complex/mfs/mfs.c +++ b/os/hal/lib/complex/mfs/mfs.c @@ -145,9 +145,6 @@ static flash_offset_t mfs_flash_get_bank_offset(MFSDriver *mfsp, * @param[in] n number of bytes to be read * @param[out] 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 */ @@ -157,6 +154,7 @@ static mfs_error_t mfs_flash_read(MFSDriver *mfsp, flash_offset_t offset, ferr = flashRead(mfsp->config->flashp, offset, n, rp); if (ferr != FLASH_NO_ERROR) { + mfsp->state = MFS_READY; return MFS_ERR_FLASH_FAILURE; } @@ -173,10 +171,6 @@ static mfs_error_t mfs_flash_read(MFSDriver *mfsp, flash_offset_t offset, * @param[in] n number of bytes to be written * @param[in] wp pointer to the data buffer * @return The operation status. - * @retval MFS_NO_ERROR if the operation has been successfully completed. - * @retval MFS_ERR_VERIFY if the verify operation failed. - * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW - * failures. * * @notapi */ @@ -188,6 +182,7 @@ static mfs_error_t mfs_flash_write(MFSDriver *mfsp, ferr = flashProgram(mfsp->config->flashp, offset, n, wp); if (ferr != FLASH_NO_ERROR) { + mfsp->state = MFS_READY; return MFS_ERR_FLASH_FAILURE; } @@ -197,7 +192,8 @@ static mfs_error_t mfs_flash_write(MFSDriver *mfsp, size_t chunk = n <= MFS_CFG_BUFFER_SIZE ? n : MFS_CFG_BUFFER_SIZE; RET_ON_ERROR(mfs_flash_read(mfsp, offset, chunk, mfsp->buffer.data8)); if (memcmp((void *)mfsp->buffer.data8, (void *)wp, chunk)) { - return MFS_ERR_VERIFY; + mfsp->state = MFS_READY; + return MFS_ERR_FLASH_FAILURE; } n -= chunk; wp += chunk; @@ -217,9 +213,6 @@ static mfs_error_t mfs_flash_write(MFSDriver *mfsp, * @param[in] soffset source flash offset * @param[in] n number of bytes to be copied * @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 */ @@ -259,9 +252,6 @@ static mfs_error_t mfs_flash_copy(MFSDriver *mfsp, * @param[in] limit flash limit offset * @param[out] sts assessed record state * @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 */ @@ -304,9 +294,6 @@ static mfs_error_t mfs_record_check(MFSDriver *mfsp, * @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_FLASH_FAILURE if the flash memory is unusable because HW - * failures. * * @notapi */ @@ -327,14 +314,17 @@ static mfs_error_t mfs_bank_erase(MFSDriver *mfsp, mfs_bank_t bank) { ferr = flashStartEraseSector(mfsp->config->flashp, sector); if (ferr != FLASH_NO_ERROR) { + mfsp->state = MFS_READY; return MFS_ERR_FLASH_FAILURE; } ferr = flashWaitErase(mfsp->config->flashp); if (ferr != FLASH_NO_ERROR) { + mfsp->state = MFS_READY; return MFS_ERR_FLASH_FAILURE; } ferr = flashVerifyErase(mfsp->config->flashp, sector); if (ferr != FLASH_NO_ERROR) { + mfsp->state = MFS_READY; return MFS_ERR_FLASH_FAILURE; } @@ -350,10 +340,6 @@ static mfs_error_t mfs_bank_erase(MFSDriver *mfsp, mfs_bank_t bank) { * @param[in] mfsp pointer to the @p MFSDriver object * @param[in] bank bank to be verified * @return The operation status. - * @retval MFS_NO_ERROR if the operation has been successfully completed. - * @retval MFS_ERR_VERIFY if the bank is not erased - * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW - * failures. * * @notapi */ @@ -374,9 +360,10 @@ static mfs_error_t mfs_bank_verify_erase(MFSDriver *mfsp, mfs_bank_t bank) { ferr = flashVerifyErase(mfsp->config->flashp, sector); if (ferr == FLASH_ERROR_VERIFY) { - return MFS_ERR_VERIFY; + return MFS_ERR_NOT_ERASED; } if (ferr != FLASH_NO_ERROR) { + mfsp->state = MFS_READY; return MFS_ERR_FLASH_FAILURE; } @@ -394,8 +381,6 @@ static mfs_error_t mfs_bank_verify_erase(MFSDriver *mfsp, mfs_bank_t bank) { * @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_ERR_FLASH_FAILURE if the flash memory is unusable because HW - * failures. * * @notapi */ @@ -440,9 +425,8 @@ static mfs_error_t mfs_bank_write_header(MFSDriver *mfsp, * @param[in] endcb callback to be called after scanning or @p NULL * * @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_bank_scan_records(MFSDriver *mfsp, mfs_bank_t bank, @@ -526,9 +510,6 @@ static mfs_error_t mfs_bank_scan_records(MFSDriver *mfsp, * . * @param[out] cntp bank counter * @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 */ @@ -581,7 +562,7 @@ static mfs_error_t mfs_bank_get_state(MFSDriver *mfsp, *statep = MFS_BANK_ERASED; } - return MFS_NO_ERROR; + return err; } /** @@ -597,9 +578,6 @@ static mfs_error_t mfs_bank_get_state(MFSDriver *mfsp, * - MFS_BANK_OK * . * @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 */ @@ -633,9 +611,6 @@ static mfs_error_t mfs_bank_mount(MFSDriver *mfsp, * * @param[out] mfsp pointer to the @p MFSDriver object * @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 */ @@ -666,11 +641,13 @@ static mfs_error_t mfs_garbage_collect(MFSDriver *mfsp) { } } - /* The header is written after the data.*/ - RET_ON_ERROR(mfs_bank_write_header(mfsp, dbank, 1)); - /* New current bank.*/ mfsp->current_bank = dbank; + mfsp->current_counter += 1U; + mfsp->next_offset = dest_offset; + + /* The header is written after the data.*/ + RET_ON_ERROR(mfs_bank_write_header(mfsp, dbank, mfsp->current_counter)); /* The source bank is erased last.*/ RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0)); @@ -683,11 +660,6 @@ static mfs_error_t mfs_garbage_collect(MFSDriver *mfsp) { * * @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 */ @@ -832,7 +804,6 @@ void mfsStart(MFSDriver *mfsp, const MFSConfig *config) { "invalid state"); mfsp->config = config; - mfs_state_reset(mfsp); mfsp->state = MFS_READY; } @@ -850,7 +821,6 @@ void mfsStop(MFSDriver *mfsp) { "invalid state"); mfsp->config = NULL; - mfs_state_reset(mfsp); mfsp->state = MFS_STOP; } @@ -864,8 +834,9 @@ void mfsStop(MFSDriver *mfsp) { * @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_INV_STATE if the volume is mounted. * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW - * failures. + * failures. Causes the volume to be unmounted. * * @api */ @@ -873,7 +844,15 @@ mfs_error_t mfsMount(MFSDriver *mfsp) { unsigned i; osalDbgCheck(mfsp != NULL); - osalDbgAssert(mfsp->state == MFS_READY, "invalid state"); + osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED), + "invalid state"); + + if (mfsp->state != MFS_READY) { + return MFS_ERR_INV_STATE; + } + + /* Clearing state.*/ + mfs_state_reset(mfsp); /* Attempting to mount the managed partition.*/ for (i = 0; i < MFS_CFG_MAX_REPAIR_ATTEMPTS; i++) { @@ -891,12 +870,24 @@ mfs_error_t mfsMount(MFSDriver *mfsp) { /** * @brief Unmounts a managed flash storage. + * + * @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_ERR_INV_STATE if the volume is not mounted. + * + * @api */ mfs_error_t mfsUnmount(MFSDriver *mfsp) { - osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state"); + osalDbgCheck(mfsp != NULL); + osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED), + "invalid state"); + + if (mfsp->state != MFS_MOUNTED) { + return MFS_ERR_INV_STATE; + } - mfs_state_reset(mfsp); mfsp->state = MFS_READY; return MFS_NO_ERROR; @@ -907,16 +898,22 @@ mfs_error_t mfsUnmount(MFSDriver *mfsp) { * * @param[in] mfsp pointer to the @p MFSDriver object * @return The operation status. + * @retval MFS_ERR_INV_STATE if the volume is mounted. * @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. + * failures. Causes the volume to be unmounted. * * @api */ mfs_error_t mfsErase(MFSDriver *mfsp) { osalDbgCheck(mfsp != NULL); - osalDbgAssert(mfsp->state == MFS_READY, "invalid state"); + osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED), + "invalid state"); + + if (mfsp->state != MFS_READY) { + return MFS_ERR_INV_STATE; + } RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0)); RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1)); @@ -935,12 +932,12 @@ mfs_error_t mfsErase(MFSDriver *mfsp) { * @param[out] 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_ERR_NOT_FOUND if the specified id does not exists. + * @retval MFS_ERR_INV_STATE if the volume is not mounted. * @retval MFS_ERR_INV_SIZE if the passed buffer is not large enough to * contain the record data. - * @retval MFS_ERR_CRC if retrieved data has a CRC error. + * @retval MFS_ERR_NOT_FOUND if the specified id does not exists. * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW - * failures. + * failures. Causes the volume to be unmounted. * * @api */ @@ -950,7 +947,12 @@ mfs_error_t mfsReadRecord(MFSDriver *mfsp, uint32_t id, osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS) && (np != NULL) && (buffer != NULL)); - osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state"); + osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED), + "invalid state"); + + if (mfsp->state != MFS_MOUNTED) { + return MFS_ERR_INV_STATE; + } /* Checking if the requested record actually exists.*/ if (mfsp->descriptors[id - 1U].offset != 0U) { @@ -972,7 +974,8 @@ mfs_error_t mfsReadRecord(MFSDriver *mfsp, uint32_t id, /* Checking CRC.*/ crc = crc16(0xFFFFU, buffer, *np); if (crc != mfsp->buffer.dhdr.fields.crc) { - return MFS_ERR_CRC; + mfsp->state = MFS_READY; + return MFS_ERR_FLASH_FAILURE; } return MFS_NO_ERROR; @@ -989,10 +992,11 @@ mfs_error_t mfsReadRecord(MFSDriver *mfsp, uint32_t id, * @return The operation status. * @retval MFS_NO_ERROR if the operation has been successfully completed. * @retval MFS_WARN_GC if the operation triggered a garbage collection. + * @retval MFS_ERR_INV_STATE if the volume is not mounted. * @retval MFS_ERR_OUT_OF_MEM if there is not enough flash space for the * operation. * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW - * failures. + * failures. Causes the volume to be unmounted. * * @api */ @@ -1003,7 +1007,12 @@ mfs_error_t mfsWriteRecord(MFSDriver *mfsp, uint32_t id, osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS) && (n > 0U) && (buffer != NULL)); - osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state"); + osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED), + "invalid state"); + + if (mfsp->state != MFS_MOUNTED) { + return MFS_ERR_INV_STATE; + } /* If the required space is beyond the available (compacted) block size then an error is returned. @@ -1071,8 +1080,10 @@ mfs_error_t mfsWriteRecord(MFSDriver *mfsp, uint32_t id, * @p 1 and @p MFS_CFG_MAX_RECORDS * @return The operation status. * @retval MFS_NO_ERROR if the operation has been successfully completed. + * @retval MFS_WARN_GC if the operation triggered a garbage collection. + * @retval MFS_ERR_INV_STATE if the volume is not mounted. * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW - * failures. + * failures. Causes the volume to be unmounted. * @retval MFS_ERR_INTERNAL if an internal logic failure is detected. * * @api @@ -1082,7 +1093,12 @@ mfs_error_t mfsEraseRecord(MFSDriver *mfsp, uint32_t id) { bool warning = false; osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS)); - osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state"); + osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED), + "invalid state"); + + if (mfsp->state != MFS_MOUNTED) { + return MFS_ERR_INV_STATE; + } /* Checking if the requested record actually exists.*/ if (mfsp->descriptors[id - 1U].offset == 0U) { @@ -1134,14 +1150,21 @@ 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_ERR_INV_STATE if the volume is not mounted. * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW - * failures. + * failures. Causes the volume to be unmounted. * * @api */ mfs_error_t mfsPerformGarbageCollection(MFSDriver *mfsp) { - osalDbgAssert(mfsp->state == MFS_MOUNTED, "invalid state"); + osalDbgCheck(mfsp != NULL); + osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED), + "invalid state"); + + if (mfsp->state != MFS_MOUNTED) { + return MFS_ERR_INV_STATE; + } return mfs_garbage_collect(mfsp); } diff --git a/os/hal/lib/complex/mfs/mfs.h b/os/hal/lib/complex/mfs/mfs.h index 433918370..e3504e29a 100644 --- a/os/hal/lib/complex/mfs/mfs.h +++ b/os/hal/lib/complex/mfs/mfs.h @@ -144,14 +144,13 @@ typedef enum { MFS_NO_ERROR = 0, MFS_WARN_REPAIR = 1, MFS_WARN_GC = 2, - MFS_ERR_NOT_FOUND = -1, + MFS_ERR_INV_STATE = -1, MFS_ERR_INV_SIZE = -2, - MFS_ERR_VERIFY = -3, - MFS_ERR_CRC = -4, - MFS_ERR_HEADER = -5, - MFS_ERR_OUT_OF_MEM = -6, - MFS_ERR_FLASH_FAILURE = -7, - MFS_ERR_INTERNAL = -8 + MFS_ERR_NOT_FOUND = -3, + MFS_ERR_OUT_OF_MEM = -4, + MFS_ERR_NOT_ERASED = -5, + MFS_ERR_FLASH_FAILURE = -6, + MFS_ERR_INTERNAL = -7 } mfs_error_t; /** diff --git a/testhal/STM32/multi/QSPI-MFS/Makefile-stm32l476_discovery b/testhal/STM32/multi/QSPI-MFS/Makefile-stm32l476_discovery index 844f08137..b01d07514 100644 --- a/testhal/STM32/multi/QSPI-MFS/Makefile-stm32l476_discovery +++ b/testhal/STM32/multi/QSPI-MFS/Makefile-stm32l476_discovery @@ -5,7 +5,7 @@ # Compiler options here. ifeq ($(USE_OPT),) - USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 + USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16 endif # C specific options here (added to USE_OPT). diff --git a/testhal/STM32/multi/QSPI-MFS/main.c b/testhal/STM32/multi/QSPI-MFS/main.c index 623916957..c3c84a30a 100644 --- a/testhal/STM32/multi/QSPI-MFS/main.c +++ b/testhal/STM32/multi/QSPI-MFS/main.c @@ -20,6 +20,7 @@ #include "hal.h" #include "m25q.h" +#include "mfs.h" /* 16MB device, 2 cycles delay after NCS.*/ const QSPIConfig qspicfg1 = { @@ -60,6 +61,17 @@ const M25QConfig m25qcfg1 = { &qspicfg1 }; +MFSDriver mfs; + +const MFSConfig mfscfg1 = { + (BaseFlash *)&m25q, + 0xFFFFFFFFU, + 131072U, + 0, + 2, + 2, + 2 +}; /* * LED blinker thread, times are in milliseconds. */ @@ -103,17 +115,24 @@ int main(void) { */ chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 1, Thread1, NULL); - /* - * Initializing and starting M25Q driver. - */ + /* Initializing and starting M25Q driver.*/ m25qObjectInit(&m25q); m25qStart(&m25q, &m25qcfg1); + /* Mounting the MFS volume defined in the configuration.*/ + mfsObjectInit(&mfs); + mfsStart(&mfs, &mfscfg1); + mfsMount(&mfs); + /* Reading.*/ err = flashRead(&m25q, 0, 128, buffer); if (err != FLASH_NO_ERROR) chSysHalt("read error"); + mfsUnmount(&mfs); + mfsErase(&mfs); + +#if 0 /* Erasing the first sector and waiting for completion.*/ (void) flashStartEraseSector(&m25q, 0); err = flashWaitErase((BaseFlash *)&m25q); @@ -158,6 +177,7 @@ int main(void) { err = flashWaitErase((BaseFlash *)&m25q); if (err != FLASH_NO_ERROR) chSysHalt("erase error"); +#endif /* * Normal main() thread activity, in this demo it does nothing. -- cgit v1.2.3