openthread: change partition table to nvs flash

pull/11692/head
zhangwenxu 2023-05-17 20:35:17 +08:00
rodzic c18cdd8859
commit 4b86ee16fa
13 zmienionych plików z 230 dodań i 18 usunięć

Wyświetl plik

@ -174,7 +174,7 @@ idf_component_register(SRC_DIRS "${src_dirs}"
REQUIRES esp_netif lwip driver
LDFRAGMENTS linker.lf
PRIV_REQUIRES console esp_event esp_partition esp_timer
ieee802154 mbedtls spi_flash)
ieee802154 mbedtls nvs_flash)
if(CONFIG_OPENTHREAD_ENABLED)
if(CONFIG_OPENTHREAD_RADIO)

Wyświetl plik

@ -139,6 +139,13 @@ void esp_openthread_platform_update(esp_openthread_mainloop_context_t *mainloop)
*/
esp_err_t esp_openthread_platform_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop);
/**
* @brief This function set the OpenThread storage name
*
* @param[in] name The OpenThread storage name.
*
*/
void esp_openthread_set_storage_name(const char *name);
#ifdef __cplusplus
} // end of extern "C"
#endif

Wyświetl plik

@ -32,7 +32,7 @@
* When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
*
*/
#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 0
/**
* @def OPENTHREAD_CONFIG_LOG_OUTPUT

Wyświetl plik

@ -32,7 +32,7 @@
* When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
*
*/
#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 0
/**
* @def OPENTHREAD_CONFIG_LOG_OUTPUT

Wyświetl plik

@ -31,7 +31,7 @@
* When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
*
*/
#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 0
/**
* @def OPENTHREAD_CONFIG_LOG_OUTPUT

Wyświetl plik

@ -102,18 +102,12 @@ esp_err_t esp_openthread_platform_init(const esp_openthread_platform_config_t *c
s_openthread_platform_initialized = true;
esp_err_t ret = ESP_OK;
/* Avoid to compile flash in RADIO type device */
#if !CONFIG_OPENTHREAD_RADIO
const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY,
config->port_config.storage_partition_name);
ESP_RETURN_ON_FALSE(partition, ESP_ERR_INVALID_ARG, OT_PLAT_LOG_TAG, "OpenThread storage partition not found");
esp_openthread_flash_set_partition(partition);
#endif
s_platform_config = *config;
ESP_GOTO_ON_ERROR(esp_openthread_lock_init(), exit, OT_PLAT_LOG_TAG, "esp_openthread_lock_init failed");
ESP_GOTO_ON_ERROR(esp_openthread_alarm_init(), exit, OT_PLAT_LOG_TAG, "esp_openthread_alarm_init failed");
esp_openthread_set_storage_name(config->port_config.storage_partition_name);
if (config->host_config.host_connection_mode == HOST_CONNECTION_MODE_RCP_SPI) {
ESP_GOTO_ON_ERROR(esp_openthread_spi_slave_init(config), exit, OT_PLAT_LOG_TAG,
"esp_openthread_spi_slave_init failed");

Wyświetl plik

@ -0,0 +1,214 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nvs.h"
#include "esp_check.h"
#include "esp_openthread_common_macro.h"
#include "openthread/instance.h"
#include "openthread/platform/settings.h"
#define OT_NAMESPACE "openthread"
#define OT_PART_NAME s_storage_name
#define OT_KEY_PATTERN "OT%02x"
#define OT_KEY_INDEX_PATTERN "OT%02x%02x"
#define OT_KEY_PATTERN_LEN 5
#define OT_KEY_INDEX_PATTERN_LEN 7
static nvs_handle_t s_ot_nvs_handle;
static const char *s_storage_name;
void esp_openthread_set_storage_name(const char *name)
{
s_storage_name = name;
}
static esp_err_t get_next_empty_index(uint16_t aKey, uint8_t *index)
{
ESP_RETURN_ON_FALSE((s_ot_nvs_handle != 0), ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "OT NVS handle is invalid.");
esp_err_t ret = ESP_OK;
static volatile uint8_t s_unused_pos = 0;
char ot_nvs_key[OT_KEY_INDEX_PATTERN_LEN] = { 0 };
nvs_iterator_t nvs_it = NULL;
bool found = false;
for (uint8_t i = 0; i != UINT8_MAX; i++) {
s_unused_pos++;
snprintf(ot_nvs_key, sizeof(ot_nvs_key), OT_KEY_INDEX_PATTERN, (uint8_t)aKey, s_unused_pos);
ret = nvs_entry_find(OT_PART_NAME, OT_NAMESPACE, NVS_TYPE_BLOB, &nvs_it);
while (ret == ESP_OK) {
nvs_entry_info_t info;
nvs_entry_info(nvs_it, &info);
if (memcmp(ot_nvs_key, info.key, OT_KEY_INDEX_PATTERN_LEN - 1) == 0) {
found = true;
break;
}
ret = nvs_entry_next(&nvs_it);
}
nvs_release_iterator(nvs_it);
if (!found) {
// find an empty position, return ESP_OK
*index = s_unused_pos;
return ESP_OK;
}
}
// all index was used, no memory for current data, return ESP_ERR_NOT_FOUND.
return ESP_ERR_NOT_FOUND;
}
static esp_err_t find_target_key_using_index(uint16_t aKey, int aIndex, char *key, size_t key_len)
{
ESP_RETURN_ON_FALSE((s_ot_nvs_handle != 0), ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "OT NVS handle is invalid.");
esp_err_t ret = ESP_OK;
nvs_iterator_t nvs_it = NULL;
int cur_index = 0;
char ot_nvs_key[OT_KEY_PATTERN_LEN] = { 0 };
ret = nvs_entry_find(OT_PART_NAME, OT_NAMESPACE, NVS_TYPE_BLOB, &nvs_it);
if (ret != ESP_OK) {
return ret;
}
snprintf(ot_nvs_key, sizeof(ot_nvs_key), OT_KEY_PATTERN, (uint8_t)aKey);
while (ret == ESP_OK) {
nvs_entry_info_t info;
nvs_entry_info(nvs_it, &info);
if (memcmp(ot_nvs_key, info.key, OT_KEY_PATTERN_LEN - 1) == 0) {
if (cur_index == aIndex) {
memcpy(key, info.key, key_len);
break;
} else {
cur_index++;
}
}
ret = nvs_entry_next(&nvs_it);
}
nvs_release_iterator(nvs_it);
if ((cur_index != aIndex) || (ret != ESP_OK)) {
return ESP_FAIL;
}
return ESP_OK;
}
static esp_err_t erase_all_key(uint16_t aKey)
{
ESP_RETURN_ON_FALSE((s_ot_nvs_handle != 0), ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG, "OT NVS handle is invalid.");
esp_err_t ret = ESP_OK;
nvs_iterator_t nvs_it = NULL;
char ot_nvs_key[OT_KEY_PATTERN_LEN] = { 0 };
ret = nvs_entry_find(OT_PART_NAME, OT_NAMESPACE, NVS_TYPE_BLOB, &nvs_it);
if (ret == ESP_ERR_NVS_NOT_FOUND) {
return ESP_OK;
}
ESP_RETURN_ON_FALSE((ret == ESP_OK && nvs_it != NULL), ESP_FAIL, OT_PLAT_LOG_TAG, "Can not find any data in nvs flash, err: %d", ret);
while (ret == ESP_OK) {
snprintf(ot_nvs_key, sizeof(ot_nvs_key), OT_KEY_PATTERN, (uint8_t)aKey);
nvs_entry_info_t info;
nvs_entry_info(nvs_it, &info);
if (memcmp(ot_nvs_key, info.key, OT_KEY_PATTERN_LEN - 1) == 0) {
ret = nvs_erase_key(s_ot_nvs_handle, info.key);
if (ret != ESP_OK) {
break;
}
}
ret = nvs_entry_next(&nvs_it);
}
nvs_release_iterator(nvs_it);
ret = nvs_commit(s_ot_nvs_handle);
if (ret != ESP_OK) {
return ESP_FAIL;
}
return ESP_OK;
}
void otPlatSettingsInit(otInstance *aInstance, const uint16_t *aSensitiveKeys, uint16_t aSensitiveKeysLength)
{
esp_err_t err = nvs_open(OT_NAMESPACE, NVS_READWRITE, &s_ot_nvs_handle);
if (err != ESP_OK) {
ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to open NVS namespace (0x%x)", err);
assert(0);
}
}
void otPlatSettingsDeinit(otInstance *aInstance)
{
if (s_ot_nvs_handle != 0) {
nvs_close(s_ot_nvs_handle);
}
}
otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
{
ESP_RETURN_ON_FALSE((s_ot_nvs_handle != 0), OT_ERROR_NOT_FOUND, OT_PLAT_LOG_TAG, "OT NVS handle is invalid.");
esp_err_t ret = ESP_OK;
char ot_nvs_key[OT_KEY_INDEX_PATTERN_LEN] = { 0 };
ret = find_target_key_using_index(aKey, aIndex, ot_nvs_key, OT_KEY_INDEX_PATTERN_LEN);
if (ret != ESP_OK) {
return OT_ERROR_NOT_FOUND;
}
ret = nvs_get_blob(s_ot_nvs_handle, ot_nvs_key, aValue, (size_t *)aValueLength);
ESP_RETURN_ON_FALSE((ret == ESP_OK), OT_ERROR_NOT_FOUND, OT_PLAT_LOG_TAG, "Data not found, err: %d", ret);
return OT_ERROR_NONE;
}
otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
ESP_RETURN_ON_FALSE((s_ot_nvs_handle != 0), OT_ERROR_NOT_FOUND, OT_PLAT_LOG_TAG, "OT NVS handle is invalid.");
esp_err_t ret = ESP_OK;
char ot_nvs_key[OT_KEY_INDEX_PATTERN_LEN]= { 0 };
snprintf(ot_nvs_key, sizeof(ot_nvs_key), OT_KEY_INDEX_PATTERN, (uint8_t)aKey, 0);
ret = nvs_set_blob(s_ot_nvs_handle, ot_nvs_key, aValue, aValueLength);
ESP_RETURN_ON_FALSE((ret == ESP_OK), OT_ERROR_NO_BUFS, OT_PLAT_LOG_TAG, "No buffers, err: %d", ret);
ret = nvs_commit(s_ot_nvs_handle);
ESP_RETURN_ON_FALSE((ret == ESP_OK), OT_ERROR_NO_BUFS, OT_PLAT_LOG_TAG, "OT NVS handle shut down, err: %d", ret);
return OT_ERROR_NONE;
}
otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
ESP_RETURN_ON_FALSE((s_ot_nvs_handle != 0), OT_ERROR_NOT_FOUND, OT_PLAT_LOG_TAG, "OT NVS handle is invalid.");
esp_err_t ret = ESP_OK;
uint8_t unused_pos;
char ot_nvs_key[OT_KEY_INDEX_PATTERN_LEN] = { 0 };
ret = get_next_empty_index(aKey, &unused_pos);
ESP_RETURN_ON_FALSE((ret == ESP_OK), OT_ERROR_NO_BUFS, OT_PLAT_LOG_TAG, "No buffers, err: %d", ret);
snprintf(ot_nvs_key, sizeof(ot_nvs_key), OT_KEY_INDEX_PATTERN, (uint8_t)aKey, unused_pos);
ret = nvs_set_blob(s_ot_nvs_handle, ot_nvs_key, aValue, aValueLength);
ESP_RETURN_ON_FALSE((ret == ESP_OK), OT_ERROR_NO_BUFS, OT_PLAT_LOG_TAG, "No buffers, err: %d", ret);
ret = nvs_commit(s_ot_nvs_handle);
ESP_RETURN_ON_FALSE((ret == ESP_OK), OT_ERROR_NO_BUFS, OT_PLAT_LOG_TAG, "OT NVS handle shut down, err: %d", ret);
return OT_ERROR_NONE;
}
otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
{
ESP_RETURN_ON_FALSE((s_ot_nvs_handle != 0), OT_ERROR_NOT_FOUND, OT_PLAT_LOG_TAG, "OT NVS handle is invalid.");
esp_err_t ret = ESP_OK;
if (aIndex == -1) {
ret = erase_all_key(aKey);
} else {
char ot_nvs_key[OT_KEY_INDEX_PATTERN_LEN] = { 0 };
ret = find_target_key_using_index(aKey, aIndex, ot_nvs_key, OT_KEY_INDEX_PATTERN_LEN);
if (ret != ESP_OK) {
return OT_ERROR_NOT_FOUND;
}
ret = nvs_erase_key(s_ot_nvs_handle, ot_nvs_key);
nvs_commit(s_ot_nvs_handle);
}
return OT_ERROR_NONE;
}
void otPlatSettingsWipe(otInstance *aInstance)
{
nvs_erase_all(s_ot_nvs_handle);
}

