Parcourir la source

nvs: add test for erase cycles distribution

Ivan Grokhotkov il y a 5 ans
Parent
commit
db34a4d031

+ 7 - 0
components/nvs_flash/test_nvs_host/spi_flash_emulation.h

@@ -36,6 +36,7 @@ public:
     SpiFlashEmulator(size_t sectorCount) : mUpperSectorBound(sectorCount)
     {
         mData.resize(sectorCount * SPI_FLASH_SEC_SIZE / 4, 0xffffffff);
+        mEraseCnt.resize(sectorCount);
         spi_flash_emulator_set(this);
     }
 
@@ -124,6 +125,7 @@ public:
         std::fill_n(begin(mData) + offset, SPI_FLASH_SEC_SIZE / 4, 0xffffffff);
 
         ++mEraseOps;
+        mEraseCnt[sectorNumber]++;
         mTotalTime += getEraseOpTime();
         return true;
     }
@@ -217,6 +219,10 @@ public:
         mFailCountdown = count;
     }
 
+    size_t getSectorEraseCount(uint32_t sector) const {
+        return mEraseCnt[sector];
+    }
+
 protected:
     static size_t getReadOpTime(uint32_t bytes);
     static size_t getWriteOpTime(uint32_t bytes);
@@ -224,6 +230,7 @@ protected:
 
 
     std::vector<uint32_t> mData;
+    std::vector<uint32_t> mEraseCnt;
 
     mutable size_t mReadOps = 0;
     mutable size_t mWriteOps = 0;

+ 30 - 1
components/nvs_flash/test_nvs_host/test_nvs.cpp

@@ -258,7 +258,7 @@ TEST_CASE("Page validates blob size", "[nvs]")
     Page page;
     TEST_ESP_OK(page.load(0));
 
-    char buf[2048] = { 0 };
+    char buf[4096] = { 0 };
     // There are two potential errors here:
     // - not enough space in the page (because one value has been written already)
     // - value is too long
@@ -527,6 +527,35 @@ TEST_CASE("can modify an item on a page which will be erased", "[nvs]")
     }
 }
 
+TEST_CASE("erase operations are distributed among sectors", "[nvs]")
+{
+    const size_t sectors = 6;
+    SpiFlashEmulator emu(sectors);
+    Storage storage;
+    CHECK(storage.init(0, sectors) == ESP_OK);
+    
+    /* Fill some part of storage with static values */
+    const size_t static_sectors = 2;
+    for (size_t i = 0; i < static_sectors * Page::ENTRY_COUNT; ++i) {
+        char name[Item::MAX_KEY_LENGTH];
+        snprintf(name, sizeof(name), "static%d", (int) i);
+        REQUIRE(storage.writeItem(1, name, i) == ESP_OK);
+    }
+
+    /* Now perform many write operations */
+    const size_t write_ops = 2000;
+    for (size_t i = 0; i < write_ops; ++i) {
+        REQUIRE(storage.writeItem(1, "value", i) == ESP_OK);
+    }
+
+    /* Check that erase counts are distributed between the remaining sectors */
+    const size_t max_erase_cnt = write_ops / Page::ENTRY_COUNT / (sectors - static_sectors) + 1;
+    for (size_t i = 0; i < sectors; ++i) {
+        auto erase_cnt = emu.getSectorEraseCount(i);
+        INFO("Sector " << i << " erased " << erase_cnt);
+        CHECK(erase_cnt <= max_erase_cnt);
+    }
+}
 
 TEST_CASE("can erase items", "[nvs]")
 {