--- /dev/null
+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
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.
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
#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
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
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
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