]> granicus.if.org Git - esp-idf/commitdiff
Added component to change standard size of the flash device. Now the sector size...
authorDmitry Yakovlev <dmitry@espressif.com>
Thu, 20 Jul 2017 10:09:39 +0000 (13:09 +0300)
committerDmitry Yakovlev <dmitry@espressif.com>
Mon, 31 Jul 2017 10:19:36 +0000 (13:19 +0300)
components/wear_levelling/Kconfig [new file with mode: 0755]
components/wear_levelling/README.rst
components/wear_levelling/WL_Ext_Perf.cpp [new file with mode: 0755]
components/wear_levelling/WL_Ext_Safe.cpp [new file with mode: 0755]
components/wear_levelling/private_include/WL_Ext_Cfg.h [new file with mode: 0755]
components/wear_levelling/private_include/WL_Ext_Perf.h [new file with mode: 0755]
components/wear_levelling/private_include/WL_Ext_Safe.h [new file with mode: 0755]
components/wear_levelling/wear_levelling.cpp

diff --git a/components/wear_levelling/Kconfig b/components/wear_levelling/Kconfig
new file mode 100755 (executable)
index 0000000..158c217
--- /dev/null
@@ -0,0 +1,50 @@
+menu "FAT FS Wear Levelling Settings"
+
+choice WL_SECTOR_SIZE
+   bool "FAT FS sector size"
+   default WL_SECTOR_SIZE_FAT
+   help
+       Specify the FAT sector size.
+       You can set default sector size or size that will
+       fit to the flash device sector size.
+       
+config WL_SECTOR_SIZE_FAT
+   bool "512"
+config WL_SECTOR_SIZE_FLASH
+   bool "4096"
+endchoice
+
+config WL_SECTOR_SIZE
+    int
+    default 512 if WL_SECTOR_SIZE_FAT
+    default 4096 if WL_SECTOR_SIZE_FLASH
+
+choice WL_SECTOR_MODE
+   bool "Sector store mode"
+   default WL_SECTOR_MODE_PERF
+   help
+       Specify the mode to store data into the flash.
+       
+config WL_SECTOR_MODE_PERF
+   bool "Perfomance"
+   help
+       In Performance mode a data will be stored to the RAM and then 
+       stored back to the flash. Compare to the Safety mode, this operation
+       faster, but if by the erase sector operation power will be off, the 
+       data from complete flash device sector will be lost.
+       
+config WL_SECTOR_MODE_SAFE
+   bool "Safety"
+   help
+       In Safety mode a data from complete flash device sector will be stored to the flash and then 
+       stored back to the flash. Compare to the Performance mode, this operation
+       slower, but if by the erase sector operation power will be off, the 
+       data of the full flash device sector will not be lost.
+endchoice
+
+config WL_SECTOR_MODE
+    int
+    default 0 if WL_SECTOR_MODE_PERF
+    default 1 if WL_SECTOR_MODE_SAFE
+
+endmenu
index ebe298355c13a59b0df3356bc1563d1c7c0214a2..c9fdd849ba1cb10f657619730974f7fe3e438814 100644 (file)
@@ -14,6 +14,19 @@ memory mapping data in the external SPI flash through the partition component. I
 also has higher-level APIs which work with FAT filesystem defined in 
 the :doc:`FAT filesystem </api-reference/storage/fatfs>`.
 
+The weat levelling componwnt, together with FAT FS component, works with FAT FS sector size 4096 
+bytes which is standard size of the flash devices. In this mode the component has best perfomance, 
+but needs additional memoty in the RAM. To save internal memory the component has two additional modes 
+to work with sector size 512 bytes: Performance and Safety modes. In Performance mode by erase sector 
+operation data will be stored to the RAM, sector will be erased and then data will be stored 
+back to the flash. If by this operation power off situation will occure, the complete 4096 bytes 
+will be lost. To prevent this the Safety mode was implemented. In dafety mode the data will be first 
+stored to the flash and after sector will be erased, will be stored back. If power off situation will 
+occure, after power on, the data will be recovered. 
+By default defined the sector size 512 bytes and Performance mode. To change these values please use 
+the configuratoin menu.  
+
+
 The wear levelling component does not cache data in RAM. Write and erase functions 
 modify flash directly, and flash contents is consistent when the function returns.
 
