From: Renz Bagaporo Date: Thu, 17 May 2018 10:56:52 +0000 (+0800) Subject: wl, spi_flash: Make wl API runnable on host X-Git-Tag: v3.1-beta1~41^2~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=893003357ad31d0dc8838a6652f29caa800ebfa4;p=esp-idf wl, spi_flash: Make wl API runnable on host Makes the entirety of the wl API runnable on host. Flash emulator is separated into spi_flash component directory to be reused by other storage components. --- diff --git a/components/fatfs/test_fatfs_host/Makefile b/components/fatfs/test_fatfs_host/Makefile new file mode 100644 index 0000000000..5b6d7a6e52 --- /dev/null +++ b/components/fatfs/test_fatfs_host/Makefile @@ -0,0 +1,45 @@ +TEST_PROGRAM=fatfs_host + +all: $(TEST_PROGRAM) + +SOURCE_FILES = \ + main.c \ + $(addprefix ../src/, \ + diskio.c \ + ff.c \ + ffsystem.c \ + ffunicode.c \ + ) + +INCLUDE_FLAGS = $(addprefix -I,\ + ../src \ + . \ + $(addprefix ./stubs/, \ + driver/include \ + freertos/include \ + sdmmc/include \ + ) \ + ../../esp32/include \ +) + +CPPFLAGS += $(INCLUDE_FLAGS) -g +CFLAGS += -fprofile-arcs -g +CXXFLAGS += -std=c++11 -Wall -Werror -fprofile-arcs -g +LDFLAGS += -lstdc++ -fprofile-arcs + +OBJ_FILES = $(SOURCE_FILES:.c=.o) +$(OBJ_FILES): %.o: %.c + +$(TEST_PROGRAM): $(OBJ_FILES) + gcc $(LDFLAGS) -o $(TEST_PROGRAM) $(OBJ_FILES) + +$(TEST_PROGRAM): $(OBJ_FILES) $(TEST_WL_DIR)/$(TEST_WL_LIB) $(TEST_PARTITION_SIM_DIR)/$(TEST_PARTITION_SIM_LIB) + g++ $(LDFLAGS) -o $(TEST_PROGRAM) $(OBJ_FILES) -L$(TEST_PARTITION_SIM_DIR) -l:$(TEST_PARTITION_SIM_LIB) -L$(TEST_WL_DIR) -l:$(TEST_WL_LIB) + +test: $(TEST_PROGRAM) + ./$(TEST_PROGRAM) + +clean: + rm -f $(OBJ_FILES) $(TEST_PROGRAM) + +.PHONY: clean all diff --git a/components/wear_levelling/test_wl_host/Flash_Emulator.cpp b/components/spi_flash/sim/Flash_Emulator.cpp similarity index 100% rename from components/wear_levelling/test_wl_host/Flash_Emulator.cpp rename to components/spi_flash/sim/Flash_Emulator.cpp diff --git a/components/wear_levelling/test_wl_host/Flash_Emulator.h b/components/spi_flash/sim/Flash_Emulator.h similarity index 92% rename from components/wear_levelling/test_wl_host/Flash_Emulator.h rename to components/spi_flash/sim/Flash_Emulator.h index 02a1be9825..30b3e6ac1a 100644 --- a/components/wear_levelling/test_wl_host/Flash_Emulator.h +++ b/components/spi_flash/sim/Flash_Emulator.h @@ -16,12 +16,12 @@ #define _Flash_Emulator_H_ #include "esp_err.h" -#include "Flash_Access.h" + /** * @brief This class is used to emulate flash devices. Class implements Flash_Access interface * */ -class Flash_Emulator : public Flash_Access +class Flash_Emulator { public: diff --git a/components/spi_flash/sim/Makefile b/components/spi_flash/sim/Makefile new file mode 100644 index 0000000000..6a9992f081 --- /dev/null +++ b/components/spi_flash/sim/Makefile @@ -0,0 +1,47 @@ +PARTITION_SIM=partition_sim +PARTITION_SIM_LIB=lib$(PARTITION_SIM).a + +lib: $(PARTITION_SIM_LIB) + +SOURCE_FILES = \ + Flash_Emulator.cpp \ + partition.c + +INCLUDE_FLAGS = $(addprefix -I,\ + . \ + ./include \ + ../../esp32/include/ \ +) + +GCOV ?= gcov + +CPPFLAGS += $(INCLUDE_FLAGS) -D CONFIG_LOG_DEFAULT_LEVEL -g +CFLAGS += -fprofile-arcs -ftest-coverage +CXXFLAGS += -std=c++11 -Wall -Werror -fprofile-arcs -ftest-coverage +LDFLAGS += -lstdc++ -fprofile-arcs -ftest-coverage + +OBJ_FILES = $(filter %.o, $(SOURCE_FILES:.cpp=.o) $(SOURCE_FILES:.c=.o)) + + +$(PARTITION_SIM_LIB): $(OBJ_FILES) + $(AR) rcs $@ $^ + +COVERAGE_FILES = $(OBJ_FILES:.o=.gc*) $(OBJ_FILES:.o=.gc*) + +$(COVERAGE_FILES): $(TEST_PROGRAM) lib + +coverage.info: $(COVERAGE_FILES) + find ../ -name "*.gcno" -exec $(GCOV) -r -pb {} + + lcov --capture --directory ../ --no-external --output-file coverage.info --gcov-tool $(GCOV) + +coverage_report: coverage.info + genhtml coverage.info --output-directory coverage_report + @echo "Coverage report is in coverage_report/index.html" + +clean: + rm -f $(OBJ_FILES) $(PARTITION_SIM_LIB) + rm -f $(COVERAGE_FILES) *.gcov + rm -rf coverage_report/ + rm -f coverage.info + +.PHONY: clean lib diff --git a/components/spi_flash/sim/include/esp_partition.h b/components/spi_flash/sim/include/esp_partition.h new file mode 100644 index 0000000000..c69df023d6 --- /dev/null +++ b/components/spi_flash/sim/include/esp_partition.h @@ -0,0 +1,85 @@ +#pragma once + +#include + +#include "esp_err.h" +#include "esp_spi_flash.h" + +/** + * @brief Partition type + * @note Keep this enum in sync with PartitionDefinition class gen_esp32part.py + */ +typedef enum { + ESP_PARTITION_TYPE_APP = 0x00, //!< Application partition type + ESP_PARTITION_TYPE_DATA = 0x01, //!< Data partition type +} esp_partition_type_t; + +/** + * @brief Partition subtype + * @note Keep this enum in sync with PartitionDefinition class gen_esp32part.py + */ +typedef enum { + ESP_PARTITION_SUBTYPE_APP_FACTORY = 0x00, //!< Factory application partition + ESP_PARTITION_SUBTYPE_APP_OTA_MIN = 0x10, //!< Base for OTA partition subtypes + ESP_PARTITION_SUBTYPE_APP_OTA_0 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 0, //!< OTA partition 0 + ESP_PARTITION_SUBTYPE_APP_OTA_1 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 1, //!< OTA partition 1 + ESP_PARTITION_SUBTYPE_APP_OTA_2 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 2, //!< OTA partition 2 + ESP_PARTITION_SUBTYPE_APP_OTA_3 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 3, //!< OTA partition 3 + ESP_PARTITION_SUBTYPE_APP_OTA_4 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 4, //!< OTA partition 4 + ESP_PARTITION_SUBTYPE_APP_OTA_5 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 5, //!< OTA partition 5 + ESP_PARTITION_SUBTYPE_APP_OTA_6 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 6, //!< OTA partition 6 + ESP_PARTITION_SUBTYPE_APP_OTA_7 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 7, //!< OTA partition 7 + ESP_PARTITION_SUBTYPE_APP_OTA_8 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 8, //!< OTA partition 8 + ESP_PARTITION_SUBTYPE_APP_OTA_9 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 9, //!< OTA partition 9 + ESP_PARTITION_SUBTYPE_APP_OTA_10 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 10,//!< OTA partition 10 + ESP_PARTITION_SUBTYPE_APP_OTA_11 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 11,//!< OTA partition 11 + ESP_PARTITION_SUBTYPE_APP_OTA_12 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 12,//!< OTA partition 12 + ESP_PARTITION_SUBTYPE_APP_OTA_13 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 13,//!< OTA partition 13 + ESP_PARTITION_SUBTYPE_APP_OTA_14 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 14,//!< OTA partition 14 + ESP_PARTITION_SUBTYPE_APP_OTA_15 = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 15,//!< OTA partition 15 + ESP_PARTITION_SUBTYPE_APP_OTA_MAX = ESP_PARTITION_SUBTYPE_APP_OTA_MIN + 16,//!< Max subtype of OTA partition + ESP_PARTITION_SUBTYPE_APP_TEST = 0x20, //!< Test application partition + + ESP_PARTITION_SUBTYPE_DATA_OTA = 0x00, //!< OTA selection partition + ESP_PARTITION_SUBTYPE_DATA_PHY = 0x01, //!< PHY init data partition + ESP_PARTITION_SUBTYPE_DATA_NVS = 0x02, //!< NVS partition + ESP_PARTITION_SUBTYPE_DATA_COREDUMP = 0x03, //!< COREDUMP partition + + ESP_PARTITION_SUBTYPE_DATA_ESPHTTPD = 0x80, //!< ESPHTTPD partition + ESP_PARTITION_SUBTYPE_DATA_FAT = 0x81, //!< FAT partition + ESP_PARTITION_SUBTYPE_DATA_SPIFFS = 0x82, //!< SPIFFS partition + + ESP_PARTITION_SUBTYPE_ANY = 0xff, //!< Used to search for partitions with any subtype +} esp_partition_subtype_t; + +/** + * @brief partition information structure + * + * This is not the format in flash, that format is esp_partition_info_t. + * + * However, this is the format used by this API. + */ +typedef struct { + esp_partition_type_t type; /*!< partition type (app/data) */ + esp_partition_subtype_t subtype; /*!< partition subtype */ + uint32_t address; /*!< starting address of the partition in flash */ + uint32_t size; /*!< size of the partition, in bytes */ + char label[17]; /*!< partition label, zero-terminated ASCII string */ + bool encrypted; /*!< flag is set to true if partition is encrypted */ + + int handle; /*!< simulator handle */ +} esp_partition_t; + +esp_err_t esp_partition_write(const esp_partition_t* partition, + size_t dst_offset, const void* src, size_t size); + +esp_err_t esp_partition_erase_range(const esp_partition_t* partition, + uint32_t start_addr, uint32_t size); + +esp_err_t esp_partition_read(const esp_partition_t* partition, + size_t src_offset, void* dst, size_t size); + +esp_partition_t esp_partition_create(uint32_t size, uint32_t start); + +void esp_partition_delete(esp_partition_t partition); + diff --git a/components/spi_flash/sim/include/esp_spi_flash.h b/components/spi_flash/sim/include/esp_spi_flash.h new file mode 100644 index 0000000000..9e0009d038 --- /dev/null +++ b/components/spi_flash/sim/include/esp_spi_flash.h @@ -0,0 +1,7 @@ +#pragma once + +#define CONFIG_WL_SECTOR_SIZE 4096 + +#define SPI_FLASH_SEC_SIZE CONFIG_WL_SECTOR_SIZE +#define SPI_FLASH_WRITE_SIZE 16 + diff --git a/components/spi_flash/sim/partition.cpp b/components/spi_flash/sim/partition.cpp new file mode 100644 index 0000000000..e9568c0b0d --- /dev/null +++ b/components/spi_flash/sim/partition.cpp @@ -0,0 +1,63 @@ +#include + +#include "esp_partition.h" +#include "esp_spi_flash.h" +#include "Flash_Emulator.h" + +#define PARTITIONS_MAX 8 + +static Flash_Emulator* emulators[PARTITIONS_MAX]; + +esp_partition_t esp_partition_create(uint32_t size, uint32_t start) +{ + int handle = -1; + + for (int i = 0; i < PARTITIONS_MAX; i++) { + if (emulators[i] == NULL) { + emulators[i] = new Flash_Emulator(start + size, SPI_FLASH_SEC_SIZE, SPI_FLASH_WRITE_SIZE); + handle = i; + break; + } + } + + assert(handle != -1); + + esp_partition_t partition; + + // Fills partition with default values, and attaches the flash_emulator reference + // to the struct + partition.type = ESP_PARTITION_TYPE_DATA; + partition.subtype = ESP_PARTITION_SUBTYPE_DATA_FAT; + partition.address = start; + partition.size = size; + partition.handle = handle; + + return partition; +} + +void esp_partition_delete(esp_partition_t partition) +{ + delete emulators[partition.handle]; + emulators[partition.handle] = NULL; +} + +esp_err_t esp_partition_write(const esp_partition_t* partition, + size_t dst_offset, const void* src, size_t size) +{ + emulators[partition->handle]->write(dst_offset, src, size); + return ESP_OK; +} + +esp_err_t esp_partition_erase_range(const esp_partition_t* partition, + uint32_t start_addr, uint32_t size) +{ + emulators[partition->handle]->erase_range(start_addr, size); + return ESP_OK; +} + +esp_err_t esp_partition_read(const esp_partition_t* partition, + size_t src_offset, void* dst, size_t size) +{ + emulators[partition->handle]->read(src_offset, dst, size); + return ESP_OK; +} \ No newline at end of file diff --git a/components/spi_flash/sim/sdkconfig.h b/components/spi_flash/sim/sdkconfig.h new file mode 100644 index 0000000000..7b9637ef9c --- /dev/null +++ b/components/spi_flash/sim/sdkconfig.h @@ -0,0 +1 @@ +#pragma once \ No newline at end of file diff --git a/components/wear_levelling/Partition.cpp b/components/wear_levelling/Partition.cpp index 63fef6ed6b..e23f7fefd9 100644 --- a/components/wear_levelling/Partition.cpp +++ b/components/wear_levelling/Partition.cpp @@ -31,6 +31,7 @@ esp_err_t Partition::erase_sector(size_t sector) result = erase_range(sector * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE); return result; } + esp_err_t Partition::erase_range(size_t start_address, size_t size) { esp_err_t result = esp_partition_erase_range(this->partition, start_address, size); @@ -48,6 +49,7 @@ esp_err_t Partition::write(size_t dest_addr, const void *src, size_t size) result = esp_partition_write(this->partition, dest_addr, src, size); return result; } + esp_err_t Partition::read(size_t src_addr, void *dest, size_t size) { esp_err_t result = ESP_OK; diff --git a/components/wear_levelling/test_wl_host/Makefile b/components/wear_levelling/test_wl_host/Makefile index e71187180c..dc36a97c15 100644 --- a/components/wear_levelling/test_wl_host/Makefile +++ b/components/wear_levelling/test_wl_host/Makefile @@ -1,54 +1,77 @@ TEST_PROGRAM=test_wl + +# Expose as a library for FS components that require wear_levelling +TEST_LIB=lib$(TEST_PROGRAM).a + +# Use simulated block device +TEST_PARTITION_SIM_DIR=$(IDF_PATH)/components/spi_flash/sim +TEST_PARTITION_SIM_LIB=libpartition_sim.a + all: $(TEST_PROGRAM) -SOURCE_FILES = \ - esp_error_check_stub.cpp \ +LIB_SOURCE_FILES = \ + $(addprefix stubs/, \ + newlib/lock.c \ + log/log.c \ + esp32/crc.cpp \ + ) \ $(addprefix ../, \ - crc32.cpp \ - WL_Flash.cpp \ - ../nvs_flash/test_nvs_host/crc.cpp\ + wear_levelling.cpp \ + crc32.cpp \ + WL_Flash.cpp \ + Partition.cpp \ ) \ - Flash_Emulator.cpp \ - wl_tests_host.cpp \ - TestPowerDown.cpp \ - esp_log_stub.cpp \ - main.cpp +TEST_SOURCE_FILES = \ + test_wl.cpp \ + main.cpp INCLUDE_FLAGS = $(addprefix -I,\ + . \ ../ \ ../include \ ../private_include \ + $(addprefix stubs/, \ + esp32/include \ + newlib/include \ + log/include \ + ) \ ../../esp32/include \ - ../../soc/esp32/include \ - ../../log/include \ - ../../spi_flash/include \ - ../../nvs_flash/test_nvs_host \ + ../../spi_flash/sim/include \ ../../../tools/catch \ -) +) GCOV ?= gcov -CPPFLAGS += $(INCLUDE_FLAGS) -D CONFIG_LOG_DEFAULT_LEVEL +CPPFLAGS += $(INCLUDE_FLAGS) -D CONFIG_LOG_DEFAULT_LEVEL -g CFLAGS += -fprofile-arcs -ftest-coverage CXXFLAGS += -std=c++11 -Wall -Werror -fprofile-arcs -ftest-coverage LDFLAGS += -lstdc++ -fprofile-arcs -ftest-coverage -OBJ_FILES = $(SOURCE_FILES:.cpp=.o) +LIB_OBJ_FILES = $(filter %.o, $(LIB_SOURCE_FILES:.cpp=.o) $(LIB_SOURCE_FILES:.c=.o)) +TEST_OBJ_FILES = $(filter %.o, $(TEST_SOURCE_FILES:.cpp=.o) $(TEST_SOURCE_FILES:.c=.o)) -COVERAGE_FILES = $(OBJ_FILES:.o=.gc*) +$(TEST_PARTITION_SIM_DIR)/$(TEST_PARTITION_SIM_LIB): force + $(MAKE) -C $(TEST_PARTITION_SIM_DIR) lib -$(OBJ_FILES): %.o: %.cpp +$(TEST_LIB): $(LIB_OBJ_FILES) + $(AR) rcs $@ $^ -$(TEST_PROGRAM): $(OBJ_FILES) - g++ $(LDFLAGS) -o $(TEST_PROGRAM) $(OBJ_FILES) +lib: $(TEST_LIB) -$(OUTPUT_DIR): - mkdir -p $(OUTPUT_DIR) +$(TEST_PROGRAM): lib $(TEST_OBJ_FILES) $(TEST_PARTITION_SIM_DIR)/$(TEST_PARTITION_SIM_LIB) + g++ $(LDFLAGS) -o $@ $(TEST_OBJ_FILES) -L$(abspath .) -l:$(TEST_LIB) -L$(TEST_PARTITION_SIM_DIR) -l:$(TEST_PARTITION_SIM_LIB) + +force: test: $(TEST_PROGRAM) ./$(TEST_PROGRAM) +$(OUTPUT_DIR): + mkdir -p $(OUTPUT_DIR) + +COVERAGE_FILES = $(LIB_OBJ_FILES:.o=.gc*) $(TEST_OBJ_FILES:.o=.gc*) + $(COVERAGE_FILES): $(TEST_PROGRAM) test coverage.info: $(COVERAGE_FILES) @@ -60,9 +83,10 @@ coverage_report: coverage.info @echo "Coverage report is in coverage_report/index.html" clean: - rm -f $(OBJ_FILES) $(TEST_PROGRAM) + $(MAKE) -C $(TEST_PARTITION_SIM_DIR) clean + rm -f $(LIB_OBJ_FILES) $(TEST_OBJ_FILES) $(TEST_PROGRAM) $(TEST_LIB) rm -f $(COVERAGE_FILES) *.gcov rm -rf coverage_report/ rm -f coverage.info -.PHONY: clean all test +.PHONY: clean all test lib diff --git a/components/wear_levelling/test_wl_host/TestPowerDown.cpp b/components/wear_levelling/test_wl_host/TestPowerDown.cpp deleted file mode 100644 index 056d815a12..0000000000 --- a/components/wear_levelling/test_wl_host/TestPowerDown.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -#include "WL_Config.h" -#include "WL_Flash.h" -#include "Flash_Emulator.h" -#ifdef _MSC_VER -#define CHECK(m) -#else -#include "catch.hpp" -#endif - -extern Flash_Access *s_flash; - -bool test_power_down(WL_Flash *wl_flash, Flash_Emulator *emul, uint32_t used_sectors_count) -{ - REQUIRE(wl_flash->init() == ESP_OK); - s_flash = wl_flash; - - uint32_t add_const = 0; - int32_t sectors_count = s_flash->chip_size() / s_flash->sector_size(); - esp_err_t err = ESP_OK; - uint32_t *sector_data = new uint32_t[s_flash->sector_size() / sizeof(uint32_t)]; - - for (int32_t i = 0; i < sectors_count; i++) { - REQUIRE(s_flash->erase_sector(i) == ESP_OK); - for (uint32_t m = 0; m < s_flash->sector_size() / sizeof(uint32_t); m++) { - uint32_t temp_data = i * s_flash->sector_size() + add_const + m; - sector_data[m] = temp_data; - } - REQUIRE(s_flash->write(i * s_flash->sector_size(), sector_data, s_flash->sector_size()) == ESP_OK); - } - for (int32_t i = 0; i < sectors_count; i++) { - err |= s_flash->read(i * s_flash->sector_size(), sector_data, s_flash->sector_size()); - for (uint32_t m = 0; m < s_flash->sector_size() / sizeof(uint32_t); m++) { - uint32_t temp_data = i * s_flash->sector_size() + add_const + m; - REQUIRE(temp_data == sector_data[m]); - if (temp_data != sector_data[m]) { - printf("Error - read: %08x, expected %08x\n", sector_data[m], temp_data); - } - } - } - - int32_t max_count = 100; - int32_t max_check_count = used_sectors_count; - printf("used_sectors_count=%d\n", used_sectors_count); - for (int32_t k = 0; k < max_check_count; k++) { - - emul->SetResetCount(max_count); - int32_t err_sector = -1; - for (int32_t i = 0; i < sectors_count; i++) { - err = ESP_OK; - err = s_flash->erase_sector(i); - if (err != ESP_OK) { - err_sector = i; - break; - } - for (uint32_t m = 0; m < s_flash->sector_size() / sizeof(uint32_t); m++) { - uint32_t temp_data = i * s_flash->sector_size() + add_const + m; - sector_data[m] = temp_data; - } - err = s_flash->write(i * s_flash->sector_size(), sector_data, s_flash->sector_size()); - if (err != ESP_OK) { - err_sector = i; - break; - } - } - if (err_sector >= 0) { - max_count++; - } else { - max_count = 0; - } - emul->SetResetCount(INT32_MAX); - REQUIRE(wl_flash->init() == ESP_OK); - for (int32_t i = 0; i < sectors_count; i++) { - if (i != err_sector) { - err |= s_flash->read(i * s_flash->sector_size(), sector_data, s_flash->sector_size()); - for (uint32_t m = 0; m < s_flash->sector_size() / sizeof(uint32_t); m++) { - uint32_t temp_data = i * s_flash->sector_size() + add_const + m; - REQUIRE(temp_data == sector_data[m]); - if (temp_data != sector_data[m]) { - printf("Error - read: %08x, expected %08x, m=%i, sector=%i\n", sector_data[m], temp_data, m, i); - } - } - } - } - if (err_sector != -1) { - err |= s_flash->erase_sector(err_sector); - for (uint32_t m = 0; m < s_flash->sector_size() / sizeof(uint32_t); m++) { - uint32_t temp_data = err_sector * s_flash->sector_size() + add_const + m; - sector_data[m] = temp_data; - } - err |= s_flash->write(err_sector * s_flash->sector_size(), sector_data, s_flash->sector_size()); - } - printf("[%3.f%%] err_sector=%i\n", (float)k / ((float)max_check_count) * 100.0f, err_sector); - } - delete[] sector_data; - return true; -} diff --git a/components/wear_levelling/test_wl_host/sdkconfig.h b/components/wear_levelling/test_wl_host/sdkconfig.h index e69de29bb2..3f59c932d3 100644 --- a/components/wear_levelling/test_wl_host/sdkconfig.h +++ b/components/wear_levelling/test_wl_host/sdkconfig.h @@ -0,0 +1,2 @@ +#pragma once + diff --git a/components/wear_levelling/test_wl_host/stubs/esp32/crc.cpp b/components/wear_levelling/test_wl_host/stubs/esp32/crc.cpp new file mode 100644 index 0000000000..9e24735604 --- /dev/null +++ b/components/wear_levelling/test_wl_host/stubs/esp32/crc.cpp @@ -0,0 +1,50 @@ +#include +#include + +#include "rom/crc.h" + +static const unsigned int crc32_le_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, + 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, + 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, + 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, + 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, + 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, + 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, + 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, + 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, + 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, + 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, + 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, + 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, + + 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, + 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, + 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, + 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, + 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, + 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, + 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, + 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, + 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, + 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, + 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, + 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, + 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL +}; + +extern "C" unsigned int crc32_le(uint32_t crc, const uint8_t* buf, size_t len) +{ + unsigned int i; + crc = ~crc; + for(i=0;i>8); + } + return ~crc; +} \ No newline at end of file diff --git a/components/wear_levelling/test_wl_host/stubs/esp32/include/rom/crc.h b/components/wear_levelling/test_wl_host/stubs/esp32/include/rom/crc.h new file mode 100644 index 0000000000..41364ee5a5 --- /dev/null +++ b/components/wear_levelling/test_wl_host/stubs/esp32/include/rom/crc.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t crc32_le(uint32_t crc, const uint8_t* buf, size_t len); + +#ifdef __cplusplus +} +#endif + diff --git a/components/wear_levelling/test_wl_host/stubs/esp32/include/rom/spi_flash.h b/components/wear_levelling/test_wl_host/stubs/esp32/include/rom/spi_flash.h new file mode 100644 index 0000000000..b9c14ef01f --- /dev/null +++ b/components/wear_levelling/test_wl_host/stubs/esp32/include/rom/spi_flash.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +typedef struct { + uint32_t device_id; + uint32_t chip_size; // chip size in bytes + uint32_t block_size; + uint32_t sector_size; + uint32_t page_size; + uint32_t status_mask; +} esp_rom_spiflash_chip_t; diff --git a/components/wear_levelling/test_wl_host/stubs/log/include/esp_log.h b/components/wear_levelling/test_wl_host/stubs/log/include/esp_log.h new file mode 100644 index 0000000000..a1d838d116 --- /dev/null +++ b/components/wear_levelling/test_wl_host/stubs/log/include/esp_log.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG + +typedef enum { + ESP_LOG_NONE, /*!< No log output */ + ESP_LOG_ERROR, /*!< Critical errors, software module can not recover on its own */ + ESP_LOG_WARN, /*!< Error conditions from which recovery measures have been taken */ + ESP_LOG_INFO, /*!< Information messages which describe normal flow of events */ + ESP_LOG_DEBUG, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */ + ESP_LOG_VERBOSE /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */ +} esp_log_level_t; + +#define LOG_COLOR_E +#define LOG_COLOR_W +#define LOG_COLOR_I +#define LOG_COLOR_D +#define LOG_COLOR_V +#define LOG_RESET_COLOR + +uint32_t esp_log_timestamp(void); +void esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...) __attribute__ ((format (printf, 3, 4))); + +#define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%d) %s: " format LOG_RESET_COLOR "\n" + +#define ESP_LOGE( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_ERROR) { esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } + +#define ESP_LOGV( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_VERBOSE) { esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } + +#define ESP_LOGD( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } + +#define ESP_LOGW( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_WARN) { esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } + +#ifdef __cplusplus +} +#endif + diff --git a/components/wear_levelling/test_wl_host/esp_log_stub.cpp b/components/wear_levelling/test_wl_host/stubs/log/log.c similarity index 83% rename from components/wear_levelling/test_wl_host/esp_log_stub.cpp rename to components/wear_levelling/test_wl_host/stubs/log/log.c index 87dd12a902..5d606d357f 100644 --- a/components/wear_levelling/test_wl_host/esp_log_stub.cpp +++ b/components/wear_levelling/test_wl_host/stubs/log/log.c @@ -1,4 +1,8 @@ #include +#include +#include +#include + #include "esp_log.h" void esp_log_write(esp_log_level_t level, @@ -15,3 +19,4 @@ uint32_t esp_log_timestamp() { return 0; } + diff --git a/components/wear_levelling/test_wl_host/stubs/newlib/include/sys/lock.h b/components/wear_levelling/test_wl_host/stubs/newlib/include/sys/lock.h new file mode 100644 index 0000000000..2b5b9f59ec --- /dev/null +++ b/components/wear_levelling/test_wl_host/stubs/newlib/include/sys/lock.h @@ -0,0 +1,17 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int _lock_t; + +void _lock_acquire(_lock_t *lock); +void _lock_close(_lock_t *lock); +void _lock_init(_lock_t *lock); +void _lock_release(_lock_t *lock); + +#ifdef __cplusplus +} +#endif + diff --git a/components/wear_levelling/test_wl_host/stubs/newlib/lock.c b/components/wear_levelling/test_wl_host/stubs/newlib/lock.c new file mode 100644 index 0000000000..f221fdbda1 --- /dev/null +++ b/components/wear_levelling/test_wl_host/stubs/newlib/lock.c @@ -0,0 +1,21 @@ +#include "sys/lock.h" + +void _lock_acquire(_lock_t *lock) +{ + return; +} + +void _lock_close(_lock_t *lock) +{ + return; +} + +void _lock_init(_lock_t *lock) +{ + return; +} + +void _lock_release(_lock_t *lock) +{ + return; +} diff --git a/components/wear_levelling/test_wl_host/test_wl.cpp b/components/wear_levelling/test_wl_host/test_wl.cpp new file mode 100644 index 0000000000..b2ed120b3f --- /dev/null +++ b/components/wear_levelling/test_wl_host/test_wl.cpp @@ -0,0 +1,94 @@ +// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include +#include +#include + +#include "esp_partition.h" +#include "wear_levelling.h" +#include "WL_Flash.h" + +#include "catch.hpp" + +extern "C" void init_spi_flash(size_t chip_size, size_t block_size, size_t sector_size, size_t page_size, const char* partition_bin); + +TEST_CASE("write and read back data", "[wear_levelling]") +{ + esp_err_t result; + wl_handle_t wl_handle; + + esp_partition_t partition = esp_partition_create(PARTITION_SIZE, PARTITION_START); + + // Mount wear-levelled partition + result = wl_mount(partition, &wl_handle); + REQUIRE(result == ESP_OK); + + // Get the sector size + uint32_t sector_size = wl_sector_size(wl_handle); + REQUIRE(sector_size == CONFIG_WL_SECTOR_SIZE); + + uint8_t* data = (uint8_t*) malloc(partition->size); + uint8_t* read = (uint8_t*) malloc(partition->size); + + uint32_t sectors = partition->size / sector_size; + + // Generate data + for(uint32_t sector = 0; sector < sectors; sector++) + { + uint32_t sector_address = sector * sector_size; + + for(uint32_t i = 0; i < sector_size / sizeof(i); i++) + { + ((uint32_t*) data)[i] = sector_address + i; + } + } + + // Write data + result = wl_write(wl_handle, 0, data, partition->size); + REQUIRE(result == ESP_OK); + + // Read data + result = wl_read(wl_handle, 0, read, partition->size); + REQUIRE(result == ESP_OK); + + // Verify that written and read data match + REQUIRE(memcmp(data, read, partition->size)); + + // Erase some ranges + result = wl_erase_range(wl_handle, 0, sector_size); + REQUIRE(result == ESP_OK); + result = wl_erase_range(wl_handle, 12288, sector_size * 2); + REQUIRE(result == ESP_OK); + result = wl_erase_range(wl_handle, 28672, sector_size * 3); + REQUIRE(result == ESP_OK); + + // Expected data after erasure + memset(data + 0, 0xFF, sector_size); + memset(data + 12288, 0xFF, sector_size * 2); + memset(data + 28672, 0xFF, sector_size * 3); + + // Read again, with erased ranges + result = wl_read(wl_handle, 0, read, partition->size); + REQUIRE(result == ESP_OK); + + // Verify that written and read data match + REQUIRE(memcmp(data, read, partition->size)); + + // Unmount + result = wl_unmount(wl_handle); + REQUIRE(result == ESP_OK); + + free(data); + free(read); +} \ No newline at end of file diff --git a/components/wear_levelling/test_wl_host/wl_tests_host.cpp b/components/wear_levelling/test_wl_host/wl_tests_host.cpp deleted file mode 100644 index 84bb59fea2..0000000000 --- a/components/wear_levelling/test_wl_host/wl_tests_host.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include "WL_Config.h" -#include "WL_Flash.h" -#include "Flash_Emulator.h" -#include "catch.hpp" - -#define FLASH_SECTOR_SIZE 512 -#define FLASH_USED_SECTOR (1024 - 3) -#define FLASH_ACCESS_SIZE (FLASH_SECTOR_SIZE*(FLASH_USED_SECTOR + 1 + 2)) -#define FLASH_START_ADDR 0x1000 -#define FLASH_PAGE_SIZE FLASH_SECTOR_SIZE*1 -#define FLASH_UPDATERATE 3 -#define FLASH_TEMP_SIZE FLASH_SECTOR_SIZE -#define FLASH_WR_BLOCK_SIZE 16 - -static const char *TAG = "wl_test_host"; -Flash_Access *s_flash; - -extern bool test_power_down(WL_Flash *wl_flash, Flash_Emulator *emul, uint32_t used_sectors_count); - -#define TEST_COUNT_MAX 100 - -TEST_CASE("flash starts with all bytes == 0xff", "[spi_flash_emu]") -{ - wl_config_t *wl = new wl_config_t(); - - wl->full_mem_size = FLASH_ACCESS_SIZE; - wl->start_addr = FLASH_START_ADDR; - wl->sector_size = FLASH_SECTOR_SIZE; - wl->page_size = FLASH_PAGE_SIZE; - wl->updaterate = FLASH_UPDATERATE; - wl->temp_buff_size = FLASH_TEMP_SIZE; - wl->wr_size = FLASH_WR_BLOCK_SIZE; - - WL_Flash *wl_flash = new WL_Flash(); - Flash_Emulator *emul = new Flash_Emulator(FLASH_ACCESS_SIZE + FLASH_START_ADDR, FLASH_SECTOR_SIZE, FLASH_WR_BLOCK_SIZE); - CHECK(wl_flash->config(wl, emul) == ESP_OK); - - test_power_down(wl_flash, emul, TEST_COUNT_MAX); -} - -