mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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:
parent
af629b3547
commit
e542b7a920
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
93
components/spiffs/spiffs_api.c
Normal file
93
components/spiffs/spiffs_api.c
Normal 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);
|
||||
}
|
||||
}
|
59
components/spiffs/spiffs_api.h
Normal file
59
components/spiffs/spiffs_api.h
Normal 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
|
79
components/spiffs/test_spiffs_host/Makefile
Normal file
79
components/spiffs/test_spiffs_host/Makefile
Normal 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
|
3
components/spiffs/test_spiffs_host/main.cpp
Normal file
3
components/spiffs/test_spiffs_host/main.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
|
14
components/spiffs/test_spiffs_host/sdkconfig.h
Normal file
14
components/spiffs/test_spiffs_host/sdkconfig.h
Normal 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
|
@ -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
|
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include "projdefs.h"
|
||||
#include "semphr.h"
|
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define pdTRUE 1
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
@ -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
|
@ -0,0 +1 @@
|
||||
#pragma once
|
@ -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
|
22
components/spiffs/test_spiffs_host/stubs/log/log.c
Normal file
22
components/spiffs/test_spiffs_host/stubs/log/log.c
Normal 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;
|
||||
}
|
||||
|
@ -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);
|
21
components/spiffs/test_spiffs_host/stubs/newlib/lock.c
Normal file
21
components/spiffs/test_spiffs_host/stubs/newlib/lock.c
Normal 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;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#define ESP_VFS_FLAG_CONTEXT_PTR 1
|
||||
#define ESP_VFS_PATH_MAX 15
|
96
components/spiffs/test_spiffs_host/test_spiffs.cpp
Normal file
96
components/spiffs/test_spiffs_host/test_spiffs.cpp
Normal 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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user