Wyświetl plik

@ -96,7 +96,7 @@
#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \
{ \
.storage_partition_name = "ot_storage", \
.storage_partition_name = "nvs", \
.netif_queue_size = 10, \
.task_queue_size = 10, \
}

Wyświetl plik

@ -3,4 +3,3 @@
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1600K,
ot_storage, data, 0x3a, , 0x2000,

1 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x6000,
4 phy_init, data, phy, 0xf000, 0x1000,
5 factory, app, factory, 0x10000, 1600K,
ot_storage, data, 0x3a, , 0x2000,

Wyświetl plik

@ -66,7 +66,7 @@
#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \
{ \
.storage_partition_name = "ot_storage", \
.storage_partition_name = "nvs", \
.netif_queue_size = 10, \
.task_queue_size = 10, \
}

Wyświetl plik

@ -3,4 +3,3 @@
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 0x120000,
ot_storage, data, 0x3a, , 0x2000,

1 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x6000,
4 phy_init, data, phy, 0xf000, 0x1000,
5 factory, app, factory, 0x10000, 0x120000,
ot_storage, data, 0x3a, , 0x2000,

Wyświetl plik

@ -75,7 +75,7 @@
#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \
{ \
.storage_partition_name = "ot_storage", \
.storage_partition_name = "nvs", \
.netif_queue_size = 10, \
.task_queue_size = 10, \
}

Wyświetl plik

@ -3,4 +3,3 @@
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, , 0x1000,
factory, app, factory, 0x10000, 1M,
ot_storage, data, 0x3a, , 0x2000,

1 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x6000,
4 phy_init, data, phy, , 0x1000,
5 factory, app, factory, 0x10000, 1M,
ot_storage, data, 0x3a, , 0x2000,