diff options
Diffstat (limited to 'os/ex')
-rw-r--r-- | os/ex/Micron/m25q.c | 63 | ||||
-rw-r--r-- | os/ex/subsystems/mfs/mfs.c | 49 | ||||
-rw-r--r-- | os/ex/subsystems/mfs/mfs.h | 23 |
3 files changed, 89 insertions, 46 deletions
diff --git a/os/ex/Micron/m25q.c b/os/ex/Micron/m25q.c index c109a61e4..3dbb3df62 100644 --- a/os/ex/Micron/m25q.c +++ b/os/ex/Micron/m25q.c @@ -54,17 +54,17 @@ /*===========================================================================*/ static const flash_descriptor_t *m25q_get_descriptor(void *instance); -static flash_error_t m25q_read(void *instance, flash_address_t addr, - uint8_t *rp, size_t n); -static flash_error_t m25q_program(void *instance, flash_address_t addr, - const uint8_t *pp, size_t n); +static flash_error_t m25q_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp); +static flash_error_t m25q_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp); static flash_error_t m25q_start_erase_all(void *instance); static flash_error_t m25q_start_erase_sector(void *instance, flash_sector_t sector); static flash_error_t m25q_query_erase(void *instance, uint32_t *msec); static flash_error_t m25q_verify_erase(void *instance, flash_sector_t sector); -static flash_error_t m25q_read_sfdp(void *instance, uint8_t *rp, - flash_address_t addr, size_t n); +static flash_error_t m25q_read_sfdp(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp); /** * @brief Virtual methods table. @@ -319,13 +319,13 @@ static const flash_descriptor_t *m25q_get_descriptor(void *instance) { return &m25q_descriptor; } -static flash_error_t m25q_read(void *instance, flash_address_t addr, - uint8_t *rp, size_t n) { +static flash_error_t m25q_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp) { M25QDriver *devp = (M25QDriver *)instance; osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U)); - osalDbgCheck((size_t)addr + n <= (size_t)m25q_descriptor.sectors_count * - (size_t)m25q_descriptor.sectors_size); + osalDbgCheck((size_t)offset + n <= (size_t)m25q_descriptor.sectors_count * + (size_t)m25q_descriptor.sectors_size); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -342,11 +342,11 @@ static flash_error_t m25q_read(void *instance, flash_address_t addr, #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI /* Fast read command in QSPI mode.*/ jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ, - addr, M25Q_READ_DUMMY_CYCLES, n, rp); + offset, M25Q_READ_DUMMY_CYCLES, n, rp); #else /* Normal read command in SPI mode.*/ jesd216_cmd_addr_receive(devp->config->busp, M25Q_CMD_READ, - addr, n, rp); + offset, n, rp); #endif /* Ready state again.*/ @@ -358,13 +358,13 @@ static flash_error_t m25q_read(void *instance, flash_address_t addr, return FLASH_NO_ERROR; } -static flash_error_t m25q_program(void *instance, flash_address_t addr, - const uint8_t *pp, size_t n) { +static flash_error_t m25q_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp) { M25QDriver *devp = (M25QDriver *)instance; osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U)); - osalDbgCheck((size_t)addr + n <= (size_t)m25q_descriptor.sectors_count * - (size_t)m25q_descriptor.sectors_size); + osalDbgCheck((size_t)offset + n <= (size_t)m25q_descriptor.sectors_count * + (size_t)m25q_descriptor.sectors_size); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -383,7 +383,7 @@ static flash_error_t m25q_program(void *instance, flash_address_t addr, flash_error_t err; /* Data size that can be written in a single program page operation.*/ - size_t chunk = (size_t)(((addr | PAGE_MASK) + 1U) - addr); + size_t chunk = (size_t)(((offset | PAGE_MASK) + 1U) - offset); if (chunk > n) { chunk = n; } @@ -392,7 +392,7 @@ static flash_error_t m25q_program(void *instance, flash_address_t addr, jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); /* Page program command.*/ - jesd216_cmd_addr_send(devp->config->busp, M25Q_CMD_PAGE_PROGRAM, addr, + jesd216_cmd_addr_send(devp->config->busp, M25Q_CMD_PAGE_PROGRAM, offset, chunk, pp); /* Wait for status and check errors.*/ @@ -406,9 +406,9 @@ static flash_error_t m25q_program(void *instance, flash_address_t addr, } /* Next page.*/ - addr += chunk; - pp += chunk; - n -= chunk; + offset += chunk; + pp += chunk; + n -= chunk; } /* Ready state again.*/ @@ -452,7 +452,7 @@ static flash_error_t m25q_start_erase_all(void *instance) { static flash_error_t m25q_start_erase_sector(void *instance, flash_sector_t sector) { M25QDriver *devp = (M25QDriver *)instance; - flash_address_t addr = (flash_address_t)(sector * SECTOR_SIZE); + flash_offset_t offset = (flash_offset_t)(sector * SECTOR_SIZE); osalDbgCheck(instance != NULL); osalDbgCheck(sector < m25q_descriptor.sectors_count); @@ -473,7 +473,7 @@ static flash_error_t m25q_start_erase_sector(void *instance, jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); /* Sector erase command.*/ - jesd216_cmd_addr(devp->config->busp, M25Q_CMD_SECTOR_ERASE, addr); + jesd216_cmd_addr(devp->config->busp, M25Q_CMD_SECTOR_ERASE, offset); /* Bus released.*/ jesd216_bus_release(devp->config->busp); @@ -485,7 +485,7 @@ static flash_error_t m25q_verify_erase(void *instance, flash_sector_t sector) { M25QDriver *devp = (M25QDriver *)instance; uint8_t cmpbuf[M25Q_COMPARE_BUFFER_SIZE]; - flash_address_t addr; + flash_offset_t offset; size_t n; osalDbgCheck(instance != NULL); @@ -504,19 +504,19 @@ static flash_error_t m25q_verify_erase(void *instance, devp->state = FLASH_READ; /* Read command.*/ - addr = (flash_address_t)(sector * SECTOR_SIZE); + offset = (flash_offset_t)(sector * SECTOR_SIZE); n = SECTOR_SIZE; while (n > 0U) { uint8_t *p; #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ, - addr, M25Q_READ_DUMMY_CYCLES, + offset, M25Q_READ_DUMMY_CYCLES, sizeof cmpbuf, cmpbuf); #else /* Normal read command in SPI mode.*/ jesd216_cmd_addr_receive(devp->config->busp, M25Q_CMD_READ, - addr, sizeof cmpbuf, cmpbuf); + offset, sizeof cmpbuf, cmpbuf); #endif /* Checking for erased state of current buffer.*/ @@ -532,7 +532,7 @@ static flash_error_t m25q_verify_erase(void *instance, } } - addr += sizeof cmpbuf; + offset += sizeof cmpbuf; n -= sizeof cmpbuf; } @@ -600,13 +600,12 @@ static flash_error_t m25q_query_erase(void *instance, uint32_t *msec) { return FLASH_NO_ERROR; } -static flash_error_t m25q_read_sfdp(void *instance, uint8_t *rp, - flash_address_t addr, - size_t n) { +static flash_error_t m25q_read_sfdp(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp) { (void)instance; (void)rp; - (void)addr; + (void)offset; (void)n; return FLASH_NO_ERROR; diff --git a/os/ex/subsystems/mfs/mfs.c b/os/ex/subsystems/mfs/mfs.c index d138852e9..58ddcbe81 100644 --- a/os/ex/subsystems/mfs/mfs.c +++ b/os/ex/subsystems/mfs/mfs.c @@ -140,6 +140,36 @@ void mfs_cache_erase_id(MFSDriver *devp, uint32_t id) { #endif /* MFS_CFG_ID_CACHE_SIZE > 0 */ /** + * @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] offset flash offset + * @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_FLASH_FAILURE if the flash memory is unusable because HW + * failures. + * + * @notapi + */ +static mfs_error_t mfs_flash_write(MFSDriver *devp, + flash_offset_t offset, + size_t n, const + uint8_t *p) { + flash_error_t ferr; + + ferr = flashProgram(devp->config->flashp, offset, n, p); + if (ferr != FLASH_NO_ERROR) { + return MFS_FLASH_FAILURE; + } + + return MFS_NO_ERROR; +} + +/** * @brief Erases and verifies all sectors belonging to a bank. * * @param[in] devp pointer to the @p MFSDriver object @@ -201,19 +231,26 @@ static mfs_error_t mfs_bank_erase(MFSDriver *devp, mfs_bank_t bank) { static mfs_error_t mfs_bank_set_header(MFSDriver *devp, 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; + } + else { + sector = devp->config->bank1_start; + } + header.magic1 = MFS_BANK_MAGIC_1; header.magic1 = MFS_BANK_MAGIC_1; header.counter = cnt; header.next = sizeof (mfs_bank_header_t); header.crc = crc16(0U, (const uint8_t *)&header, sizeof (uint32_t) * 4); - (void)devp; - (void)bank; - (void)cnt; - - return MFS_NO_ERROR; + return mfs_flash_write(devp, + flashGetSectorOffset(devp->config->flashp, sector), + sizeof (mfs_bank_header_t), + (const uint8_t *)&header); } /** @@ -549,7 +586,7 @@ mfs_error_t mfsMount(MFSDriver *devp) { unsigned i; /* Attempting to mount the managed partition.*/ - for (i = 0; i < MFS_MAX_REPAIR_ATTEMPTS; i++) { + for (i = 0; i < MFS_CFG_MAX_REPAIR_ATTEMPTS; i++) { mfs_error_t err; err = mfs_try_mount(devp); diff --git a/os/ex/subsystems/mfs/mfs.h b/os/ex/subsystems/mfs/mfs.h index 28b8436a6..ec5719738 100644 --- a/os/ex/subsystems/mfs/mfs.h +++ b/os/ex/subsystems/mfs/mfs.h @@ -57,8 +57,15 @@ /** * @brief Maximum number of repair attempts on partition mount. */ -#if !defined(MFS_MAX_REPAIR_ATTEMPTS) || defined(__DOXIGEN__) -#define MFS_MAX_REPAIR_ATTEMPTS 3 +#if !defined(MFS_CFG_MAX_REPAIR_ATTEMPTS) || defined(__DOXIGEN__) +#define MFS_CFG_MAX_REPAIR_ATTEMPTS 3 +#endif + +/** + * @brief Verify written data. + */ +#if !defined(MFS_CFG_WRITE_VERIFY) || defined(__DOXIGEN__) +#define MFS_CFG_WRITE_VERIFY TRUE #endif /** @} */ @@ -70,7 +77,7 @@ #error "invalid MFS_CFG_ID_CACHE_SIZE value" #endif -#if (MFS_MAX_REPAIR_ATTEMPTS < 1) || (MFS_MAX_REPAIR_ATTEMPTS > 10) +#if (MFS_CFG_MAX_REPAIR_ATTEMPTS < 1) || (MFS_CFG_MAX_REPAIR_ATTEMPTS > 10) #error "invalid MFS_MAX_REPAIR_ATTEMPTS value" #endif @@ -145,7 +152,7 @@ typedef struct { /** * @brief First data element. */ - flash_address_t next; + flash_offset_t next; /** * @brief Header CRC. */ @@ -176,7 +183,7 @@ typedef struct { /** * @brief Address of the previous header or zero if none. */ - flash_address_t prev_header; + flash_offset_t prev_header; } mfs_data_header_t; #if (MFS_CFG_ID_CACHE_SIZE > 0) || defined(__DOXYGEN__) @@ -199,7 +206,7 @@ typedef struct mfs_cached_id { /** * @brief Data address of the cached element. */ - flash_address_t addr; + flash_offset_t offset; /** * @brief Data size of the cached element. */ @@ -272,11 +279,11 @@ typedef struct { /** * @brief Pointer to the next free position in the current bank. */ - flash_address_t next_position; + flash_offset_t next_offset; /** * @brief Pointer to the last header in the list or zero. */ - flash_address_t last_header; + flash_offset_t last_offset; /** * @brief Used space in the current bank without considering erased records. */ |