]> granicus.if.org Git - esp-idf/commitdiff
nvs_flash: add functions to deinitialize storage
authorIvan Grokhotkov <ivan@espressif.com>
Mon, 18 Sep 2017 14:30:21 +0000 (22:30 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Tue, 19 Sep 2017 02:39:44 +0000 (10:39 +0800)
components/nvs_flash/include/nvs_flash.h
components/nvs_flash/src/nvs_api.cpp
components/nvs_flash/test/test_nvs.c

index c9e4a72d742498a591eff8f73012a554d85643c1..a7ef7f4511efc564bd978a7a969618d8ccb4a0e5 100644 (file)
@@ -24,7 +24,7 @@ extern "C" {
  * @brief Initialize the default NVS partition.
  *
  * This API initialises the default NVS partition. The default NVS partition
- * is the one that is labelled "nvs" in the partition table.
+ * is the one that is labeled "nvs" in the partition table.
  *
  * @return
  *      - ESP_OK if storage was successfully initialized.
@@ -38,7 +38,7 @@ esp_err_t nvs_flash_init(void);
 /**
  * @brief Initialize NVS flash storage for the specified partition.
  *
- * @param[in]  partition_name    Name (label) of the partition. Note that internally a reference to
+ * @param[in]  partition_label   Label of the partition. Note that internally a reference to
  *                               passed value is kept and it should be accessible for future operations
  *
  * @return
@@ -48,7 +48,30 @@ esp_err_t nvs_flash_init(void);
  *      - ESP_ERR_NOT_FOUND if specified partition is not found in the partition table
  *      - one of the error codes from the underlying flash storage driver
  */
-esp_err_t nvs_flash_init_partition(const char *partition_name);
+esp_err_t nvs_flash_init_partition(const char *partition_label);
+
+/**
+ * @brief Deinitialize NVS storage for the default NVS partition
+ *
+ * Default NVS partition is the partition with "nvs" label in the partition table.
+ *
+ * @return
+ *      - ESP_OK on success (storage was deinitialized)
+ *      - ESP_ERR_NVS_NOT_INITIALIZED if the storage was not initialized prior to this call
+ */
+esp_err_t nvs_flash_deinit(void);
+
+/**
+ * @brief Deinitialize NVS storage for the given NVS partition
+ *
+ * @param[in]  partition_label   Label of the partition
+ *
+ * @return
+ *      - ESP_OK on success
+ *      - ESP_ERR_NVS_NOT_INITIALIZED if the storage for given partition was not
+ *        initialized prior to this call
+ */
+esp_err_t nvs_flash_deinit_partition(const char* partition_label);
 
 /**
  * @brief Erase the default NVS partition
index e5c2f5adcd4e1e1b3fe6b81b59362ae9636eb2f8..dba8e115a0364d777032e958f2bd84379fb10616 100644 (file)
@@ -126,6 +126,42 @@ extern "C" esp_err_t nvs_flash_init(void)
     return nvs_flash_init_partition(NVS_DEFAULT_PART_NAME);
 }
 
+extern "C" esp_err_t nvs_flash_deinit_partition(const char* partition_name)
+{
+    Lock::init();
+    Lock lock;
+
+    nvs::Storage* storage = lookup_storage_from_name(partition_name);
+    if (!storage) {
+        return ESP_ERR_NVS_NOT_INITIALIZED;
+    }
+
+    /* Clean up handles related to the storage being deinitialized */
+    auto it = s_nvs_handles.begin();
+    auto next = it;
+    while(it != s_nvs_handles.end()) {
+        next++;
+        if (it->mStoragePtr == storage) {
+            ESP_LOGD(TAG, "Deleting handle %d (ns=%d) related to partition \"%s\" (missing call to nvs_close?)",
+                    it->mHandle, it->mNsIndex, partition_name);
+            s_nvs_handles.erase(it);
+            delete static_cast<HandleEntry*>(it);
+        }
+        it = next;
+    }
+
+    /* Finally delete the storage itself */
+    s_nvs_storage_list.erase(storage);
+    delete storage;
+
+    return ESP_OK;
+}
+
+extern "C" esp_err_t nvs_flash_deinit(void)
+{
+    return nvs_flash_deinit_partition(NVS_DEFAULT_PART_NAME);
+}
+
 extern "C" esp_err_t nvs_flash_erase_partition(const char *part_name)
 {
     const esp_partition_t* partition = esp_partition_find_first(
index 07d01db468f1d66f3391e470d6d35d2f516fc9ac..ed0884a7d8661b15a1ce2e20961c0b372b277de8 100644 (file)
@@ -59,5 +59,9 @@ TEST_CASE("various nvs tests", "[nvs]")
     TEST_ASSERT_EQUAL_INT32(0, strcmp(buf, str));
 
     nvs_close(handle_1);
+
+    // check that deinit does not leak memory if some handles are still open
+    nvs_flash_deinit();
+
     nvs_close(handle_2);
 }