From 9f53939da7a858284eaae8df986f55198640aed4 Mon Sep 17 00:00:00 2001 From: armink Date: Thu, 7 Feb 2019 14:36:35 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=AE=8C=E6=88=90=E3=80=91GC=20?= =?UTF-8?q?=E7=9A=84=E5=BC=82=E5=B8=B8=E6=8E=89=E7=94=B5=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: armink --- easyflash/src/ef_env_ng.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/easyflash/src/ef_env_ng.c b/easyflash/src/ef_env_ng.c index 9358b4c..a3fe227 100644 --- a/easyflash/src/ef_env_ng.c +++ b/easyflash/src/ef_env_ng.c @@ -31,8 +31,7 @@ #if defined(EF_USING_ENV) /* the flash write granularity, unit: bit */ -//#define EF_WRITE_GRAN 1 -#define EF_WRITE_GRAN 8 +#define EF_WRITE_GRAN 1 @@ -190,8 +189,8 @@ static size_t default_env_set_size = 0; static bool init_ok = false; /* the using status sector table */ static struct sector_meta_data using_sec_table[USING_SECTOR_TABLE_LEN]; -/* the GC is triggered */ -static bool gc_is_triggered = false; +/* ready for GC check */ +static bool gc_check = false; static size_t set_status(uint8_t status_table[], size_t status_num, size_t status_index) { @@ -706,7 +705,7 @@ static bool do_gc(sector_meta_data_t sector, void *arg1, void *arg2) #endif //TODO 重复写入安全性验证 /* change the sector status to GC */ - write_status(sector->addr, status_table, SECTOR_DIRTY_STATUS_NUM, SECTOR_DIRTY_GC); + write_status(sector->addr + SECTOR_DIRTY_OFFSET, status_table, SECTOR_DIRTY_STATUS_NUM, SECTOR_DIRTY_GC); /* search all ENV */ env.addr.start = GET_ADDR_FAILED; while ((env.addr.start = get_next_env_addr(sector, &env)) != GET_ADDR_FAILED) { @@ -714,7 +713,6 @@ static bool do_gc(sector_meta_data_t sector, void *arg1, void *arg2) if (env.crc_is_ok && (env.status == ENV_WRITE || env.status == ENV_PRE_DELETE)) { uint32_t env_addr; struct sector_meta_data new_sector; - //TODO 异常掉电测试 /* change the current ENV status to prepare delete */ write_status(env.addr.start, status_table, ENV_STATUS_NUM, ENV_PRE_DELETE); /* alloc new space for move the old ENV */ @@ -743,8 +741,8 @@ static void gc_collect(void) sector_iterator(§or, SECTOR_STORE_EMPTY, &empty_sec, NULL, gc_check_cb, false); /* do GC collect */ + EF_DEBUG("The remain empty sector is %d, GC threshold is %d.\n", empty_sec, EF_GC_EMPTY_SEC_THRESHOLD); if (empty_sec <= EF_GC_EMPTY_SEC_THRESHOLD) { - EF_DEBUG("The remain empty sector is %d, GC threshold is %d.\n", empty_sec, EF_GC_EMPTY_SEC_THRESHOLD); sector_iterator(§or, SECTOR_STORE_FULL, NULL, NULL, do_gc, false); } } @@ -792,7 +790,6 @@ static EfErrCode create_env_blob(const char *key, const void *value, size_t len) if ((env_addr = alloc_env(§or, env_hdr.len)) != GET_ADDR_FAILED) { size_t align_remain; - uint32_t sec_addr = EF_ALIGN_DOWN(env_addr, SECTOR_SIZE); /* update the sector status */ if (result == EF_NO_ERR) { result = update_sec_status(§or, env_hdr.len, &is_full); @@ -829,11 +826,8 @@ static EfErrCode create_env_blob(const char *key, const void *value, size_t len) } /* trigger GC collect when current sector is full */ if (result == EF_NO_ERR && is_full) { - uint8_t status_table[DIRTY_STATUS_TABLE_SIZE]; - /* change the sector status to GC */ - write_status(sector.addr, status_table, SECTOR_DIRTY_STATUS_NUM, SECTOR_DIRTY_GC); - EF_DEBUG("Trigger a GC collect.\n"); - gc_is_triggered = true; + EF_DEBUG("Trigger a GC check.\n"); + gc_check = true; } //TODO 更新 using_sec_table } @@ -946,9 +940,9 @@ EfErrCode ef_set_env(const char *key, const char *value) result = del_env(key, &env, true); } /* process the GC after set ENV */ - if (result == EF_NO_ERR && gc_is_triggered) { + if (result == EF_NO_ERR && gc_check) { gc_collect(); - gc_is_triggered = false; + gc_check = false; } } @@ -1113,7 +1107,7 @@ static bool check_sec_hdr_cb(sector_meta_data_t sector, void *arg1, void *arg2) ef_env_set_default(); ef_port_env_lock(); return true; - } else if(sector->status.dirty == SECTOR_DIRTY_GC) { + } else if (sector->status.dirty == SECTOR_DIRTY_GC) { /* resume the GC operate */ gc_collect(); } @@ -1168,7 +1162,6 @@ EfErrCode ef_load_env(void) ef_port_env_lock(); //TODO 装载环境变量元数据,using_sec_table - //TODO 检查是否存在未完成的垃圾回收工作,存在则垃圾回收 /* check all sector header */ sector_iterator(§or, SECTOR_DIRTY_UNUSED, NULL, NULL, check_sec_hdr_cb, false); /* check all ENV for recovery */ @@ -1198,8 +1191,11 @@ EfErrCode ef_env_init(ef_env const *default_env, size_t default_env_size) { EF_ASSERT(ENV_AREA_SIZE % EF_ERASE_MIN_SIZE == 0); /* must be aligned with write granularity */ EF_ASSERT((EF_STR_ENV_VALUE_MAX_SIZE * 8) % EF_WRITE_GRAN == 0); - - //TODO GC 扇区数量的检查 + /* sector number must lager then or equal to 2 */ + EF_ASSERT(SECTOR_NUM >= 2); + /* Check the GC threshold setting. There is at least one empty sector. */ + EF_ASSERT(EF_GC_EMPTY_SEC_THRESHOLD); + EF_ASSERT(SECTOR_NUM > EF_GC_EMPTY_SEC_THRESHOLD); env_start_addr = EF_START_ADDR; default_env_set = default_env;