Skip to content

Commit e835afc

Browse files
committed
DNM: add zms_get_num_cycles()
...which calculates the maximum number of times a single ZMS sector has been recycled. This is to enable estimation of an RRAM lifetime based on a set of tests. Signed-off-by: Damian Krolik <[email protected]>
1 parent 9fc0338 commit e835afc

File tree

3 files changed

+59
-6
lines changed

3 files changed

+59
-6
lines changed

include/zephyr/fs/zms.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ size_t zms_active_sector_free_space(struct zms_fs *fs);
235235
*/
236236
int zms_sector_use_next(struct zms_fs *fs);
237237

238+
uint32_t zms_get_num_cycles(struct zms_fs *fs);
238239
/**
239240
* @}
240241
*/

subsys/fs/zms/zms.c

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ LOG_MODULE_REGISTER(fs_zms, CONFIG_ZMS_LOG_LEVEL);
2020

2121
static int zms_prev_ate(struct zms_fs *fs, uint64_t *addr, struct zms_ate *ate);
2222
static int zms_ate_valid(struct zms_fs *fs, const struct zms_ate *entry);
23+
static int zms_get_full_sector_cycle(struct zms_fs *fs, uint64_t addr, uint32_t *cycle_cnt);
2324
static int zms_get_sector_cycle(struct zms_fs *fs, uint64_t addr, uint8_t *cycle_cnt);
2425
static int zms_get_sector_header(struct zms_fs *fs, uint64_t addr, struct zms_ate *empty_ate,
2526
struct zms_ate *close_ate);
@@ -754,7 +755,7 @@ static int zms_add_gc_done_ate(struct zms_fs *fs)
754755
static int zms_add_empty_ate(struct zms_fs *fs, uint64_t addr)
755756
{
756757
struct zms_ate empty_ate;
757-
uint8_t cycle_cnt;
758+
uint32_t cycle_cnt;
758759
int rc = 0;
759760
uint64_t previous_ate_wra;
760761

@@ -763,11 +764,10 @@ static int zms_add_empty_ate(struct zms_fs *fs, uint64_t addr)
763764
LOG_DBG("Adding empty ate at %llx", (uint64_t)(addr + fs->sector_size - fs->ate_size));
764765
empty_ate.id = ZMS_HEAD_ID;
765766
empty_ate.len = 0xffff;
766-
empty_ate.offset = 0U;
767767
empty_ate.metadata =
768768
FIELD_PREP(ZMS_MAGIC_NUMBER_MASK, ZMS_MAGIC_NUMBER) | ZMS_DEFAULT_VERSION;
769769

770-
rc = zms_get_sector_cycle(fs, addr, &cycle_cnt);
770+
rc = zms_get_full_sector_cycle(fs, addr, &cycle_cnt);
771771
if (rc == -ENOENT) {
772772
/* sector never used */
773773
cycle_cnt = 0;
@@ -777,7 +777,8 @@ static int zms_add_empty_ate(struct zms_fs *fs, uint64_t addr)
777777
}
778778

779779
/* increase cycle counter */
780-
empty_ate.cycle_cnt = (cycle_cnt + 1) % BIT(8);
780+
empty_ate.full_cycle_cnt = cycle_cnt + 1;
781+
empty_ate.cycle_cnt = (uint8_t)empty_ate.full_cycle_cnt;
781782
zms_ate_crc8_update(&empty_ate);
782783

783784
/* Adding empty ate to this sector changes fs->ate_wra value
@@ -818,6 +819,30 @@ static int zms_get_sector_cycle(struct zms_fs *fs, uint64_t addr, uint8_t *cycle
818819
return -ENOENT;
819820
}
820821

822+
static int zms_get_full_sector_cycle(struct zms_fs *fs, uint64_t addr, uint32_t *cycle_cnt)
823+
{
824+
int rc;
825+
struct zms_ate empty_ate;
826+
uint64_t empty_addr;
827+
828+
empty_addr = zms_empty_ate_addr(fs, addr);
829+
830+
/* read the cycle counter of the current sector */
831+
rc = zms_flash_ate_rd(fs, empty_addr, &empty_ate);
832+
if (rc < 0) {
833+
/* flash error */
834+
return rc;
835+
}
836+
837+
if (zms_empty_ate_valid(fs, &empty_ate)) {
838+
*cycle_cnt = empty_ate.full_cycle_cnt;
839+
return 0;
840+
}
841+
842+
/* there is no empty ATE in this sector */
843+
return -ENOENT;
844+
}
845+
821846
static int zms_get_sector_header(struct zms_fs *fs, uint64_t addr, struct zms_ate *empty_ate,
822847
struct zms_ate *close_ate)
823848
{
@@ -1828,3 +1853,26 @@ int zms_sector_use_next(struct zms_fs *fs)
18281853
k_mutex_unlock(&fs->zms_lock);
18291854
return ret;
18301855
}
1856+
1857+
uint32_t zms_get_num_cycles(struct zms_fs *fs)
1858+
{
1859+
uint32_t max_cycle_cnt = 0;
1860+
uint32_t cycle_cnt;
1861+
int rc;
1862+
1863+
k_mutex_lock(&fs->zms_lock, K_FOREVER);
1864+
1865+
for (uint32_t i = 0; i < fs->sector_count; i++) {
1866+
rc = zms_get_full_sector_cycle(fs, (uint64_t)i << ADDR_SECT_SHIFT, &cycle_cnt);
1867+
1868+
if (rc) {
1869+
continue;
1870+
}
1871+
1872+
max_cycle_cnt = MAX(max_cycle_cnt, cycle_cnt);
1873+
}
1874+
1875+
k_mutex_unlock(&fs->zms_lock);
1876+
1877+
return max_cycle_cnt;
1878+
}

subsys/fs/zms/zms_priv.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,12 @@ struct zms_ate {
5757
/** data field used to store small sized data */
5858
uint8_t data[8];
5959
struct {
60-
/** data offset within sector */
61-
uint32_t offset;
60+
union {
61+
/** data offset within sector */
62+
uint32_t offset;
63+
/** full cycle count (for empty ATE) */
64+
uint32_t full_cycle_cnt;
65+
};
6266
union {
6367
/**
6468
* crc for data: The data CRC is checked only when the whole data

0 commit comments

Comments
 (0)