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:
parent
5c12b7c7e9
commit
d25b8b2a55
7 changed files with 352 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -7,3 +7,5 @@ SPIFFS_BASE_ADDR = 0x200000
|
|||
SPIFFS_SIZE = 0x100000
|
||||
|
||||
include ../../common.mk
|
||||
|
||||
$(eval $(call make_spiffs_image,files))
|
||||
|
|
1
examples/spiffs/files/test.txt
Normal file
1
examples/spiffs/files/test.txt
Normal file
|
@ -0,0 +1 @@
|
|||
This file will go to SPIFFS image.
|
|
@ -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))
|
||||
|
|
37
extras/spiffs/mkspiffs/Makefile
Normal file
37
extras/spiffs/mkspiffs/Makefile
Normal 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
|
34
extras/spiffs/mkspiffs/README.md
Normal file
34
extras/spiffs/mkspiffs/README.md
Normal 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
|
||||
```
|
243
extras/spiffs/mkspiffs/mkspiffs.c
Normal file
243
extras/spiffs/mkspiffs/mkspiffs.c
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue