From 9b6e79c5c1b2c853051c1d190ce95adf1e9063e3 Mon Sep 17 00:00:00 2001 From: armink Date: Mon, 14 Nov 2016 19:32:05 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E3=80=90=E6=9B=B4=E6=96=B0=E3=80=91R?= =?UTF-8?q?T-Thread=20Demo=20=E4=BD=BF=E7=94=A8=E7=9A=84=20EasyFlash=20?= =?UTF-8?q?=E5=BA=93=E8=87=B3=E6=9C=80=E6=96=B0=E7=89=88=E6=9C=AC=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: armink --- .../components/easyflash/inc/easyflash.h | 7 +- .../components/easyflash/inc/ef_cfg.h | 11 +- .../components/easyflash/src/easyflash.c | 10 +- .../components/easyflash/src/ef_env.c | 89 ++++++--- .../components/easyflash/src/ef_env_wl.c | 179 +++++++++++------- .../components/easyflash/src/ef_iap.c | 4 +- .../components/easyflash/src/ef_utils.c | 4 +- 7 files changed, 188 insertions(+), 116 deletions(-) diff --git a/demo/os/rt-thread/stm32f10x/components/easyflash/inc/easyflash.h b/demo/os/rt-thread/stm32f10x/components/easyflash/inc/easyflash.h index dceefe8..9a162d6 100644 --- a/demo/os/rt-thread/stm32f10x/components/easyflash/inc/easyflash.h +++ b/demo/os/rt-thread/stm32f10x/components/easyflash/inc/easyflash.h @@ -1,7 +1,7 @@ /* * This file is part of the EasyFlash Library. * - * Copyright (c) 2014, Armink, + * Copyright (c) 2014-2016, Armink, * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -67,7 +67,7 @@ if (!(EXPR)) \ while (1); \ } /* EasyFlash software version number */ -#define EF_SW_VERSION "2.08.26" +#define EF_SW_VERSION "2.10.24" typedef struct _ef_env{ char *key; @@ -82,6 +82,7 @@ typedef enum { EF_ENV_NAME_ERR, EF_ENV_NAME_EXIST, EF_ENV_FULL, + EF_ENV_INIT_FAILED, } EfErrCode; /* the flash sector current status */ @@ -96,7 +97,7 @@ EfErrCode easyflash_init(void); #ifdef EF_USING_ENV /* ef_env.c ef_env_wl.c */ -void ef_load_env(void); +EfErrCode ef_load_env(void); void ef_print_env(void); char *ef_get_env(const char *key); EfErrCode ef_set_env(const char *key, const char *value); diff --git a/demo/os/rt-thread/stm32f10x/components/easyflash/inc/ef_cfg.h b/demo/os/rt-thread/stm32f10x/components/easyflash/inc/ef_cfg.h index d3a733f..a01be1d 100644 --- a/demo/os/rt-thread/stm32f10x/components/easyflash/inc/ef_cfg.h +++ b/demo/os/rt-thread/stm32f10x/components/easyflash/inc/ef_cfg.h @@ -69,20 +69,19 @@ * |----------------------------| * * @note all area size must be aligned with EF_ERASE_MIN_SIZE - * @note EasyFlash will use ram to buffered the ENV.At some time some flash's EF_ERASE_MIN_SIZE is so big, + * @note EasyFlash will use ram to buffered the ENV. At some time flash's EF_ERASE_MIN_SIZE is so big, * and you want use ENV size is less than it. So you must defined ENV_USER_SETTING_SIZE for ENV. * @note ENV area size has some limitations in different modes. * 1.Normal mode: no more limitations * 2.Wear leveling mode: system section will used an flash section and the data section will used at least 2 flash sections * 3.Power fail safeguard mode: ENV area will has an backup. It is twice as normal mode. - * 4.wear leveling and power fail safeguard mode: The system section will used an flash section. - * The data section is twice as wear leveling mode data section size. + * 4.wear leveling and power fail safeguard mode: The required capacity will be 2 times the total capacity in wear leveling mode. * For example: * The EF_ERASE_MIN_SIZE is 128K and the ENV_USER_SETTING_SIZE: 2K. The ENV_AREA_SIZE in different mode you can define * 1.Normal mode: 1*EF_ERASE_MIN_SIZE - * 2.Wear leveling mode: 2*EF_ERASE_MIN_SIZE (It has 2 flash section to store ENV. So ENV can erase at least 200,000 times) + * 2.Wear leveling mode: 3*EF_ERASE_MIN_SIZE (It has 2 data section to store ENV. So ENV can erase at least 200,000 times) * 3.Power fail safeguard mode: 2*EF_ERASE_MIN_SIZE - * 4.Wear leveling and power fail safeguard mode: 5*EF_ERASE_MIN_SIZE + * 4.Wear leveling and power fail safeguard mode: 6*EF_ERASE_MIN_SIZE * @note the log area size must be more than twice of EF_ERASE_MIN_SIZE */ /* backup area start address */ @@ -103,7 +102,7 @@ #define ENV_AREA_SIZE (2 * EF_ERASE_MIN_SIZE) /* 4K */ #else /* ENV area total bytes size in wear leveling and power fail safeguard mode. */ - #define ENV_AREA_SIZE (5 * EF_ERASE_MIN_SIZE) /* 10K */ + #define ENV_AREA_SIZE (8 * EF_ERASE_MIN_SIZE) /* 16K */ #endif #endif /* saved log area size */ diff --git a/demo/os/rt-thread/stm32f10x/components/easyflash/src/easyflash.c b/demo/os/rt-thread/stm32f10x/components/easyflash/src/easyflash.c index 62ba994..0f6f1aa 100644 --- a/demo/os/rt-thread/stm32f10x/components/easyflash/src/easyflash.c +++ b/demo/os/rt-thread/stm32f10x/components/easyflash/src/easyflash.c @@ -1,7 +1,7 @@ /* * This file is part of the EasyFlash Library. * - * Copyright (c) 2014, Armink, + * Copyright (c) 2014-2016, Armink, * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -46,14 +46,13 @@ * 1.Normal mode: no more limitations * 2.Wear leveling mode: system section will used an flash section and the data section will used at least 2 flash sections * 3.Power fail safeguard mode: ENV area will has an backup. It is twice as normal mode. - * 4.wear leveling and power fail safeguard mode: The system section will used an flash section. - * The data section is twice as wear leveling mode data section size. + * 4.wear leveling and power fail safeguard mode: The required capacity will be 2 times the total capacity in wear leveling mode. * For example: * The EF_ERASE_MIN_SIZE is 128K and the ENV_USER_SETTING_SIZE: 2K. The ENV_AREA_SIZE in different mode you can define * 1.Normal mode: 1*EF_ERASE_MIN_SIZE - * 2.Wear leveling mode: 3*EF_ERASE_MIN_SIZE (It has 2 flash section to store ENV. So ENV can erase at least 200,000 times) + * 2.Wear leveling mode: 3*EF_ERASE_MIN_SIZE (It has 2 data section to store ENV. So ENV can erase at least 200,000 times) * 3.Power fail safeguard mode: 2*EF_ERASE_MIN_SIZE - * 4.Wear leveling and power fail safeguard mode: 5*EF_ERASE_MIN_SIZE + * 4.Wear leveling and power fail safeguard mode: 6*EF_ERASE_MIN_SIZE * @note the log area size must be more than twice of EF_ERASE_MIN_SIZE */ #include @@ -98,6 +97,7 @@ EfErrCode easyflash_init(void) { } else { EF_DEBUG("EasyFlash V%s is initialize fail.\n", EF_SW_VERSION); } + EF_DEBUG("You can get the latest version on https://github.com/armink/EasyFlash .\n"); return result; } diff --git a/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_env.c b/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_env.c index 568ad3d..b1ce732 100644 --- a/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_env.c +++ b/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_env.c @@ -1,7 +1,7 @@ /* * This file is part of the EasyFlash Library. * - * Copyright (c) 2014, Armink, + * Copyright (c) 2014-2016, Armink, * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -65,21 +65,23 @@ enum { }; /* default ENV set, must be initialized by user */ -static ef_env const *default_env_set = NULL; +static ef_env const *default_env_set; /* default ENV set size, must be initialized by user */ -static size_t default_env_set_size = NULL; +static size_t default_env_set_size = 0; /* ENV ram cache */ static uint32_t env_cache[ENV_USER_SETTING_SIZE / 4] = { 0 }; /* ENV start address in flash */ -static uint32_t env_start_addr = NULL; +static uint32_t env_start_addr = 0; /* ENV ram cache has changed when ENV created, deleted and changed value. */ static bool env_cache_changed = false; +/* initialize OK flag */ +static bool init_ok = false; #ifdef EF_ENV_USING_PFS_MODE /* current load ENV area address */ -static uint32_t cur_load_area_addr = NULL; +static uint32_t cur_load_area_addr = 0; /* next save ENV area address */ -static uint32_t next_save_area_addr = NULL; +static uint32_t next_save_area_addr = 0; #endif static uint32_t get_env_system_addr(void); @@ -90,6 +92,7 @@ static EfErrCode write_env(const char *key, const char *value); static char *find_env(const char *key); static EfErrCode del_env(const char *key); static size_t get_env_data_size(void); +static size_t get_env_user_used_size(void); static EfErrCode create_env(const char *key, const char *value); static uint32_t calc_env_crc(void); static bool env_crc_is_ok(void); @@ -140,7 +143,11 @@ EfErrCode ef_env_init(ef_env const *default_env, size_t default_env_size) { EF_DEBUG("ENV start address is 0x%08X, size is %d bytes.\n", EF_START_ADDR, ENV_AREA_SIZE); - ef_load_env(); + result = ef_load_env(); + + if (result == EF_NO_ERR) { + init_ok = true; + } return result; } @@ -176,7 +183,7 @@ EfErrCode ef_env_set_default(void){ /* unlock the ENV cache */ ef_port_env_unlock(); - ef_save_env(); + result = ef_save_env(); return result; } @@ -233,6 +240,15 @@ static size_t get_env_data_size(void) { return get_env_end_addr() - get_env_data_addr(); } +/** + * Get current user used ENV size. + * + * @return bytes + */ +static size_t get_env_user_used_size(void) { + return get_env_end_addr() - get_env_system_addr(); +} + /** * Get current ENV already write bytes. * @@ -240,10 +256,9 @@ static size_t get_env_data_size(void) { */ size_t ef_get_env_write_bytes(void) { #ifndef EF_ENV_USING_PFS_MODE - return get_env_end_addr() - env_start_addr; + return get_env_user_used_size(); #else - /* It has two ENV areas(Area0, Area1) on used power fail safeguard mode */ - return 2 * (get_env_end_addr() - get_env_system_addr()); + return get_env_user_used_size() * 2; #endif } @@ -266,12 +281,12 @@ static EfErrCode write_env(const char *key, const char *value) { env_str_len = (env_str_len / 4 + 1) * 4; } /* check capacity of ENV */ - if (env_str_len + get_env_data_size() >= ENV_USER_SETTING_SIZE) { + if (env_str_len + get_env_user_used_size() >= ENV_USER_SETTING_SIZE) { return EF_ENV_FULL; } /* calculate current ENV ram cache end address */ - env_cache_bak += get_env_end_addr() - get_env_system_addr(); + env_cache_bak += get_env_user_used_size(); /* copy key name */ memcpy(env_cache_bak, key, ker_len); @@ -312,7 +327,7 @@ static char *find_env(const char *key) { /* from data section start to data section end */ env_start = (char *) ((char *) env_cache + ENV_PARAM_BYTE_SIZE); - env_end = (char *) ((char *) env_cache + (get_env_end_addr() - get_env_system_addr())); + env_end = (char *) ((char *) env_cache + get_env_user_used_size()); /* ENV is null */ if (env_start == env_end) { @@ -439,6 +454,11 @@ EfErrCode ef_set_env(const char *key, const char *value) { EfErrCode result = EF_NO_ERR; char *old_env, *old_value; + if(!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return EF_ENV_INIT_FAILED; + } + /* lock the ENV cache */ ef_port_env_lock(); @@ -479,6 +499,11 @@ EfErrCode ef_set_env(const char *key, const char *value) { char *ef_get_env(const char *key) { char *env = NULL, *value = NULL; + if(!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return NULL; + } + /* find ENV */ env = find_env(key); @@ -503,6 +528,11 @@ void ef_print_env(void) { uint8_t j; char c; + if(!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return; + } + for (; env_cache_data_addr < env_cache_end_addr; env_cache_data_addr += 1) { for (j = 0; j < 4; j++) { c = (*env_cache_data_addr) >> (8 * j); @@ -515,19 +545,23 @@ void ef_print_env(void) { } #ifndef EF_ENV_USING_PFS_MODE - ef_print("\nENV size: %ld/%ld bytes.\n", ef_get_env_write_bytes(), ENV_AREA_SIZE); + ef_print("\nENV size: %ld/%ld bytes.\n", get_env_user_used_size(), ENV_USER_SETTING_SIZE); #else - ef_print("\nENV size: %ld/%ld bytes, saved count: %ld, mode: power fail safeguard.\n", - ef_get_env_write_bytes(), ENV_AREA_SIZE, env_cache[ENV_PARAM_INDEX_SAVED_COUNT]); + ef_print("\nENV size: %ld/%ld bytes, write bytes %ld/%ld, saved count: %ld, mode: power fail safeguard.\n", + get_env_user_used_size(), ENV_USER_SETTING_SIZE, ef_get_env_write_bytes(), + ENV_AREA_SIZE, env_cache[ENV_PARAM_INDEX_SAVED_COUNT]); #endif } /** * Load flash ENV to ram. + * + * @return result */ #ifndef EF_ENV_USING_PFS_MODE -void ef_load_env(void) { +EfErrCode ef_load_env(void) { + EfErrCode result = EF_NO_ERR; uint32_t *env_cache_bak, env_end_addr; /* read ENV end address from flash */ @@ -535,7 +569,7 @@ void ef_load_env(void) { /* if ENV is not initialize or flash has dirty data, set default for it */ if ((env_end_addr == 0xFFFFFFFF) || (env_end_addr < env_start_addr) || (env_end_addr > env_start_addr + ENV_USER_SETTING_SIZE)) { - ef_env_set_default(); + result = ef_env_set_default(); } else { /* set ENV end address */ set_env_end_addr(env_end_addr); @@ -549,12 +583,14 @@ void ef_load_env(void) { /* if ENV CRC32 check is fault, set default for it */ if (!env_crc_is_ok()) { EF_INFO("Warning: ENV CRC check failed. Set it to default.\n"); - ef_env_set_default(); + result = ef_env_set_default(); } } + return result; } #else -void ef_load_env(void) { +EfErrCode ef_load_env(void) { + EfErrCode result = EF_NO_ERR; uint32_t area0_start_address = env_start_addr, area1_start_address = env_start_addr + ENV_AREA_SIZE / 2; uint32_t area0_end_addr, area1_end_addr, area0_crc, area1_crc, area0_saved_count, area1_saved_count; @@ -624,8 +660,9 @@ void ef_load_env(void) { /* next save ENV area address is area0 start address */ next_save_area_addr = area0_start_address; /* set the ENV to default */ - ef_env_set_default(); + result = ef_env_set_default(); } + return result; } #endif @@ -643,12 +680,12 @@ EfErrCode ef_save_env(void) { #ifndef EF_ENV_USING_PFS_MODE write_addr = get_env_system_addr(); - write_size = get_env_end_addr() - get_env_system_addr(); + write_size = get_env_user_used_size(); /* calculate and cache CRC32 code */ env_cache[ENV_PARAM_INDEX_DATA_CRC] = calc_env_crc(); #else write_addr = next_save_area_addr; - write_size = get_env_end_addr() - get_env_system_addr(); + write_size = get_env_user_used_size(); /* replace next_save_area_addr with cur_load_area_addr */ next_save_area_addr = cur_load_area_addr; cur_load_area_addr = write_addr; @@ -668,7 +705,7 @@ EfErrCode ef_save_env(void) { break; } case EF_ERASE_ERR: { - EF_INFO("Warning: Erased ENV fault!\n"); + EF_INFO("Error: Erased ENV fault! Start address is 0x%08X, size is %ld.\n", write_addr, write_size); /* will return when erase fault */ return result; } @@ -682,7 +719,7 @@ EfErrCode ef_save_env(void) { break; } case EF_WRITE_ERR: { - EF_INFO("Warning: Saved ENV fault!\n"); + EF_INFO("Error: Saved ENV fault! Start address is 0x%08X, size is %ld.\n", write_addr, write_size); break; } } diff --git a/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_env_wl.c b/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_env_wl.c index c4821e4..d02029c 100644 --- a/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_env_wl.c +++ b/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_env_wl.c @@ -1,7 +1,7 @@ /* * This file is part of the EasyFlash Library. * - * Copyright (c) 2015, Armink, + * Copyright (c) 2015-2016, Armink, * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -72,23 +72,25 @@ enum { }; /* default ENV set, must be initialized by user */ -static ef_env const *default_env_set = NULL; +static ef_env const *default_env_set; /* default ENV set size, must be initialized by user */ -static size_t default_env_set_size = NULL; +static size_t default_env_set_size = 0; /* flash ENV data section size */ -static size_t env_data_section_size = NULL; +static size_t env_data_section_size = 0; /* ENV ram cache */ static uint32_t env_cache[ENV_USER_SETTING_SIZE / 4] = { 0 }; /* ENV start address in flash */ -static uint32_t env_start_addr = NULL; +static uint32_t env_start_addr = 0; /* current using data section address */ -static uint32_t cur_using_data_addr = NULL; +static uint32_t cur_using_data_addr = 0; /* ENV ram cache has changed when ENV created, deleted and changed value. */ static bool env_cache_changed = false; +/* initialize OK flag */ +static bool init_ok = false; #ifdef EF_ENV_USING_PFS_MODE /* next save ENV area address */ -static uint32_t next_save_area_addr = NULL; +static uint32_t next_save_area_addr = 0; #endif static uint32_t get_env_start_addr(void); @@ -125,18 +127,18 @@ EfErrCode ef_env_init(ef_env const *default_env, size_t default_env_size) { EF_ASSERT(ENV_AREA_SIZE % 4 == 0); EF_ASSERT(default_env); EF_ASSERT(default_env_size < ENV_USER_SETTING_SIZE); - /* system section size is erase_min_size, so last part is data section */ - env_data_section_size = ENV_AREA_SIZE - EF_ERASE_MIN_SIZE; - /* the ENV data section size should be an integral multiple of erase minimum size. */ - EF_ASSERT(env_data_section_size % EF_ERASE_MIN_SIZE == 0); #ifndef EF_ENV_USING_PFS_MODE - EF_ASSERT(env_data_section_size >= ENV_USER_SETTING_SIZE); + /* system section size is erase_min_size, so last part is data section */ + env_data_section_size = ENV_AREA_SIZE - EF_ERASE_MIN_SIZE; #else - /* it has double area when used power fail safeguard mode */ - EF_ASSERT(env_data_section_size >= 2*ENV_USER_SETTING_SIZE); - EF_ASSERT((env_data_section_size / EF_ERASE_MIN_SIZE) % 2 == 0); + /* system section size is erase_min_size, so last part is data section */ + env_data_section_size = ENV_AREA_SIZE / 2 - EF_ERASE_MIN_SIZE; + EF_ASSERT((ENV_AREA_SIZE / EF_ERASE_MIN_SIZE) % 2 == 0); #endif + EF_ASSERT(env_data_section_size >= ENV_USER_SETTING_SIZE); + /* the ENV data section size should be an integral multiple of erase minimum size. */ + EF_ASSERT(env_data_section_size % EF_ERASE_MIN_SIZE == 0); env_start_addr = EF_START_ADDR; @@ -145,7 +147,11 @@ EfErrCode ef_env_init(ef_env const *default_env, size_t default_env_size) { EF_DEBUG("ENV start address is 0x%08X, size is %d bytes.\n", EF_START_ADDR, ENV_AREA_SIZE); - ef_load_env(); + result = ef_load_env(); + + if (result == EF_NO_ERR) { + init_ok = true; + } return result; } @@ -181,7 +187,7 @@ EfErrCode ef_env_set_default(void){ /* unlock the ENV cache */ ef_port_env_unlock(); - ef_save_env(); + result = ef_save_env(); return result; } @@ -274,16 +280,7 @@ size_t ef_get_env_write_bytes(void) { #ifndef EF_ENV_USING_PFS_MODE return get_env_detail_end_addr() - get_env_start_addr(); #else - if (get_cur_using_data_addr() - < get_env_start_addr() + EF_ERASE_MIN_SIZE + env_data_section_size / 2) { - /* current using is ENV area0 */ - return EF_ERASE_MIN_SIZE + 2 * (get_env_detail_end_addr() - (get_env_start_addr() - +EF_ERASE_MIN_SIZE)); - } else { - /* current using is ENV area1 */ - return EF_ERASE_MIN_SIZE + 2 * (get_env_detail_end_addr() - (get_env_start_addr() - + EF_ERASE_MIN_SIZE + env_data_section_size / 2)); - } + return EF_ERASE_MIN_SIZE + get_env_detail_end_addr() - get_cur_using_data_addr(); #endif } @@ -306,7 +303,7 @@ static EfErrCode write_env(const char *key, const char *value) { env_str_len = (env_str_len / 4 + 1) * 4; } /* check capacity of ENV */ - if (env_str_len + get_env_detail_size() >= ENV_USER_SETTING_SIZE) { + if (env_str_len + get_env_user_used_size() >= ENV_USER_SETTING_SIZE) { return EF_ENV_FULL; } /* calculate current ENV ram cache end address */ @@ -480,6 +477,11 @@ EfErrCode ef_set_env(const char *key, const char *value) { EfErrCode result = EF_NO_ERR; char *old_env, *old_value; + if(!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return EF_ENV_INIT_FAILED; + } + /* lock the ENV cache */ ef_port_env_lock(); @@ -520,6 +522,11 @@ EfErrCode ef_set_env(const char *key, const char *value) { char *ef_get_env(const char *key) { char *env = NULL, *value = NULL; + if(!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return NULL; + } + /* find ENV */ env = find_env(key); @@ -543,6 +550,11 @@ void ef_print_env(void) { uint8_t j; char c; + if(!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return; + } + for (; env_cache_detail_addr < env_cache_end_addr; env_cache_detail_addr += 1) { for (j = 0; j < 4; j++) { c = (*env_cache_detail_addr) >> (8 * j); @@ -561,15 +573,18 @@ void ef_print_env(void) { #else ef_print("\nENV size: %ld/%ld bytes, write bytes %ld/%ld, saved count: %ld, mode: wear leveling and power fail safeguard.\n", get_env_user_used_size(), ENV_USER_SETTING_SIZE, ef_get_env_write_bytes(), - ENV_AREA_SIZE, env_cache[ENV_PARAM_PART_INDEX_SAVED_COUNT]); + ENV_AREA_SIZE/2, env_cache[ENV_PARAM_PART_INDEX_SAVED_COUNT]); #endif } /** * Load flash ENV to ram. + * + * @return result */ #ifndef EF_ENV_USING_PFS_MODE -void ef_load_env(void) { +EfErrCode ef_load_env(void) { + EfErrCode result = EF_NO_ERR; uint32_t *env_cache_bak, env_end_addr, using_data_addr; /* read current using data section address */ @@ -581,9 +596,10 @@ void ef_load_env(void) { /* initialize current using data section address */ set_cur_using_data_addr(get_env_start_addr() + EF_ERASE_MIN_SIZE); /* save current using data section address to flash*/ - save_cur_using_data_addr(get_cur_using_data_addr()); - /* set default ENV */ - ef_env_set_default(); + if ((result = save_cur_using_data_addr(get_cur_using_data_addr())) == EF_NO_ERR) { + /* set default ENV */ + result = ef_env_set_default(); + } } else { /* set current using data section address */ set_cur_using_data_addr(using_data_addr); @@ -591,7 +607,13 @@ void ef_load_env(void) { ef_port_read(get_cur_using_data_addr() + ENV_PARAM_PART_INDEX_END_ADDR * 4, &env_end_addr, 4); /* if ENV end address has error, set default for ENV */ if (env_end_addr > get_env_start_addr() + ENV_AREA_SIZE) { - ef_env_set_default(); + /* initialize current using data section address */ + set_cur_using_data_addr(get_env_start_addr() + EF_ERASE_MIN_SIZE); + /* save current using data section address to flash*/ + if ((result = save_cur_using_data_addr(get_cur_using_data_addr())) == EF_NO_ERR) { + EF_INFO("Warning: ENV end address has error. Set it to default.\n"); + result = ef_env_set_default(); + } } else { /* set ENV detail part end address */ set_env_detail_end_addr(env_end_addr); @@ -605,34 +627,36 @@ void ef_load_env(void) { /* if ENV CRC32 check is fault, set default for it */ if (!env_crc_is_ok()) { EF_INFO("Warning: ENV CRC check failed. Set it to default.\n"); - ef_env_set_default(); + result = ef_env_set_default(); } } } + return result; } #else -void ef_load_env(void) { +EfErrCode ef_load_env(void) { + EfErrCode result = EF_NO_ERR; /* ENV area0 current using address default value */ uint32_t area0_default_cur_using_addr = get_env_start_addr() + EF_ERASE_MIN_SIZE; /* ENV area1 current using address default value */ - uint32_t area1_default_cur_using_addr = area0_default_cur_using_addr + env_data_section_size / 2; + uint32_t area1_default_cur_using_addr = area0_default_cur_using_addr + ENV_AREA_SIZE / 2; uint32_t area0_cur_using_addr, area1_cur_using_addr, area0_end_addr, area1_end_addr; uint32_t area0_crc, area1_crc, area0_saved_count, area1_saved_count; bool area0_is_valid = true, area1_is_valid = true; - /* read ENV area0 and area1 current using address */ + /* read ENV area0 and area1 current using data section address */ ef_port_read(get_env_start_addr(), &area0_cur_using_addr, 4); - ef_port_read(get_env_start_addr() + 4, &area1_cur_using_addr, 4); + ef_port_read(get_env_start_addr() + ENV_AREA_SIZE / 2, &area1_cur_using_addr, 4); /* if ENV is not initialize or flash has dirty data, set it isn't valid */ if ((area0_cur_using_addr == 0xFFFFFFFF) - || (area0_cur_using_addr > get_env_start_addr() + ENV_AREA_SIZE) + || (area0_cur_using_addr > get_env_start_addr() + ENV_AREA_SIZE / 2) || (area0_cur_using_addr < get_env_start_addr() + EF_ERASE_MIN_SIZE)) { area0_is_valid = false; } if ((area1_cur_using_addr == 0xFFFFFFFF) || (area1_cur_using_addr > get_env_start_addr() + ENV_AREA_SIZE) - || (area1_cur_using_addr < get_env_start_addr() + EF_ERASE_MIN_SIZE)) { + || (area1_cur_using_addr < get_env_start_addr() + ENV_AREA_SIZE / 2 + EF_ERASE_MIN_SIZE)) { area1_is_valid = false; } /* check area0 end address when it is valid */ @@ -694,24 +718,27 @@ void ef_load_env(void) { if (area0_is_valid) { /* current using data section address is area0 current using data section address */ set_cur_using_data_addr(area0_cur_using_addr); - /* next save ENV area address is area1 current using address default value */ - next_save_area_addr = area1_default_cur_using_addr; + /* next save ENV area address is area1 current using address value */ + next_save_area_addr = area1_cur_using_addr; /* read all ENV from area0 */ ef_port_read(area0_cur_using_addr, env_cache, area0_end_addr - area0_cur_using_addr); } else if (area1_is_valid) { - /* next save ENV area address is area0 current using address default value */ - next_save_area_addr = area0_default_cur_using_addr; + /* already read data section and set_cur_using_data_addr above current code, + * so just set next save ENV area address is area0 current using address value */ + next_save_area_addr = area0_cur_using_addr; } else { /* current using data section address is area1 current using address default value */ set_cur_using_data_addr(area1_default_cur_using_addr); /* next save ENV area address default is area0 current using address default value */ next_save_area_addr = area0_default_cur_using_addr; /* save current using data section address to flash*/ - save_cur_using_data_addr(area0_default_cur_using_addr); - save_cur_using_data_addr(area1_default_cur_using_addr); - /* set the ENV to default */ - ef_env_set_default(); + if (((result = save_cur_using_data_addr(area0_default_cur_using_addr)) == EF_NO_ERR) + && ((result = save_cur_using_data_addr(area1_default_cur_using_addr)) == EF_NO_ERR)) { + /* set the ENV to default */ + result = ef_env_set_default(); + } } + return result; } #endif @@ -722,6 +749,7 @@ EfErrCode ef_save_env(void) { EfErrCode result = EF_NO_ERR; uint32_t cur_using_addr_bak, move_offset_addr; size_t env_used_size = get_env_user_used_size(); + uint32_t data_sec_end_addr; /* ENV ram cache has not changed don't need to save */ if (!env_cache_changed) { @@ -729,6 +757,7 @@ EfErrCode ef_save_env(void) { } #ifndef EF_ENV_USING_PFS_MODE + data_sec_end_addr = get_env_start_addr() + ENV_AREA_SIZE - 4; cur_using_addr_bak = get_cur_using_data_addr(); #else cur_using_addr_bak = next_save_area_addr; @@ -737,12 +766,18 @@ EfErrCode ef_save_env(void) { set_cur_using_data_addr(cur_using_addr_bak); /* change the ENV detail end address to next save area address */ set_env_detail_end_addr(get_cur_using_data_addr() + env_used_size); + /* area0 or area1 */ + if(get_cur_using_data_addr() < get_env_start_addr() + ENV_AREA_SIZE / 2) { + data_sec_end_addr = get_env_start_addr() + ENV_AREA_SIZE / 2 - 4; + } else { + data_sec_end_addr = get_env_start_addr() + ENV_AREA_SIZE - 4; + } /* ENV area saved count +1 */ env_cache[ENV_PARAM_PART_INDEX_SAVED_COUNT]++; #endif /* wear leveling process, automatic move ENV to next available position */ - while (get_cur_using_data_addr() + env_used_size < get_env_start_addr() + ENV_AREA_SIZE) { + while (get_cur_using_data_addr() + env_used_size < data_sec_end_addr) { /* calculate and cache CRC32 code */ env_cache[ENV_PARAM_PART_INDEX_DATA_CRC] = calc_env_crc(); /* erase ENV */ @@ -753,7 +788,8 @@ EfErrCode ef_save_env(void) { break; } case EF_ERASE_ERR: { - EF_INFO("Warning: Erased ENV fault!\n"); + EF_INFO("Warning: Erased ENV fault! Start address is 0x%08X, size is %ld.\n", + get_cur_using_data_addr(), env_used_size); EF_INFO("Moving ENV to next available position.\n"); /* Calculate move offset address. * Current strategy is optimistic. It will offset the flash erasure minimum size. @@ -774,7 +810,8 @@ EfErrCode ef_save_env(void) { break; } case EF_WRITE_ERR: { - EF_INFO("Warning: Saved ENV fault!\n"); + EF_INFO("Warning: Saved ENV fault! Start address is 0x%08X, size is %ld.\n", + get_cur_using_data_addr(), env_used_size); EF_INFO("Moving ENV to next available position.\n"); /* Calculate move offset address. * Current strategy is optimistic. It will offset the flash erasure minimum size. @@ -793,16 +830,14 @@ EfErrCode ef_save_env(void) { } } - if (get_cur_using_data_addr() + env_used_size < get_env_start_addr() + ENV_AREA_SIZE) { + if (get_cur_using_data_addr() + env_used_size < data_sec_end_addr) { /* current using data section address has changed, save it */ if (get_cur_using_data_addr() != cur_using_addr_bak) { - save_cur_using_data_addr(get_cur_using_data_addr()); + result = save_cur_using_data_addr(get_cur_using_data_addr()); } } else { result = EF_ENV_FULL; EF_INFO("Error: The flash has no available space to save ENV.\n"); - /* clear current using data section address on flash */ - save_cur_using_data_addr(0xFFFFFFFF); } env_cache_changed = false; @@ -858,11 +893,13 @@ static EfErrCode save_cur_using_data_addr(uint32_t cur_data_addr) { /* write current using data section address to flash */ result = ef_port_write(get_env_start_addr(), &cur_data_addr, 4); if (result == EF_WRITE_ERR) { - EF_INFO("Error: Write system section fault!\n"); + EF_INFO("Error: Write system section fault! Start address is 0x%08X, size is %ld.\n", + get_env_start_addr(), 4); EF_INFO("Note: The ENV can not be used.\n"); } } else { - EF_INFO("Error: Erased system section fault!\n"); + EF_INFO("Error: Erased system section fault! Start address is 0x%08X, size is %ld.\n", + get_env_start_addr(), 4); EF_INFO("Note: The ENV can not be used\n"); } return result; @@ -870,30 +907,28 @@ static EfErrCode save_cur_using_data_addr(uint32_t cur_data_addr) { #else static EfErrCode save_cur_using_data_addr(uint32_t cur_data_addr) { EfErrCode result = EF_NO_ERR; - uint32_t cur_using_addr[2]; - - /* read area0 and area1 current using data section address for backup */ - ef_port_read(get_env_start_addr(), &cur_using_addr[0], 4); - ef_port_read(get_env_start_addr() + 4, &cur_using_addr[1], 4); + uint32_t cur_system_sec_addr; - if (cur_data_addr < get_env_start_addr() + EF_ERASE_MIN_SIZE + env_data_section_size / 2){ - /* current using data section is in ENV area0 */ - cur_using_addr[0] = cur_data_addr; + if (cur_data_addr < get_env_start_addr() + ENV_AREA_SIZE / 2){ + /* current using system section is in ENV area0 */ + cur_system_sec_addr = get_env_start_addr(); } else { - /* current using data section is in ENV area1 */ - cur_using_addr[1] = cur_data_addr; + /* current using system section is in ENV area1 */ + cur_system_sec_addr = get_env_start_addr() + ENV_AREA_SIZE / 2; } /* erase ENV system section */ - result = ef_port_erase(get_env_start_addr(), 8); + result = ef_port_erase(cur_system_sec_addr, 4); if (result == EF_NO_ERR) { /* write area0 and area1 current using data section address to flash */ - result = ef_port_write(get_env_start_addr(), cur_using_addr, 8); + result = ef_port_write(cur_system_sec_addr, &cur_data_addr, 4); if (result == EF_WRITE_ERR) { - EF_INFO("Error: Write system section fault!\n"); + EF_INFO("Error: Write system section fault! Start address is 0x%08X, size is %ld.\n", + cur_system_sec_addr, 4); EF_INFO("Note: The ENV can not be used.\n"); } } else { - EF_INFO("Error: Erased system section fault!\n"); + EF_INFO("Error: Erased system section fault! Start address is 0x%08X, size is %ld.\n", + cur_system_sec_addr, 4); EF_INFO("Note: The ENV can not be used\n"); } return result; diff --git a/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_iap.c b/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_iap.c index 010bd47..16d1fd6 100644 --- a/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_iap.c +++ b/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_iap.c @@ -1,7 +1,7 @@ /* * This file is part of the EasyFlash Library. * - * Copyright (c) 2015, Armink, + * Copyright (c) 2015-2016, Armink, * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -31,7 +31,7 @@ #ifdef EF_USING_IAP /* IAP section backup application section start address in flash */ -static uint32_t bak_app_start_addr = NULL; +static uint32_t bak_app_start_addr = 0; static uint32_t get_bak_app_start_addr(void); diff --git a/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_utils.c b/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_utils.c index 4c5161f..770e860 100644 --- a/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_utils.c +++ b/demo/os/rt-thread/stm32f10x/components/easyflash/src/ef_utils.c @@ -1,7 +1,7 @@ /* * This file is part of the EasyFlash Library. * - * Copyright (c) 2015, Armink, + * Copyright (c) 2015-2016, Armink, * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -88,7 +88,7 @@ uint32_t ef_calc_crc32(uint32_t crc, const void *buf, size_t size) { const uint8_t *p; - p = buf; + p = (const uint8_t *)buf; crc = crc ^ ~0U; while (size--) {