diff --git a/components/wear_levelling/WL_Ext_Perf.cpp b/components/wear_levelling/WL_Ext_Perf.cpp
new file mode 100755 (executable)
index 0000000..18869f2
--- /dev/null
@@ -0,0 +1,163 @@
+// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//     http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+#include "WL_Ext_Perf.h"\r
+#include <stdlib.h>\r
+#include "esp_log.h"\r
+\r
+static const char *TAG = "wl_ext_perf";\r
+\r
+#define WL_EXT_RESULT_CHECK(result) \\r
+    if (result != ESP_OK) { \\r
+        ESP_LOGE(TAG,"%s(%d): result = 0x%08x", __FUNCTION__, __LINE__, result); \\r
+        return (result); \\r
+    }\r
+\r
+WL_Ext_Perf::WL_Ext_Perf(): WL_Flash()\r
+{\r
+    this->sector_buffer = NULL;\r
+}\r
+\r
+WL_Ext_Perf::~WL_Ext_Perf()\r
+{\r
+    free(this->sector_buffer);\r
+}\r
+\r
+esp_err_t WL_Ext_Perf::config(WL_Config_s *cfg, Flash_Access *flash_drv)\r
+{\r
+    wl_ext_cfg_t *config = (wl_ext_cfg_t *)cfg;\r
+\r
+    this->fat_sector_size = config->fat_sector_size;\r
+    this->flash_sector_size = cfg->sector_size;\r
+\r
+    this->sector_buffer = (uint32_t *)malloc(cfg->sector_size);\r
+    if (this->sector_buffer == NULL) {\r
+        return ESP_ERR_NO_MEM;\r
+    }\r
+\r
+    this->size_factor = this->flash_sector_size / this->fat_sector_size;\r
+    if (this->size_factor < 1) {\r
+        return ESP_ERR_INVALID_ARG;\r
+    }\r
+\r
+    return WL_Flash::config(cfg, flash_drv);\r
+}\r
+\r
+esp_err_t WL_Ext_Perf::init()\r
+{\r
+    return WL_Flash::init();\r
+}\r
+\r
+size_t WL_Ext_Perf::chip_size()\r
+{\r
+    return WL_Flash::chip_size();\r
+}\r
+size_t WL_Ext_Perf::sector_size()\r
+{\r
+    return this->fat_sector_size;\r
+}\r
+\r
+esp_err_t WL_Ext_Perf::erase_sector(size_t sector)\r
+{\r
+    return this->erase_sector_fit(sector, 1);\r
+}\r
+\r
+esp_err_t WL_Ext_Perf::erase_sector_fit(uint32_t start_sector, uint32_t count)\r
+{\r
+    // This method works with one flash device sector and able to erase "count" of fatfs sectors from this sector\r
+    esp_err_t result = ESP_OK;\r
+\r
+    uint32_t pre_check_start = start_sector % this->size_factor;\r
+\r
+\r
+    for (int i = 0; i < this->size_factor; i++) {\r
+        if ((i < pre_check_start) || (i >= count + pre_check_start)) {\r
+            result = this->read(start_sector / this->size_factor * this->flash_sector_size + i * this->fat_sector_size, &this->sector_buffer[i * this->fat_sector_size / sizeof(uint32_t)], this->fat_sector_size);\r
+            WL_EXT_RESULT_CHECK(result);\r
+        }\r
+    }\r
+\r
+    result = WL_Flash::erase_sector(start_sector / this->size_factor); // erase comlete flash sector\r
+    WL_EXT_RESULT_CHECK(result);\r
+    // And write back only data that should not be erased...\r
+    for (int i = 0; i < this->size_factor; i++) {\r
+        if ((i < pre_check_start) || (i >= count + pre_check_start)) {\r
+            result = this->write(start_sector / this->size_factor * this->flash_sector_size + i * this->fat_sector_size, &this->sector_buffer[i * this->fat_sector_size / sizeof(uint32_t)], this->fat_sector_size);\r
+            WL_EXT_RESULT_CHECK(result);\r
+        }\r
+    }\r
+    return ESP_OK;\r
+}\r
+\r
+esp_err_t WL_Ext_Perf::erase_range(size_t start_address, size_t size)\r
+{\r
+    esp_err_t result = ESP_OK;\r
+    if ((start_address % this->fat_sector_size) != 0) {\r
+        result = ESP_ERR_INVALID_ARG;\r
+    }\r
+    if (((size % this->fat_sector_size) != 0) || (size == 0)) {\r
+        result = ESP_ERR_INVALID_ARG;\r
+    }\r
+    WL_EXT_RESULT_CHECK(result);\r
+\r
+    // The range to erase could be allocated in any possible way\r
+    // ---------------------------------------------------------\r
+    // |       |       |       |       |\r
+    // |0|0|x|x|x|x|x|x|x|x|x|x|x|x|0|0|\r
+    // | pre   | rest  | rest  | post  |  <- check ranges\r
+    //\r
+    // Pre check - the data that is not fit to the full sector at the begining of the erased block\r
+    // Post check - the data that are not fit to the full sector at the end of the erased block\r
+    // rest - data that are fit to the flash device sector at the middle of the erased block\r
+    //\r
+    // In case of pre and post check situations the data of the non erased area have to be readed first and then\r
+    // stored back.\r
+    // For the rest area this operation not needed because complete flash device sector will be erased.\r
+\r
+    ESP_LOGV(TAG, "%s begin, addr = 0x%08x, size = %i", __func__, start_address, size);\r
+    // Calculate pre check values\r
+    uint32_t pre_check_start = (start_address / this->fat_sector_size) % this->size_factor;\r
+    uint32_t sectors_count = size / this->fat_sector_size;\r
+    uint32_t pre_check_count = (this->size_factor - pre_check_start);\r
+    if (pre_check_count > sectors_count) {\r
+        pre_check_count = sectors_count;\r
+    }\r
+\r
+    // Calculate post ckeck\r
+    uint32_t post_check_count = (sectors_count - pre_check_count) % this->size_factor;\r
+    uint32_t post_check_start = ((start_address + size - post_check_count * this->fat_sector_size) / this->fat_sector_size);\r
+\r
+    // Calculate rest\r
+    uint32_t rest_check_count = sectors_count - pre_check_count - post_check_count;\r
+    if ((pre_check_count == this->size_factor) && (0 == pre_check_start)) {\r
+        rest_check_count++;\r
+        pre_check_count = 0;\r
+    }\r
+    uint32_t rest_check_start = start_address + pre_check_count * this->fat_sector_size;\r
+\r
+    // Here we will clear pre_check_count amount of sectors\r
+    if (pre_check_count != 0) {\r
+        result = this->erase_sector_fit(start_address / this->fat_sector_size, pre_check_count);\r
+        WL_EXT_RESULT_CHECK(result);\r
+    }\r
+    if (rest_check_count > 0) {\r
+        rest_check_count = rest_check_count / this->size_factor;\r
+        result = WL_Flash::erase_range(rest_check_start, rest_check_count * this->flash_sector_size);\r
+        WL_EXT_RESULT_CHECK(result);\r
+    }\r
+    if (post_check_count != 0) {\r
+        result = this->erase_sector_fit(post_check_start, post_check_count);\r
+        WL_EXT_RESULT_CHECK(result);\r
+    }\r
+    return ESP_OK;\r
+}\r
diff --git a/components/wear_levelling/WL_Ext_Safe.cpp b/components/wear_levelling/WL_Ext_Safe.cpp
new file mode 100755 (executable)
index 0000000..d77bcbe
--- /dev/null
@@ -0,0 +1,161 @@
+// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//     http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+#include "WL_Ext_Safe.h"\r
+#include <stdlib.h>\r
+#include "esp_log.h"\r
+\r
+static const char *TAG = "wl_ext_safe";\r
+\r
+#define WL_EXT_RESULT_CHECK(result) \\r
+    if (result != ESP_OK) { \\r
+        ESP_LOGE(TAG,"%s(%d): result = 0x%08x", __FUNCTION__, __LINE__, result); \\r
+        return (result); \\r
+    }\r
+\r
+#ifndef FLASH_ERASE_VALUE\r
+#define FLASH_ERASE_VALUE 0xffffffff\r
+#endif // FLASH_ERASE_VALUE\r
+\r
+\r
+#ifndef WL_EXT_SAFE_OK\r
+#define WL_EXT_SAFE_OK 0x12345678\r
+#endif // WL_EXT_SAFE_OK\r
+\r
+#ifndef WL_EXT_SAFE_OFFSET\r
+#define WL_EXT_SAFE_OFFSET 16\r
+#endif // WL_EXT_SAFE_OFFSET\r
+\r
+\r
+struct WL_Ext_Safe_State {\r
+public:\r
+    uint32_t erase_begin;\r
+    uint32_t local_addr_base;\r
+    uint32_t local_addr_shift;\r
+    uint32_t count;\r
+};\r
+\r
+WL_Ext_Safe::WL_Ext_Safe(): WL_Ext_Perf()\r
+{\r
+}\r
+\r
+WL_Ext_Safe::~WL_Ext_Safe()\r
+{\r
+}\r
+\r
+esp_err_t WL_Ext_Safe::config(WL_Config_s *cfg, Flash_Access *flash_drv)\r
+{\r
+    esp_err_t result = ESP_OK;\r
+\r
+    result = WL_Ext_Perf::config(cfg, flash_drv);\r
+    WL_EXT_RESULT_CHECK(result);\r
+    this->state_addr = WL_Flash::chip_size() - 2 * WL_Flash::sector_size();\r
+    this->dump_addr = WL_Flash::chip_size() - 1 * WL_Flash::sector_size();\r
+    return ESP_OK;\r
+}\r
+\r
+esp_err_t WL_Ext_Safe::init()\r
+{\r
+    esp_err_t result = ESP_OK;\r
+    ESP_LOGV(TAG, "%s", __func__);\r
+\r
+    result = WL_Ext_Perf::init();\r
+    WL_EXT_RESULT_CHECK(result);\r
+\r
+    result = this->recover();\r
+    return result;\r
+}\r
+\r
+size_t WL_Ext_Safe::chip_size()\r
+{\r
+    ESP_LOGV(TAG, "%s size = %i", __func__, WL_Flash::chip_size() - 2 * this->flash_sector_size);\r
+    return WL_Flash::chip_size() - 2 * this->flash_sector_size;\r
+}\r
+\r
+esp_err_t WL_Ext_Safe::recover()\r
+{\r
+    esp_err_t result = ESP_OK;\r
+\r
+    WL_Ext_Safe_State state;\r
+    result = WL_Flash::read(this->state_addr, &state, sizeof(WL_Ext_Safe_State));\r
+    WL_EXT_RESULT_CHECK(result);\r
+    ESP_LOGI(TAG, "%s recover, start_addr = 0x%08x, local_addr_base = 0x%08x, local_addr_shift = %i, count=%i", __func__, state.erase_begin, state.local_addr_base, state.local_addr_shift, state.count);\r
+\r
+    // check if we have transaction\r
+    if (state.erase_begin == WL_EXT_SAFE_OK) {\r
+\r
+        result = this->read(this->dump_addr, this->sector_buffer, this->flash_sector_size);\r
+        WL_EXT_RESULT_CHECK(result);\r
+\r
+        result = WL_Flash::erase_sector(state.local_addr_base); // erase comlete flash sector\r
+        WL_EXT_RESULT_CHECK(result);\r
+\r
+        // And write back...\r
+        for (int i = 0; i < this->size_factor; i++) {\r
+            if ((i < state.local_addr_shift) || (i >= state.count + state.local_addr_shift)) {\r
+                result = this->write(state.local_addr_base * this->flash_sector_size + i * this->fat_sector_size, &this->sector_buffer[i * this->fat_sector_size / sizeof(uint32_t)], this->fat_sector_size);\r
+                WL_EXT_RESULT_CHECK(result);\r
+            }\r
+        }\r
+        // clear transaction\r
+        result = WL_Flash::erase_range(this->state_addr, this->flash_sector_size);\r
+    }\r
+    return result;\r
+}\r
+\r
+esp_err_t WL_Ext_Safe::erase_sector_fit(uint32_t start_sector, uint32_t count)\r
+{\r
+    esp_err_t result = ESP_OK;\r
+\r
+    uint32_t local_addr_base = start_sector / this->size_factor;\r
+    uint32_t pre_check_start = start_sector % this->size_factor;\r
+    ESP_LOGV(TAG, "%s start_sector=0x%08x, count = %i", __func__, start_sector, count);\r
+    for (int i = 0; i < this->size_factor; i++) {\r
+        if ((i < pre_check_start) || (i >= count + pre_check_start)) {\r
+            result = this->read(start_sector / this->size_factor * this->flash_sector_size + i * this->fat_sector_size, &this->sector_buffer[i * this->fat_sector_size / sizeof(uint32_t)], this->fat_sector_size);\r
+            WL_EXT_RESULT_CHECK(result);\r
+        }\r
+    }\r
+\r
+    result = WL_Flash::erase_sector(this->dump_addr / this->flash_sector_size);\r
+    WL_EXT_RESULT_CHECK(result);\r
+    result = WL_Flash::write(this->dump_addr, this->sector_buffer, this->flash_sector_size);\r
+    WL_EXT_RESULT_CHECK(result);\r
+\r
+    WL_Ext_Safe_State state;\r
+    state.erase_begin = WL_EXT_SAFE_OK;\r
+    state.local_addr_base = local_addr_base;\r
+    state.local_addr_shift = pre_check_start;\r
+    state.count = count;\r
+\r
+    result = WL_Flash::erase_sector(this->state_addr / this->flash_sector_size);\r
+    WL_EXT_RESULT_CHECK(result);\r
+    result = WL_Flash::write(this->state_addr + 0, &state, sizeof(WL_Ext_Safe_State));\r
+    WL_EXT_RESULT_CHECK(result);\r
+\r
+    // Erase\r
+    result = WL_Flash::erase_sector(local_addr_base); // erase comlete flash sector\r
+    WL_EXT_RESULT_CHECK(result);\r
+    // And write back...\r
+    for (int i = 0; i < this->size_factor; i++) {\r
+        if ((i < pre_check_start) || (i >= count + pre_check_start)) {\r
+            result = this->write(local_addr_base * this->flash_sector_size + i * this->fat_sector_size, &this->sector_buffer[i * this->fat_sector_size / sizeof(uint32_t)], this->fat_sector_size);\r
+            WL_EXT_RESULT_CHECK(result);\r
+        }\r
+    }\r
+\r
+    result = WL_Flash::erase_sector(this->state_addr / this->flash_sector_size);\r
+    WL_EXT_RESULT_CHECK(result);\r
+\r
+    return ESP_OK;\r
+}\r
diff --git a/components/wear_levelling/private_include/WL_Ext_Cfg.h b/components/wear_levelling/private_include/WL_Ext_Cfg.h
new file mode 100755 (executable)
index 0000000..a82ba5f
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//     http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+#ifndef _WL_Ext_Cfg_H_\r
+#define _WL_Ext_Cfg_H_\r
+#include "WL_Config.h"\r
+\r
+typedef struct WL_Ext_Cfg_s : public WL_Config_s {\r
+    uint32_t fat_sector_size;   /*!< virtual sector size*/\r
+} wl_ext_cfg_t;\r
+\r
+#endif // _WL_Ext_Cfg_H_
\ No newline at end of file
diff --git a/components/wear_levelling/private_include/WL_Ext_Perf.h b/components/wear_levelling/private_include/WL_Ext_Perf.h
new file mode 100755 (executable)
index 0000000..63823d8
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//     http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+#ifndef _WL_Ext_Perf_H_\r
+#define _WL_Ext_Perf_H_\r
+\r
+#include "WL_Flash.h"\r
+#include "WL_Ext_Cfg.h"\r
+\r
+class WL_Ext_Perf : public WL_Flash\r
+{\r
+public:\r
+    WL_Ext_Perf();\r
+    ~WL_Ext_Perf() override;\r
+\r
+    esp_err_t config(WL_Config_s *cfg, Flash_Access *flash_drv) override;\r
+    esp_err_t init() override;\r
+\r
+    size_t chip_size() override;\r
+    size_t sector_size() override;\r
+\r
+\r
+    esp_err_t erase_sector(size_t sector) override;\r
+    esp_err_t erase_range(size_t start_address, size_t size) override;\r
+\r
+protected:\r
+    uint32_t flash_sector_size;\r
+    uint32_t fat_sector_size;\r
+    uint32_t size_factor;\r
+    uint32_t *sector_buffer;\r
+\r
+    virtual esp_err_t erase_sector_fit(uint32_t start_sector, uint32_t count);\r
+\r
+};\r
+\r
+#endif // _WL_Ext_Perf_H_
\ No newline at end of file
diff --git a/components/wear_levelling/private_include/WL_Ext_Safe.h b/components/wear_levelling/private_include/WL_Ext_Safe.h
new file mode 100755 (executable)
index 0000000..5c20371
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//     http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+#ifndef _WL_Ext_Safe_H_\r
+#define _WL_Ext_Safe_H_\r
+\r
+#include "WL_Flash.h"\r
+#include "WL_Ext_Cfg.h"\r
+#include "WL_Ext_Perf.h"\r
+\r
+class WL_Ext_Safe : public WL_Ext_Perf\r
+{\r
+public:\r
+    WL_Ext_Safe();\r
+    ~WL_Ext_Safe() override;\r
+\r
+    esp_err_t config(WL_Config_s *cfg, Flash_Access *flash_drv) override;\r
+    esp_err_t init() override;\r
+\r
+    size_t chip_size() override;\r
+\r
+protected:\r
+    esp_err_t erase_sector_fit(uint32_t start_sector, uint32_t count) override;\r
+\r
+    // Dump Sector\r
+    uint32_t dump_addr; // dump buffer address\r
+    uint32_t state_addr;// sectore where state of transaction will be stored\r
+\r
+    esp_err_t recover();\r
+};\r
+\r
+#endif // _WL_Ext_Safe_H_
\ No newline at end of file
index 4e581196b0981589890e94503a27b6f893aacba4..30d36ce2091e553114a5c22d83a4c5f37d9512d5 100644 (file)
 #include <sys/lock.h>\r
 #include "wear_levelling.h"\r
 #include "WL_Config.h"\r
