Forráskód Böngészése

openthread: change partition table to nvs flash

zhangwenxu 2 éve
szülő
commit
4b86ee16fa

+ 1 - 1
components/openthread/CMakeLists.txt

@@ -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)

+ 7 - 0
components/openthread/private_include/esp_openthread_platform.h

@@ -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

+ 1 - 1
components/openthread/private_include/openthread-core-esp32x-ftd-config.h

@@ -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

+ 1 - 1
components/openthread/private_include/openthread-core-esp32x-mtd-config.h

@@ -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

+ 1 - 1
components/openthread/private_include/openthread-core-esp32x-radio-config.h

@@ -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

+ 2 - 8
components/openthread/src/esp_openthread_platform.cpp

@@ -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");

+ 214 - 0
components/openthread/src/port/esp_openthread_settings.c

@@ -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);
+}

+ 1 - 1
examples/openthread/ot_br/main/esp_ot_config.h

@@ -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,                  \
     }

+ 0 - 1
examples/openthread/ot_br/partitions.csv

@@ -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 - 1
examples/openthread/ot_cli/main/esp_ot_config.h

@@ -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,                  \
     }

+ 0 - 1
examples/openthread/ot_cli/partitions.csv

@@ -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 - 1
examples/openthread/ot_rcp/main/esp_ot_config.h

@@ -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,                  \
     }

+ 0 - 1
examples/openthread/ot_rcp/partitions.csv

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