Create SPIFFS image and flash it.

mkspiffs is added to create SPIFFS image from directory with files.
Build process changed to flash SPIFFS image if necessary
This commit is contained in:
sheinz 2016-07-10 01:33:23 +03:00
parent 5c12b7c7e9
commit d25b8b2a55
7 changed files with 352 additions and 1 deletions

View file

@ -210,7 +210,8 @@ $(FW_FILE): $(PROGRAM_OUT) $(FIRMWARE_DIR)
$(Q) $(ESPTOOL) elf2image --version=2 $(ESPTOOL_ARGS) $< -o $(FW_FILE)
flash: $(FW_FILE)
$(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) write_flash $(ESPTOOL_ARGS) 0x0 $(RBOOT_BIN) 0x1000 $(RBOOT_CONF) 0x2000 $(FW_FILE)
$(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) write_flash $(ESPTOOL_ARGS) \
0x0 $(RBOOT_BIN) 0x1000 $(RBOOT_CONF) 0x2000 $(FW_FILE) $(SPIFFS_ESPTOOL_ARGS)
erase_flash:
$(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) erase_flash

View file

@ -7,3 +7,5 @@ SPIFFS_BASE_ADDR = 0x200000
SPIFFS_SIZE = 0x100000
include ../../common.mk
$(eval $(call make_spiffs_image,files))

View file

@ -0,0 +1 @@
This file will go to SPIFFS image.

View file

@ -14,4 +14,37 @@ spiffs_CFLAGS = $(CFLAGS)
spiffs_CFLAGS += -DSPIFFS_BASE_ADDR=$(SPIFFS_BASE_ADDR)
spiffs_CFLAGS += -DSPIFFS_SIZE=$(SPIFFS_SIZE)
# Create an SPIFFS image of specified directory and flash it with
# the rest of the firmware.
#
# Argumens:
# $(1) - directory with files which go into spiffs image
#
# Example:
# $(eval $(call make_spiffs_image,files))
define make_spiffs_image
SPIFFS_IMAGE = $(addprefix $(FIRMWARE_DIR),spiffs.bin)
MKSPIFFS_DIR = $(ROOT)/extras/spiffs/mkspiffs
MKSPIFFS = $$(MKSPIFFS_DIR)/mkspiffs
all: $$(SPIFFS_IMAGE)
clean: clean_spiffs_img clean_mkspiffs
$$(SPIFFS_IMAGE): $$(MKSPIFFS) $(1)
$$< $(1) $$@
$$(MKSPIFFS):
$$(MAKE) -C $$(MKSPIFFS_DIR) SPIFFS_SIZE=$(SPIFFS_SIZE)
clean_spiffs_img:
$$(Q) rm -f spiffs.img
clean_mkspiffs:
$$(Q) $$(MAKE) -C $$(MKSPIFFS_DIR) clean
SPIFFS_ESPTOOL_ARGS = $(SPIFFS_BASE_ADDR) $$(SPIFFS_IMAGE)
endef
$(eval $(call component_compile_rules,spiffs))

View file

@ -0,0 +1,37 @@
# Check if SPIFFS_SIZE defined only if not cleaning
ifneq ($(MAKECMDGOALS),clean)
ifndef SPIFFS_SIZE
define ERROR_MSG
Variable SPIFFS_SIZE is not defined.
Cannot build mkspiffs without SPIFFS_SIZE.
Please specify it in your application Makefile.
endef
$(error $(ERROR_MSG))
endif
endif
SOURCES := spiffs_hydrogen.c
SOURCES += spiffs_cache.c
SOURCES += spiffs_gc.c
SOURCES += spiffs_check.c
SOURCES += spiffs_nucleus.c
SOURCES += mkspiffs.c
OBJECTS := $(SOURCES:.c=.o)
VPATH = ../spiffs/src
CFLAGS += -I..
CFLAGS += -DSPIFFS_BASE_ADDR=0 # for image base addr is start of the image
CFLAGS += -DSPIFFS_SIZE=$(SPIFFS_SIZE)
all: mkspiffs
mkspiffs: $(OBJECTS)
clean:
@rm -f mkspiffs
@rm -f *.o
.PHONY: all clean

View file

@ -0,0 +1,34 @@
# mkspiffs Create spiffs image
mkspiffs is a command line utility to create an image of SPIFFS in order
to write to flash.
## Usage
mkspiffs will be built automatically if you include the following line in your
makefile:
```
$(eval $(call make_spiffs_image,files))
```
where *files* is the directory with files that should go into SPIFFS image.
Or you can build mkspiffs manually with:
```
make SPIFFS_SIZE=0x100000
```
mkspiffs cannot be built without specifying SPIFFS size because it uses the
same SPIFFS sources as the firmware. And for the firmware SPIFFS size is
compile time defined.
Please note that if you change SPIFFS_SIZE you need to rebuild mkspiffs.
The easiest way is to run `make clean` for you project.
To manually generate SPIFFS image from directory, run:
```
mkspiffs DIRECTORY IMAGE_NAME
```

View file