+#include "WL_Ext_Cfg.h"\r
 #include "WL_Flash.h"\r
+#include "WL_Ext_Perf.h"\r
+#include "WL_Ext_Safe.h"\r
 #include "SPI_Flash.h"\r
 #include "Partition.h"\r
 \r
@@ -79,7 +82,7 @@ esp_err_t wl_mount(const esp_partition_t *partition, wl_handle_t *out_handle)
         goto out;\r
     }\r
 \r
-    wl_config_t cfg;\r
+    wl_ext_cfg_t cfg;\r
     cfg.full_mem_size = partition->size;\r
     cfg.start_addr = WL_DEFAULT_START_ADDR;\r
     cfg.version = WL_CURRENT_VERSION;\r
@@ -88,6 +91,8 @@ esp_err_t wl_mount(const esp_partition_t *partition, wl_handle_t *out_handle)
     cfg.updaterate = WL_DEFAULT_UPDATERATE;\r
     cfg.temp_buff_size = WL_DEFAULT_TEMP_BUFF_SIZE;\r
     cfg.wr_size = WL_DEFAULT_WRITE_SIZE;\r
+    // FAT sector size by default will be 512\r
+    cfg.fat_sector_size = CONFIG_WL_SECTOR_SIZE;\r
 \r
     // Allocate memory for a Partition object, and then initialize the object\r
     // using placement new operator. This way we can recover from out of\r
