/** * If the ENV is not exist, create it. * @see flash_write_env * * @param key ENV name * @param value ENV value * * @return result */ static FlashErrCode create_env(const char *key, const char *value) { FlashErrCode result = FLASH_NO_ERR; FLASH_ASSERT(key); FLASH_ASSERT(value); if (*key == NULL) { FLASH_INFO("Flash ENV name must be not empty!\n"); return FLASH_ENV_NAME_ERR; } if (strstr(key, "=")) { FLASH_INFO("Flash ENV name can't contain '='.\n"); return FLASH_ENV_NAME_ERR; } /* find ENV */ if (find_env(key)) { FLASH_INFO("The name of \"%s\" is already exist.\n", key); return FLASH_ENV_NAME_EXIST; } /* write ENV at the end of cache */ result = write_env(key, value); return result; }
/** * Flash IAP function initialize. * * @param start_addr IAP section backup application section start address in flash * * @return result */ FlashErrCode flash_iap_init(uint32_t start_addr) { FlashErrCode result = FLASH_NO_ERR; FLASH_ASSERT(start_addr); bak_app_start_addr = start_addr; return result; }
/** * Flash ENV initialize. * * @param start_addr ENV start address in flash * @param total_size ENV section total size (@note must be word alignment) * @param erase_min_size the minimum size of flash erasure * @param default_env default ENV set for user * @param default_env_size default ENV set size * * @return result */ FlashErrCode flash_env_init(uint32_t start_addr, size_t total_size, size_t erase_min_size, flash_env const *default_env, size_t default_env_size) { FlashErrCode result = FLASH_NO_ERR; FLASH_ASSERT(start_addr); FLASH_ASSERT(total_size); FLASH_ASSERT(erase_min_size); FLASH_ASSERT(default_env); FLASH_ASSERT(default_env_size < FLASH_USER_SETTING_ENV_SIZE); /* must be word alignment for ENV */ FLASH_ASSERT(FLASH_USER_SETTING_ENV_SIZE % 4 == 0); FLASH_ASSERT(total_size % 4 == 0); env_start_addr = start_addr; env_total_size = total_size; flash_erase_min_size = erase_min_size; default_env_set = default_env; default_env_set_size = default_env_size; FLASH_DEBUG("Env start address is 0x%08X, size is %d bytes.\n", start_addr, total_size); flash_load_env(); return result; }
/** * ENV set default. * * @return result */ FlashErrCode flash_env_set_default(void){ FlashErrCode result = FLASH_NO_ERR; size_t i; FLASH_ASSERT(default_env_set); FLASH_ASSERT(default_env_set_size); /* set ENV detail part end address is at ENV detail part start address */ set_env_detail_end_addr(get_env_detail_addr()); /* create default ENV */ for (i = 0; i < default_env_set_size; i++) { create_env(default_env_set[i].key, default_env_set[i].value); } flash_save_env(); return result; }
/** * Delete an ENV in cache. * * @param key ENV name * * @return result */ FlashErrCode flash_del_env(const char *key){ FlashErrCode result = FLASH_NO_ERR; char *del_env_str = NULL; size_t del_env_length, remain_env_length; FLASH_ASSERT(key); if (*key == NULL) { FLASH_INFO("Flash ENV name must be not NULL!\n"); return FLASH_ENV_NAME_ERR; } if (strstr(key, "=")) { FLASH_INFO("Flash ENV name or value can't contain '='.\n"); return FLASH_ENV_NAME_ERR; } /* find ENV */ del_env_str = (char *) find_env(key); if (!del_env_str) { FLASH_INFO("Not find \"%s\" in ENV.\n", key); return FLASH_ENV_NAME_ERR; } del_env_length = strlen(del_env_str); /* '\0' also must be as ENV length */ del_env_length ++; /* the address must multiple of 4 */ if (del_env_length % 4 != 0) { del_env_length = (del_env_length / 4 + 1) * 4; } /* calculate remain ENV length */ remain_env_length = get_env_detail_size() - (((uint32_t) del_env_str + del_env_length) - ((uint32_t) env_cache + ENV_PARAM_PART_BYTE_SIZE)); /* remain ENV move forward */ memcpy(del_env_str, del_env_str + del_env_length, remain_env_length); /* reset ENV end address */ set_env_detail_end_addr(get_env_detail_end_addr() - del_env_length); return result; }
/** * Find ENV. * * @param key ENV name * * @return index of ENV in ram cache */ static uint32_t *find_env(const char *key) { uint32_t *env_cache_addr = NULL; char *env_start, *env_end, *env, *env_bak; FLASH_ASSERT(cur_using_data_addr); if (*key == NULL) { FLASH_INFO("Flash ENV name must be not empty!\n"); return NULL; } /* from data section start to data section end */ env_start = (char *) ((char *) env_cache + ENV_PARAM_PART_BYTE_SIZE); env_end = (char *) ((char *) env_cache + ENV_PARAM_PART_BYTE_SIZE + get_env_detail_size()); /* ENV is null */ if (env_start == env_end) { return NULL; } env = env_start; while (env < env_end) { /* storage model is key=value\0 */ env_bak = strstr(env, key); /* the key name length must be equal */ if (env_bak && (env_bak[strlen(key)] == '=')) { env_cache_addr = (uint32_t *) env_bak; break; } else { /* next ENV and word alignment */ if ((strlen(env) + 1) % 4 == 0) { env += strlen(env) + 1; } else { env += ((strlen(env) + 1) / 4 + 1) * 4; } } } return env_cache_addr; }
/** * Get IAP section start address in flash. * * @return size */ static uint32_t get_bak_app_start_addr(void) { FLASH_ASSERT(bak_app_start_addr); return bak_app_start_addr; }
/** * Get current ENV section total size. * * @see flash_get_env_total_size * * @return size */ size_t flash_get_env_total_size(void) { /* must be initialized */ FLASH_ASSERT(env_total_size); return env_total_size; }
/** * Get ENV detail part start address. * * @return detail part start address */ static uint32_t get_env_detail_addr(void) { FLASH_ASSERT(cur_using_data_addr); return get_cur_using_data_addr() + ENV_PARAM_PART_BYTE_SIZE; }
/** * Get current using data section address. * * @return current using data section address */ static uint32_t get_cur_using_data_addr(void) { FLASH_ASSERT(cur_using_data_addr); return cur_using_data_addr; }
/** * Get ENV start address in flash. * * @return ENV start address in flash */ static uint32_t get_env_start_addr(void) { FLASH_ASSERT(env_start_addr); return env_start_addr; }