fork the esp-idf fatfs for f_forward and exfat support
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
ifndef COMPONENT
|
||||
COMPONENT := fatfs
|
||||
endif
|
||||
|
||||
COMPONENT_LIB := lib$(COMPONENT).a
|
||||
TEST_PROGRAM := test_$(COMPONENT)
|
||||
|
||||
STUBS_LIB_DIR := ../../../components/spi_flash/sim/stubs
|
||||
STUBS_LIB_BUILD_DIR := $(STUBS_LIB_DIR)/build
|
||||
STUBS_LIB := libstubs.a
|
||||
|
||||
SPI_FLASH_SIM_DIR := ../../../components/spi_flash/sim
|
||||
SPI_FLASH_SIM_BUILD_DIR := $(SPI_FLASH_SIM_DIR)/build
|
||||
SPI_FLASH_SIM_LIB := libspi_flash.a
|
||||
|
||||
WEAR_LEVELLING_DIR := ../../../components/wear_levelling/test_wl_host
|
||||
WEAR_LEVELLING_BUILD_DIR := $(WEAR_LEVELLING_DIR)/build
|
||||
WEAR_LEVELLING_LIB := libwl.a
|
||||
|
||||
include Makefile.files
|
||||
|
||||
all: test
|
||||
|
||||
ifndef SDKCONFIG
|
||||
SDKCONFIG_DIR := $(dir $(realpath sdkconfig/sdkconfig.h))
|
||||
SDKCONFIG := $(SDKCONFIG_DIR)sdkconfig.h
|
||||
else
|
||||
SDKCONFIG_DIR := $(dir $(realpath $(SDKCONFIG)))
|
||||
endif
|
||||
|
||||
INCLUDE_FLAGS := $(addprefix -I, $(INCLUDE_DIRS) $(SDKCONFIG_DIR) ../../../tools/catch)
|
||||
|
||||
CPPFLAGS += $(INCLUDE_FLAGS) -g -m32
|
||||
CXXFLAGS += $(INCLUDE_FLAGS) -std=c++11 -g -m32
|
||||
|
||||
# Build libraries that this component is dependent on
|
||||
$(STUBS_LIB_BUILD_DIR)/$(STUBS_LIB): force
|
||||
$(MAKE) -C $(STUBS_LIB_DIR) lib SDKCONFIG=$(SDKCONFIG)
|
||||
|
||||
$(SPI_FLASH_SIM_BUILD_DIR)/$(SPI_FLASH_SIM_LIB): force
|
||||
$(MAKE) -C $(SPI_FLASH_SIM_DIR) lib SDKCONFIG=$(SDKCONFIG)
|
||||
|
||||
$(WEAR_LEVELLING_BUILD_DIR)/$(WEAR_LEVELLING_LIB): force
|
||||
$(MAKE) -C $(WEAR_LEVELLING_DIR) lib SDKCONFIG=$(SDKCONFIG)
|
||||
|
||||
# Create target for building this component as a library
|
||||
CFILES := $(filter %.c, $(SOURCE_FILES))
|
||||
CPPFILES := $(filter %.cpp, $(SOURCE_FILES))
|
||||
|
||||
CTARGET = ${2}/$(patsubst %.c,%.o,$(notdir ${1}))
|
||||
CPPTARGET = ${2}/$(patsubst %.cpp,%.o,$(notdir ${1}))
|
||||
|
||||
ifndef BUILD_DIR
|
||||
BUILD_DIR := build
|
||||
endif
|
||||
|
||||
OBJ_FILES := $(addprefix $(BUILD_DIR)/, $(filter %.o, $(notdir $(SOURCE_FILES:.cpp=.o) $(SOURCE_FILES:.c=.o))))
|
||||
|
||||
define COMPILE_C
|
||||
$(call CTARGET, ${1}, $(BUILD_DIR)) : ${1} $(SDKCONFIG)
|
||||
mkdir -p $(BUILD_DIR)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(call CTARGET, ${1}, $(BUILD_DIR)) ${1}
|
||||
endef
|
||||
|
||||
define COMPILE_CPP
|
||||
$(call CPPTARGET, ${1}, $(BUILD_DIR)) : ${1} $(SDKCONFIG)
|
||||
mkdir -p $(BUILD_DIR)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $(call CPPTARGET, ${1}, $(BUILD_DIR)) ${1}
|
||||
endef
|
||||
|
||||
$(BUILD_DIR)/$(COMPONENT_LIB): $(OBJ_FILES) $(SDKCONFIG)
|
||||
mkdir -p $(BUILD_DIR)
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
lib: $(BUILD_DIR)/$(COMPONENT_LIB)
|
||||
|
||||
$(foreach cfile, $(CFILES), $(eval $(call COMPILE_C, $(cfile))))
|
||||
$(foreach cxxfile, $(CPPFILES), $(eval $(call COMPILE_CPP, $(cxxfile))))
|
||||
|
||||
# Create target for building this component as a test
|
||||
TEST_SOURCE_FILES = \
|
||||
test_fatfs.cpp \
|
||||
main.cpp \
|
||||
|
||||
TEST_OBJ_FILES = $(filter %.o, $(TEST_SOURCE_FILES:.cpp=.o) $(TEST_SOURCE_FILES:.c=.o))
|
||||
|
||||
$(TEST_PROGRAM): lib $(TEST_OBJ_FILES) $(WEAR_LEVELLING_BUILD_DIR)/$(WEAR_LEVELLING_LIB) $(SPI_FLASH_SIM_BUILD_DIR)/$(SPI_FLASH_SIM_LIB) $(STUBS_LIB_BUILD_DIR)/$(STUBS_LIB) partition_table.bin $(SDKCONFIG)
|
||||
g++ $(LDFLAGS) $(CXXFLAGS) -o $@ $(TEST_OBJ_FILES) -L$(BUILD_DIR) -l:$(COMPONENT_LIB) -L$(WEAR_LEVELLING_BUILD_DIR) -l:$(WEAR_LEVELLING_LIB) -L$(SPI_FLASH_SIM_BUILD_DIR) -l:$(SPI_FLASH_SIM_LIB) -L$(STUBS_LIB_BUILD_DIR) -l:$(STUBS_LIB)
|
||||
|
||||
test: $(TEST_PROGRAM)
|
||||
./$(TEST_PROGRAM)
|
||||
|
||||
# Create other necessary targets
|
||||
partition_table.bin: partition_table.csv
|
||||
python ../../../components/partition_table/gen_esp32part.py --verify $< $@
|
||||
|
||||
force:
|
||||
|
||||
# Create target to cleanup files
|
||||
clean:
|
||||
$(MAKE) -C $(STUBS_LIB_DIR) clean
|
||||
$(MAKE) -C $(SPI_FLASH_SIM_DIR) clean
|
||||
$(MAKE) -C $(WEAR_LEVELLING_DIR) clean
|
||||
rm -f $(OBJ_FILES) $(TEST_OBJ_FILES) $(TEST_PROGRAM) $(COMPONENT_LIB) partition_table.bin
|
||||
|
||||
.PHONY: all lib test clean force
|
||||
@@ -0,0 +1,44 @@
|
||||
SOURCE_FILES := \
|
||||
$(addprefix ../src/, \
|
||||
ff.c \
|
||||
ffunicode.c \
|
||||
) \
|
||||
$(addprefix ../diskio/,\
|
||||
diskio.c \
|
||||
diskio_wl.c \
|
||||
) \
|
||||
../port/linux/ffsystem.c
|
||||
|
||||
INCLUDE_DIRS := \
|
||||
. \
|
||||
../diskio \
|
||||
../src \
|
||||
$(addprefix ../../spi_flash/sim/stubs/, \
|
||||
app_update/include \
|
||||
driver/include \
|
||||
freertos/include \
|
||||
newlib/include \
|
||||
sdmmc/include \
|
||||
vfs/include \
|
||||
) \
|
||||
$(addprefix ../../../components/, \
|
||||
esp_rom/include \
|
||||
esp_hw_support/include \
|
||||
esp_hw_support/include/soc \
|
||||
esp_system/include \
|
||||
log/include \
|
||||
xtensa/include \
|
||||
xtensa/esp32/include \
|
||||
soc/esp32/include \
|
||||
heap/include \
|
||||
soc/include \
|
||||
esp32/include \
|
||||
esp_common/include \
|
||||
bootloader_support/include \
|
||||
bootloader_support/bootloader_flash/include \
|
||||
app_update/include \
|
||||
hal/include \
|
||||
spi_flash/include \
|
||||
wear_levelling/include \
|
||||
esp_partition/include \
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
include $(COMPONENT_PATH)/Makefile.files
|
||||
|
||||
COMPONENT_OWNBUILDTARGET := 1
|
||||
COMPONENT_OWNCLEANTARGET := 1
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := $(INCLUDE_DIRS)
|
||||
|
||||
.PHONY: build
|
||||
build: $(SDKCONFIG_HEADER)
|
||||
$(MAKE) -C $(COMPONENT_PATH) lib SDKCONFIG=$(SDKCONFIG_HEADER) BUILD_DIR=$(COMPONENT_BUILD_DIR) COMPONENT=$(COMPONENT_NAME)
|
||||
|
||||
CLEAN_FILES := component_project_vars.mk
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(summary) RM $(CLEAN_FILES)
|
||||
rm -f $(CLEAN_FILES)
|
||||
$(MAKE) -C $(COMPONENT_PATH) clean SDKCONFIG=$(SDKCONFIG_HEADER) BUILD_DIR=$(COMPONENT_BUILD_DIR) COMPONENT=$(COMPONENT_NAME)
|
||||
@@ -0,0 +1,2 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
@@ -0,0 +1,6 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 1M,
|
||||
storage, data, fat, , 1M,
|
||||
|
@@ -0,0 +1,94 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ff.h"
|
||||
#include "esp_partition.h"
|
||||
#include "wear_levelling.h"
|
||||
#include "diskio_impl.h"
|
||||
#include "diskio_wl.h"
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
extern "C" void _spi_flash_init(const char* chip_size, size_t block_size, size_t sector_size, size_t page_size, const char* partition_bin);
|
||||
|
||||
TEST_CASE("create volume, open file, write and read back data", "[fatfs]")
|
||||
{
|
||||
_spi_flash_init(CONFIG_ESPTOOLPY_FLASHSIZE, CONFIG_WL_SECTOR_SIZE * 16, CONFIG_WL_SECTOR_SIZE, CONFIG_WL_SECTOR_SIZE, "partition_table.bin");
|
||||
|
||||
FRESULT fr_result;
|
||||
BYTE pdrv;
|
||||
FATFS fs;
|
||||
FIL file;
|
||||
UINT bw;
|
||||
|
||||
esp_err_t esp_result;
|
||||
|
||||
const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, "storage");
|
||||
|
||||
// Mount wear-levelled partition
|
||||
wl_handle_t wl_handle;
|
||||
esp_result = wl_mount(partition, &wl_handle);
|
||||
REQUIRE(esp_result == ESP_OK);
|
||||
|
||||
// Get a physical drive
|
||||
esp_result = ff_diskio_get_drive(&pdrv);
|
||||
REQUIRE(esp_result == ESP_OK);
|
||||
|
||||
// Register physical drive as wear-levelled partition
|
||||
esp_result = ff_diskio_register_wl_partition(pdrv, wl_handle);
|
||||
|
||||
// Create FAT volume on the entire disk
|
||||
LBA_t part_list[] = {100, 0, 0, 0};
|
||||
BYTE work_area[FF_MAX_SS];
|
||||
|
||||
fr_result = f_fdisk(pdrv, part_list, work_area);
|
||||
REQUIRE(fr_result == FR_OK);
|
||||
const MKFS_PARM opt = {(BYTE)FM_ANY, 0, 0, 0, 0};
|
||||
fr_result = f_mkfs("", &opt, work_area, sizeof(work_area)); // Use default volume
|
||||
|
||||
// Mount the volume
|
||||
fr_result = f_mount(&fs, "", 0);
|
||||
REQUIRE(fr_result == FR_OK);
|
||||
|
||||
// Open, write and read data
|
||||
fr_result = f_open(&file, "test.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
|
||||
REQUIRE(fr_result == FR_OK);
|
||||
|
||||
// Generate data
|
||||
uint32_t data_size = 100000;
|
||||
|
||||
char *data = (char*) malloc(data_size);
|
||||
char *read = (char*) malloc(data_size);
|
||||
|
||||
for(uint32_t i = 0; i < data_size; i += sizeof(i))
|
||||
{
|
||||
*((uint32_t*)(data + i)) = i;
|
||||
}
|
||||
|
||||
// Write generated data
|
||||
fr_result = f_write(&file, data, data_size, &bw);
|
||||
REQUIRE(fr_result == FR_OK);
|
||||
REQUIRE(bw == data_size);
|
||||
|
||||
// Move to beginning of file
|
||||
fr_result = f_lseek(&file, 0);
|
||||
REQUIRE(fr_result == FR_OK);
|
||||
|
||||
// Read written data
|
||||
fr_result = f_read(&file, read, data_size, &bw);
|
||||
REQUIRE(fr_result == FR_OK);
|
||||
REQUIRE(bw == data_size);
|
||||
|
||||
REQUIRE(memcmp(data, read, data_size) == 0);
|
||||
|
||||
// Close file
|
||||
fr_result = f_close(&file);
|
||||
REQUIRE(fr_result == FR_OK);
|
||||
|
||||
// Unmount default volume
|
||||
fr_result = f_mount(0, "", 0);
|
||||
REQUIRE(fr_result == FR_OK);
|
||||
|
||||
free(read);
|
||||
free(data);
|
||||
}
|
||||
Reference in New Issue
Block a user