spiffs: Make spiffs runnable on host

Makes spiffs component runnable on host. Depends on the host library build
of flash emulator. Includes a basic sanity test of
mounting a volume, opening a file, writing to the file, reading the file,
closing the file and unmounting volume.
This commit is contained in:
Renz Bagaporo 2018-05-22 16:47:30 +08:00 committed by bot
parent af629b3547
commit e542b7a920
24 changed files with 542 additions and 112 deletions

View File

@ -57,7 +57,7 @@ force:
$(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*)
@ -80,4 +80,4 @@ clean:
rm -rf coverage_report/
rm -f coverage.info
.PHONY: clean all
.PHONY: clean all test

View File

@ -23,7 +23,7 @@ TEST_CASE("create volume, open file, write and read back data", "[fatfs]")
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);
@ -77,7 +77,7 @@ TEST_CASE("create volume, open file, write and read back data", "[fatfs]")
fr_result = f_mount(0, "", 0);
REQUIRE(fr_result == FR_OK);
esp_partition_delete(partition);
esp_flash_delete(flash_handle);
free(read);
}
}

View File

@ -27,6 +27,7 @@ Flash_Emulator::Flash_Emulator(size_t size, size_t sector_sise, size_t min_size)
this->buff = (uint8_t *)malloc(this->size);
this->access_count = new uint32_t[this->size / this->sector_sise];
memset(this->access_count, 0, this->size / this->sector_sise * sizeof(uint32_t));
memset(this->buff, 1, this->size);
}
size_t Flash_Emulator::chip_size()

View File

@ -84,9 +84,11 @@ esp_err_t esp_partition_erase_range(const esp_partition_t* partition,
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)
}

View File

@ -8,13 +8,13 @@
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;
}
@ -22,23 +22,28 @@ esp_partition_t esp_partition_create(uint32_t size, uint32_t start)
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,
@ -60,4 +65,4 @@ esp_err_t esp_partition_read(const esp_partition_t* partition,
{
emulators[partition->handle]->read(src_offset, dst, size);
return ESP_OK;
}
}

View File

@ -1,5 +1,5 @@
COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_PRIV_INCLUDEDIRS := spiffs/src
COMPONENT_PRIV_INCLUDEDIRS := . spiffs/src
COMPONENT_SRCDIRS := . spiffs/src
COMPONENT_SUBMODULES := spiffs

View File

@ -30,29 +30,12 @@
#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
@ -89,77 +72,6 @@ static time_t vfs_spiffs_get_mtime(const spiffs_stat* s);
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;
@ -232,7 +144,7 @@ static esp_err_t esp_spiffs_init(const esp_vfs_spiffs_conf_t* conf)
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");
@ -310,7 +222,7 @@ static esp_err_t esp_spiffs_init(const esp_vfs_spiffs_conf_t* conf)
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) {
@ -323,7 +235,7 @@ static esp_err_t esp_spiffs_init(const esp_vfs_spiffs_conf_t* conf)
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) {
@ -710,7 +622,7 @@ static struct dirent* vfs_spiffs_readdir(void* ctx, DIR* pdir)
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);

View File

@ -0,0 +1,93 @@
// 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);
}
}

View File

@ -0,0 +1,59 @@
// 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

View File

@ -0,0 +1,79 @@
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

View File

@ -0,0 +1,3 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"

View File

@ -0,0 +1,14 @@
#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

View File

@ -0,0 +1,23 @@
#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

View File

@ -0,0 +1,4 @@
#pragma once
#include "projdefs.h"
#include "semphr.h"

View File

@ -0,0 +1,11 @@
#pragma once
#if defined(__cplusplus)
extern "C" {
#endif
#define pdTRUE 1
#if defined(__cplusplus)
}
#endif

View File

@ -0,0 +1,16 @@
#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

View File

@ -0,0 +1 @@
#pragma once

View File

@ -0,0 +1,51 @@
#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

View File

@ -0,0 +1,22 @@
#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;
}

View File

@ -0,0 +1,10 @@
#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);

View File

@ -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;
}

View File

@ -0,0 +1,6 @@
#pragma once
#include "esp_err.h"
#define ESP_VFS_FLAG_CONTEXT_PTR 1
#define ESP_VFS_PATH_MAX 15

View File

@ -0,0 +1,96 @@
#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);
}

View File

@ -28,7 +28,8 @@ 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);
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);
@ -91,4 +92,4 @@ TEST_CASE("write and read back data", "[wear_levelling]")
free(data);
free(read);
}
}