@@ -101,13 +106,37 @@ esp_err_t wl_mount(const esp_partition_t *partition, wl_handle_t *out_handle)
     part = new (part_ptr) Partition(partition);\r
 \r
     // Same for WL_Flash: allocate memory, use placement new\r
+#if CONFIG_WL_SECTOR_SIZE == 512\r
+#if CONFIG_WL_SECTOR_MODE == 1\r
+    wl_flash_ptr = malloc(sizeof(WL_Ext_Safe));\r
+\r
+    if (wl_flash_ptr == NULL) {\r
+        result = ESP_ERR_NO_MEM;\r
+        ESP_LOGE(TAG, "%s: can't allocate WL_Ext_Safe", __func__);\r
+        goto out;\r
+    }\r
+    wl_flash = new (wl_flash_ptr) WL_Ext_Safe();\r
+#else\r
+    wl_flash_ptr = malloc(sizeof(WL_Ext_Perf));\r
+\r
+    if (wl_flash_ptr == NULL) {\r
+        result = ESP_ERR_NO_MEM;\r
+        ESP_LOGE(TAG, "%s: can't allocate WL_Ext_Perf", __func__);\r
+        goto out;\r
+    }\r
+    wl_flash = new (wl_flash_ptr) WL_Ext_Perf();\r
+#endif // CONFIG_WL_SECTOR_MODE\r
+#endif // CONFIG_WL_SECTOR_SIZE\r
+#if CONFIG_WL_SECTOR_SIZE == 4096\r
     wl_flash_ptr = malloc(sizeof(WL_Flash));\r
+\r
     if (wl_flash_ptr == NULL) {\r
         result = ESP_ERR_NO_MEM;\r
         ESP_LOGE(TAG, "%s: can't allocate WL_Flash", __func__);\r
         goto out;\r
     }\r
     wl_flash = new (wl_flash_ptr) WL_Flash();\r
+#endif // CONFIG_WL_SECTOR_SIZE\r
 \r
     result = wl_flash->config(&cfg, part);\r
     if (ESP_OK != result) {\r