$(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)
-run: $(TEST_PROGRAM)
+test: $(TEST_PROGRAM)
./$(TEST_PROGRAM)
COVERAGE_FILES = $(OBJ_FILES:.o=.gc*) $(OBJ_FILES:.o=.gc*)
rm -rf coverage_report/
rm -f coverage.info
-.PHONY: clean all
+.PHONY: clean all test
uint32_t size = 0x00400000;
int flash_handle = esp_flash_create(size, 4096, 1);
esp_partition_t partition = esp_partition_create(size, 0, flash_handle);
-
+
// Mount wear-levelled partition
wl_handle_t wl_handle;
esp_result = wl_mount(&partition, &wl_handle);
fr_result = f_mount(0, "", 0);
REQUIRE(fr_result == FR_OK);
- esp_partition_delete(partition);
+ esp_flash_delete(flash_handle);
free(read);
-}
\ No newline at end of file
+}
this->buff = (uint8_t *)malloc(this->size);\r
this->access_count = new uint32_t[this->size / this->sector_sise];\r
memset(this->access_count, 0, this->size / this->sector_sise * sizeof(uint32_t));\r
+ memset(this->buff, 1, this->size);\r
}\r
\r
size_t Flash_Emulator::chip_size()\r
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);
+esp_partition_t esp_partition_create(uint32_t size, uint32_t start, int handle);
-void esp_partition_delete(esp_partition_t partition);
+int esp_flash_create(uint32_t size, uint32_t sector_size, uint32_t write_size);
+
+void esp_flash_delete(int handle);
#if defined(__cplusplus)
}
static Flash_Emulator* emulators[EMULATORS_MAX];
-esp_partition_t esp_partition_create(uint32_t size, uint32_t start)
-{
+int esp_flash_create(uint32_t size, uint32_t sector_size, uint32_t write_size)
+{
int handle = -1;
for (int i = 0; i < EMULATORS_MAX; i++) {
if (emulators[i] == NULL) {
- emulators[i] = new Flash_Emulator(start + size, SPI_FLASH_SEC_SIZE, SPI_FLASH_WRITE_SIZE);
+ emulators[i] = new Flash_Emulator(size, sector_size, write_size);
handle = i;
break;
}
assert(handle != -1);
+ return handle;
+}
+
+esp_partition_t esp_partition_create(uint32_t size, uint32_t start, int flash)
+{
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.subtype = ESP_PARTITION_SUBTYPE_ANY;
partition.address = start;
partition.size = size;
- partition.handle = handle;
+ partition.handle = flash;
return partition;
}
-void esp_partition_delete(esp_partition_t partition)
+void esp_flash_delete(int handle)
{
- delete emulators[partition.handle];
- emulators[partition.handle] = NULL;
+ delete emulators[handle];
+ emulators[handle] = NULL;
}
esp_err_t esp_partition_write(const esp_partition_t* partition,
{
emulators[partition->handle]->read(src_offset, dst, size);
return ESP_OK;
-}
\ No newline at end of file
+}
COMPONENT_ADD_INCLUDEDIRS := include
-COMPONENT_PRIV_INCLUDEDIRS := spiffs/src
+COMPONENT_PRIV_INCLUDEDIRS := . spiffs/src
COMPONENT_SRCDIRS := . spiffs/src
COMPONENT_SUBMODULES := spiffs
#include "esp_vfs.h"
#include "esp_err.h"
#include "rom/spi_flash.h"
-
-static const char * TAG = "SPIFFS";
+#include "spiffs_api.h"
#ifdef CONFIG_SPIFFS_USE_MTIME
_Static_assert(CONFIG_SPIFFS_META_LENGTH >= sizeof(time_t),
"SPIFFS_META_LENGTH size should be >= sizeof(time_t)");
#endif //CONFIG_SPIFFS_USE_MTIME
-/**
- * @brief SPIFFS definition structure
- */
-typedef struct {
- spiffs *fs; /*!< Handle to the underlying SPIFFS */
- SemaphoreHandle_t lock; /*!< FS lock */
- const esp_partition_t* partition; /*!< The partition on which SPIFFS is located */
- char base_path[ESP_VFS_PATH_MAX+1]; /*!< Mount point */
- bool by_label; /*!< Partition was mounted by label */
- spiffs_config cfg; /*!< SPIFFS Mount configuration */
- uint8_t *work; /*!< Work Buffer */
- uint8_t *fds; /*!< File Descriptor Buffer */
- uint32_t fds_sz; /*!< File Descriptor Buffer Length */
- uint8_t *cache; /*!< Cache Buffer */
- uint32_t cache_sz; /*!< Cache Buffer Length */
-} esp_spiffs_t;
/**
* @brief SPIFFS DIR structure
static esp_spiffs_t * _efs[CONFIG_SPIFFS_MAX_PARTITIONS];
-void spiffs_api_lock(spiffs *fs)
-{
- xSemaphoreTake(((esp_spiffs_t *)(fs->user_data))->lock, portMAX_DELAY);
-}
-
-void spiffs_api_unlock(spiffs *fs)
-{
- xSemaphoreGive(((esp_spiffs_t *)(fs->user_data))->lock);
-}
-
-static s32_t spiffs_api_read(spiffs *fs, uint32_t addr, uint32_t size, uint8_t *dst)
-{
- esp_err_t err = esp_partition_read(((esp_spiffs_t *)(fs->user_data))->partition,
- addr, dst, size);
- if (err) {
- ESP_LOGE(TAG, "failed to read addr %08x, size %08x, err %d", addr, size, err);
- return -1;
- }
- return 0;
-}
-
-static s32_t spiffs_api_write(spiffs *fs, uint32_t addr, uint32_t size, uint8_t *src)
-{
- esp_err_t err = esp_partition_write(((esp_spiffs_t *)(fs->user_data))->partition,
- addr, src, size);
- if (err) {
- ESP_LOGE(TAG, "failed to write addr %08x, size %08x, err %d", addr, size, err);
- return -1;
- }
- return 0;
-}
-
-static s32_t spiffs_api_erase(spiffs *fs, uint32_t addr, uint32_t size)
-{
- esp_err_t err = esp_partition_erase_range(((esp_spiffs_t *)(fs->user_data))->partition,
- addr, size);
- if (err) {
- ESP_LOGE(TAG, "failed to erase addr %08x, size %08x, err %d", addr, size, err);
- return -1;
- }
- return 0;
-}
-
-static void spiffs_api_check(spiffs *fs, spiffs_check_type type,
- spiffs_check_report report, uint32_t arg1, uint32_t arg2)
-{
- static const char * spiffs_check_type_str[3] = {
- "LOOKUP",
- "INDEX",
- "PAGE"
- };
-
- static const char * spiffs_check_report_str[7] = {
- "PROGRESS",
- "ERROR",
- "FIX INDEX",
- "FIX LOOKUP",
- "DELETE ORPHANED INDEX",
- "DELETE PAGE",
- "DELETE BAD FILE"
- };
-
- if (report != SPIFFS_CHECK_PROGRESS) {
- ESP_LOGE(TAG, "CHECK: type:%s, report:%s, %x:%x", spiffs_check_type_str[type],
- spiffs_check_report_str[report], arg1, arg2);
- } else {
- ESP_LOGV(TAG, "CHECK PROGRESS: report:%s, %x:%x",
- spiffs_check_report_str[report], arg1, arg2);
- }
-}
-
static void esp_spiffs_free(esp_spiffs_t ** efs)
{
esp_spiffs_t * e = *efs;
esp_partition_subtype_t subtype = conf->partition_label ?
ESP_PARTITION_SUBTYPE_ANY : ESP_PARTITION_SUBTYPE_DATA_SPIFFS;
- const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
+ const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
subtype, conf->partition_label);
if (!partition) {
ESP_LOGE(TAG, "spiffs partition could not be found");
efs->fs->user_data = (void *)efs;
efs->partition = partition;
- s32_t res = SPIFFS_mount(efs->fs, &efs->cfg, efs->work, efs->fds, efs->fds_sz,
+ s32_t res = SPIFFS_mount(efs->fs, &efs->cfg, efs->work, efs->fds, efs->fds_sz,
efs->cache, efs->cache_sz, spiffs_api_check);
if (conf->format_if_mount_failed && res != SPIFFS_OK) {
esp_spiffs_free(&efs);
return ESP_FAIL;
}
- res = SPIFFS_mount(efs->fs, &efs->cfg, efs->work, efs->fds, efs->fds_sz,
+ res = SPIFFS_mount(efs->fs, &efs->cfg, efs->work, efs->fds, efs->fds_sz,
efs->cache, efs->cache_sz, spiffs_api_check);
}
if (res != SPIFFS_OK) {
return out_dirent;
}
-static int vfs_spiffs_readdir_r(void* ctx, DIR* pdir, struct dirent* entry,
+static int vfs_spiffs_readdir_r(void* ctx, DIR* pdir, struct dirent* entry,
struct dirent** out_dirent)
{
assert(pdir);
--- /dev/null
+// 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 "freertos/FreeRTOS.h"
+#include "esp_log.h"
+#include "esp_partition.h"
+#include "esp_spiffs.h"
+#include "esp_vfs.h"
+#include "spiffs_api.h"
+
+const char* TAG = "SPIFFS";
+
+void spiffs_api_lock(spiffs *fs)
+{
+ xSemaphoreTake(((esp_spiffs_t *)(fs->user_data))->lock, portMAX_DELAY);
+}
+
+void spiffs_api_unlock(spiffs *fs)
+{
+ xSemaphoreGive(((esp_spiffs_t *)(fs->user_data))->lock);
+}
+
+s32_t spiffs_api_read(spiffs *fs, uint32_t addr, uint32_t size, uint8_t *dst)
+{
+ esp_err_t err = esp_partition_read(((esp_spiffs_t *)(fs->user_data))->partition,
+ addr, dst, size);
+ if (err) {
+ ESP_LOGE(TAG, "failed to read addr %08x, size %08x, err %d", addr, size, err);
+ return -1;
+ }
+ return 0;
+}
+
+s32_t spiffs_api_write(spiffs *fs, uint32_t addr, uint32_t size, uint8_t *src)
+{
+ esp_err_t err = esp_partition_write(((esp_spiffs_t *)(fs->user_data))->partition,
+ addr, src, size);
+ if (err) {
+ ESP_LOGE(TAG, "failed to write addr %08x, size %08x, err %d", addr, size, err);
+ return -1;
+ }
+ return 0;
+}
+
+s32_t spiffs_api_erase(spiffs *fs, uint32_t addr, uint32_t size)
+{
+ esp_err_t err = esp_partition_erase_range(((esp_spiffs_t *)(fs->user_data))->partition,
+ addr, size);
+ if (err) {
+ ESP_LOGE(TAG, "failed to erase addr %08x, size %08x, err %d", addr, size, err);
+ return -1;
+ }
+ return 0;
+}
+
+void spiffs_api_check(spiffs *fs, spiffs_check_type type,
+ spiffs_check_report report, uint32_t arg1, uint32_t arg2)
+{
+ static const char * spiffs_check_type_str[3] = {
+ "LOOKUP",
+ "INDEX",
+ "PAGE"
+ };
+
+ static const char * spiffs_check_report_str[7] = {
+ "PROGRESS",
+ "ERROR",
+ "FIX INDEX",
+ "FIX LOOKUP",
+ "DELETE ORPHANED INDEX",
+ "DELETE PAGE",
+ "DELETE BAD FILE"
+ };
+
+ if (report != SPIFFS_CHECK_PROGRESS) {
+ ESP_LOGE(TAG, "CHECK: type:%s, report:%s, %x:%x", spiffs_check_type_str[type],
+ spiffs_check_report_str[report], arg1, arg2);
+ } else {
+ ESP_LOGV(TAG, "CHECK PROGRESS: report:%s, %x:%x",
+ spiffs_check_report_str[report], arg1, arg2);
+ }
+}
--- /dev/null
+// 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.
+
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "spiffs.h"
+#include "esp_vfs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char* TAG;
+
+/**
+ * @brief SPIFFS definition structure
+ */
+typedef struct {
+ spiffs *fs; /*!< Handle to the underlying SPIFFS */
+ SemaphoreHandle_t lock; /*!< FS lock */
+ const esp_partition_t* partition; /*!< The partition on which SPIFFS is located */
+ char base_path[ESP_VFS_PATH_MAX+1]; /*!< Mount point */
+ bool by_label; /*!< Partition was mounted by label */
+ spiffs_config cfg; /*!< SPIFFS Mount configuration */
+ uint8_t *work; /*!< Work Buffer */
+ uint8_t *fds; /*!< File Descriptor Buffer */
+ uint32_t fds_sz; /*!< File Descriptor Buffer Length */
+ uint8_t *cache; /*!< Cache Buffer */
+ uint32_t cache_sz; /*!< Cache Buffer Length */
+} esp_spiffs_t;
+
+s32_t spiffs_api_read(spiffs *fs, uint32_t addr, uint32_t size, uint8_t *dst);
+
+s32_t spiffs_api_write(spiffs *fs, uint32_t addr, uint32_t size, uint8_t *src);
+
+s32_t spiffs_api_erase(spiffs *fs, uint32_t addr, uint32_t size);
+
+void spiffs_api_check(spiffs *fs, spiffs_check_type type,
+ spiffs_check_report report, uint32_t arg1, uint32_t arg2);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
--- /dev/null
+TEST_PROGRAM=test_spiffs
+
+TEST_PARTITION_SIM_DIR=$(IDF_PATH)/components/spi_flash/sim
+TEST_PARTITION_SIM_LIB=libpartition_sim.a
+
+all: $(TEST_PROGRAM)
+
+SOURCE_FILES = \
+ main.cpp \
+ test_spiffs.cpp \
+ ../spiffs_api.c \
+ $(addprefix ../spiffs/src/, \
+ spiffs_cache.c \
+ spiffs_check.c \
+ spiffs_gc.c \
+ spiffs_hydrogen.c \
+ spiffs_nucleus.c \
+ ) \
+ $(addprefix ./stubs/, \
+ log/log.c \
+ )
+
+INCLUDE_FLAGS = $(addprefix -I,\
+ . \
+ .. \
+ ../spiffs/src \
+ ../include \
+ $(addprefix ./stubs/, \
+ esp32/include \
+ log/include \
+ freertos/include \
+ newlib/include \
+ vfs/include \
+ ) \
+ ../../esp32/include \
+ $(TEST_PARTITION_SIM_DIR)/include \
+ ../../../tools/catch \
+)
+
+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))
+
+$(TEST_PARTITION_SIM_DIR)/$(TEST_PARTITION_SIM_LIB): force
+ $(MAKE) -C $(TEST_PARTITION_SIM_DIR) lib
+
+$(TEST_PROGRAM): $(OBJ_FILES) $(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)
+
+force:
+
+test: $(TEST_PROGRAM)
+ ./$(TEST_PROGRAM)
+
+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) $(TEST_PROGRAM) $(TEST_WL_LIB)
+ $(MAKE) -C $(TEST_PARTITION_SIM_DIR) clean
+ rm -f $(COVERAGE_FILES) *.gcov
+ rm -rf coverage_report/
+ rm -f coverage.info
+
+.PHONY: clean all test
--- /dev/null
+#define CATCH_CONFIG_MAIN
+#include "catch.hpp"
+
--- /dev/null
+#pragma once
+
+#define CONFIG_SPIFFS_USE_MAGIC_LENGTH 1
+#define CONFIG_SPIFFS_MAX_PARTITIONS 3
+#define CONFIG_SPIFFS_OBJ_NAME_LEN 32
+#define CONFIG_SPIFFS_PAGE_SIZE 256
+#define CONFIG_SPIFFS_GC_MAX_RUNS 10
+#define CONFIG_SPIFFS_CACHE_WR 1
+#define CONFIG_SPIFFS_CACHE 1
+#define CONFIG_SPIFFS_META_LENGTH 4
+#define CONFIG_SPIFFS_USE_MAGIC 1
+#define CONFIG_SPIFFS_PAGE_CHECK 1
+#define CONFIG_SPIFFS_USE_MTIME 1
+#define CONFIG_WL_SECTOR_SIZE 4096
--- /dev/null
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+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;
+
+extern esp_rom_spiflash_chip_t g_rom_flashchip;
+
+#if defined(__cplusplus)
+}
+#endif
\ No newline at end of file
--- /dev/null
+#pragma once
+
+#include "projdefs.h"
+#include "semphr.h"
--- /dev/null
+#pragma once
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define pdTRUE 1
+
+#if defined(__cplusplus)
+}
+#endif
--- /dev/null
+#pragma once
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define vSemaphoreDelete( xSemaphore )
+#define xSemaphoreCreateMutex() ((void*)(1))
+#define xSemaphoreGive( xSemaphore )
+#define xSemaphoreTake( xSemaphore, xBlockTime ) pdTRUE
+
+typedef void* SemaphoreHandle_t;
+
+#if defined(__cplusplus)
+}
+#endif
--- /dev/null
+#pragma once
\ No newline at end of file
--- /dev/null
+#pragma once
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "sdkconfig.h"
+
+#define strlcpy(a, b, c)
+#define strlcat(a, b, c)
+
+#if defined(__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
+
+#undef _Static_assert
+#define _Static_assert(cond, message)
+
+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__); }
+
+#if defined(__cplusplus)
+}
+#endif
\ No newline at end of file
--- /dev/null
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "esp_log.h"
+
+void esp_log_write(esp_log_level_t level,
+ const char *tag,
+ const char *format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ vprintf(format, arg);
+ va_end(arg);
+}
+
+uint32_t esp_log_timestamp()
+{
+ return 0;
+}
+
--- /dev/null
+#pragma once
+
+#include <time.h>
+
+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);
--- /dev/null
+#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;
+}
--- /dev/null
+#pragma once
+
+#include "esp_err.h"
+
+#define ESP_VFS_FLAG_CONTEXT_PTR 1
+#define ESP_VFS_PATH_MAX 15
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "esp_partition.h"
+#include "spiffs.h"
+#include "spiffs_nucleus.h"
+#include "spiffs_api.h"
+
+#include "catch.hpp"
+
+TEST_CASE("format disk, open file, write and read file", "[spiffs]")
+{
+ uint32_t size = 0x00400000;
+
+ int flash_handle = esp_flash_create(size, CONFIG_WL_SECTOR_SIZE, 1);
+ esp_partition_t partition = esp_partition_create(size, 0, flash_handle);
+
+ spiffs fs;
+ spiffs_config cfg;
+
+ // Configure objects needed by SPIFFS
+ esp_spiffs_t esp_user_data;
+ esp_user_data.partition = &partition;
+ fs.user_data = (void*)&esp_user_data;
+
+ cfg.hal_erase_f = spiffs_api_erase;
+ cfg.hal_read_f = spiffs_api_read;
+ cfg.hal_write_f = spiffs_api_write;
+ cfg.log_block_size = CONFIG_WL_SECTOR_SIZE;
+ cfg.log_page_size = CONFIG_SPIFFS_PAGE_SIZE;
+ cfg.phys_addr = 0;
+ cfg.phys_erase_block = CONFIG_WL_SECTOR_SIZE;
+ cfg.phys_size = partition.size;
+
+ uint32_t max_files = 5;
+
+ uint32_t fds_sz = max_files * sizeof(spiffs_fd);
+ uint32_t work_sz = cfg.log_page_size * 2;
+ uint32_t cache_sz = sizeof(spiffs_cache) + max_files * (sizeof(spiffs_cache_page)
+ + cfg.log_page_size);
+
+ uint8_t *work = (uint8_t*) malloc(work_sz);
+ uint8_t *fds = (uint8_t*) malloc(fds_sz);
+ uint8_t *cache = (uint8_t*) malloc(cache_sz);
+
+ s32_t spiffs_res;
+
+ // Special mounting procedure: mount, format, mount as per
+ // https://github.com/pellepl/spiffs/wiki/Using-spiffs
+ spiffs_res = SPIFFS_mount(&fs, &cfg, work, fds, fds_sz,
+ cache, cache_sz, spiffs_api_check);
+ REQUIRE(spiffs_res == SPIFFS_ERR_NOT_A_FS);
+
+ spiffs_res = SPIFFS_format(&fs);
+ REQUIRE(spiffs_res >= SPIFFS_OK);
+
+ spiffs_res = SPIFFS_mount(&fs, &cfg, work, fds, fds_sz,
+ cache, cache_sz, spiffs_api_check);
+ REQUIRE(spiffs_res >= SPIFFS_OK);
+
+ // Open test file
+ spiffs_res = SPIFFS_open(&fs, "test.txt", SPIFFS_O_CREAT | SPIFFS_O_RDWR, 0);
+ REQUIRE(spiffs_res >= SPIFFS_OK);
+
+ // Write to the test file
+ spiffs_file file = spiffs_res;
+
+ const char data[] = "Hello, World!";
+ char *read = (char*) malloc(sizeof(data));
+
+ s32_t bw;
+
+ spiffs_res = SPIFFS_write(&fs, file, (void*)data, sizeof(data));
+ REQUIRE(spiffs_res >= SPIFFS_OK);
+ REQUIRE(spiffs_res == sizeof(data));
+
+ // Set the file object pointer to the beginning
+ spiffs_res = SPIFFS_lseek(&fs, file, 0, SPIFFS_SEEK_SET);
+ REQUIRE(spiffs_res >= SPIFFS_OK);
+
+ // Set the file object pointer to the beginning
+ spiffs_res = SPIFFS_read(&fs, file, (void*)read, sizeof(data));
+ REQUIRE(spiffs_res >= SPIFFS_OK);
+ REQUIRE(spiffs_res == sizeof(data));
+
+ // Close the test file
+ spiffs_res = SPIFFS_close(&fs, file);
+ REQUIRE(spiffs_res >= SPIFFS_OK);
+
+ // Unmount
+ SPIFFS_unmount(&fs);
+
+ esp_flash_delete(flash_handle);
+ free(read);
+}
\ No newline at end of file
esp_err_t result;
wl_handle_t wl_handle;
- esp_partition_t partition = esp_partition_create(PARTITION_SIZE, PARTITION_START);
+ int flash_handle = esp_flash_create(PARTITION_SIZE, 4096, 16);
+ esp_partition_t partition = esp_partition_create(PARTITION_SIZE, PARTITION_START, flash_handle);
// Mount wear-levelled partition
result = wl_mount(partition, &wl_handle);
free(data);
free(read);
-}
\ No newline at end of file
+}