@ -0,0 +1,243 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 sheinz (https://github.com/sheinz)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/dirent.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "spiffs_config.h"
#include "../spiffs/src/spiffs.h"
static spiffs fs;
static void *image = 0;
static void *work_buf = 0;
static void *fds_buf = 0;
static void *cache_buf = 0;
static void print_usage(const char *prog_name, const char *error_msg)
{
if (error_msg) {
printf("Error: %s\n", error_msg);
}
printf("Usage: ");
printf("\t%s DIRECTORY IMAGE_NAME\n\n", prog_name);
printf("Example:\n");
printf("\t%s ./my_files spiffs.img\n\n", prog_name);
}
static s32_t _read_data(u32_t addr, u32_t size, u8_t *dst)
{
memcpy(dst, (uint8_t*)image + addr, size);
return SPIFFS_OK;
}
static s32_t _write_data(u32_t addr, u32_t size, u8_t *src)
{
memcpy((uint8_t*)image + addr, src, size);
return SPIFFS_OK;
}
static s32_t _erase_data(u32_t addr, u32_t size)
{
memset((uint8_t*)image + addr, 0xFF, size);
return SPIFFS_OK;
}
static bool init_spiffs(bool allocate_mem)
{
spiffs_config config = {0};
printf("Initializing SPIFFS, size=%d\n", SPIFFS_SIZE);
config.hal_read_f = _read_data;
config.hal_write_f = _write_data;
config.hal_erase_f = _erase_data;
int workBufSize = 2 * SPIFFS_CFG_LOG_PAGE_SZ();
int fdsBufSize = SPIFFS_buffer_bytes_for_filedescs(&fs, 5);
int cacheBufSize = SPIFFS_buffer_bytes_for_cache(&fs, 5);
if (allocate_mem) {
image = malloc(SPIFFS_SIZE);
work_buf = malloc(workBufSize);
fds_buf = malloc(fdsBufSize);
cache_buf = malloc(cacheBufSize);
printf("spiffs memory, work_buf_size=%d, fds_buf_size=%d, cache_buf_size=%d\n",
workBufSize, fdsBufSize, cacheBufSize);
}
int32_t err = SPIFFS_mount(&fs, &config, work_buf, fds_buf, fdsBufSize,
cache_buf, cacheBufSize, 0);
if (err != SPIFFS_OK) {
printf("Error spiffs mount: %d\n", err);
return false;
}
return true;
}
static bool format_spiffs()
{
SPIFFS_unmount(&fs);
if (SPIFFS_format(&fs) == SPIFFS_OK) {
printf("Format complete\n");
} else {
printf("Failed to format SPIFFS\n");
return false;
}
if (!init_spiffs(false)) {
printf("Failed to mount SPIFFS\n");
return false;
}
return true;
}
static void spiffs_free()
{
free(image);
image = NULL;
free(work_buf);
work_buf = NULL;
free(fds_buf);
fds_buf = NULL;
free(cache_buf);
cache_buf = NULL;
}
static bool process_file(const char *src_file, const char *dst_file)
{
int fd;
const int buf_size = 256;
uint8_t buf[buf_size];
int data_len;
fd = open(src_file, O_RDONLY);
if (fd < 0) {
printf("Error openning file: %s\n", src_file);
}
spiffs_file out_fd = SPIFFS_open(&fs, dst_file,
SPIFFS_O_CREAT | SPIFFS_O_WRONLY, 0);
while ((data_len = read(fd, buf, buf_size)) != 0) {
if (SPIFFS_write(&fs, out_fd, buf, data_len) != data_len) {
printf("Error writing to SPIFFS file\n");
break;
}
}
SPIFFS_close(&fs, out_fd);
close(fd);
return true;
}
static bool process_directory(const char *direcotry)
{
DIR *dp;
struct dirent *ep;
char path[256];
dp = opendir(direcotry);
if (dp != NULL) {
while ((ep = readdir(dp)) != 0) {
if (!strcmp(ep->d_name, ".") ||
!strcmp(ep->d_name, "..")) {
continue;
}
if (ep->d_type != DT_REG) {
continue; // not a regular file
}
sprintf(path, "%s/%s", direcotry, ep->d_name);
printf("Processing file %s\n", path);
if (!process_file(path, ep->d_name)) {
printf("Error processing file\n");
break;
}
}
closedir(dp);
} else {
printf("Error reading direcotry: %s\n", direcotry);
}
return true;
}
static bool write_image(const char *out_file)
{
int fd;
int size = SPIFFS_SIZE;
uint8_t *p = (uint8_t*)image;
fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0) {
printf("Error creating file %s\n", out_file);
return false;
}
printf("Writing image to file: %s\n", out_file);
while (size != 0) {
write(fd, p, SPIFFS_CFG_LOG_PAGE_SZ());
p += SPIFFS_CFG_LOG_PAGE_SZ();
size -= SPIFFS_CFG_LOG_PAGE_SZ();
}
close(fd);
return true;
}
int main(int argc, char *argv[])
{
int result = 0;
if (argc != 3) {
print_usage(argv[0], NULL);
return -1;
}
if (init_spiffs(/*allocate_mem=*/true)) {
if (format_spiffs()) {
if (process_directory(argv[1])) {
if (!write_image(argv[2])) {
printf("Error writing image\n");
}
} else {
printf("Error processing direcotry\n");
}
} else {
printf("Error formating spiffs\n");
}
} else {
printf("Error initialising SPIFFS\n");
}
spiffs_free();
return result;
}