aboutsummaryrefslogtreecommitdiffstats
path: root/os/ex
diff options
context:
space:
mode:
Diffstat (limited to 'os/ex')
-rw-r--r--os/ex/Micron/m25q.c63
-rw-r--r--os/ex/subsystems/mfs/mfs.c49
-rw-r--r--os/ex/subsystems/mfs/mfs.h23
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.
*/