From a3fd9bfd5135e93073e9c5b90587dba00b4f177b Mon Sep 17 00:00:00 2001 From: Timo Wischer Date: Mon, 29 Feb 2016 12:04:39 +0100 Subject: [PATCH] flash ESP FS to the other (currently not used) partition of the --- Makefile | 27 ++++++++++++++++++++++----- esp-link/cgiflash.c | 38 ++++++++++++++++++++++++++++++-------- esp-link/cgiflash.h | 2 ++ esp-link/main.c | 5 +++++ espfs/espfs.c | 11 ++++++++--- espfs/espfs.h | 5 ++++- 6 files changed, 71 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index e80e253..c8f9db5 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ ESPBAUD ?= 460800 # --------------- chipset configuration --------------- # Pick your flash size: "512KB", "1MB", or "4MB" -FLASH_SIZE ?= 4MB +FLASH_SIZE ?= 512KB # The pin assignments below are used when the settings in flash are invalid, they # can be changed via the web interface @@ -84,7 +84,7 @@ LED_SERIAL_PIN ?= 14 # --------------- esp-link modules config options --------------- # Optional Modules mqtt -MODULES ?= mqtt rest syslog +#MODULES ?= mqtt rest syslog # --------------- esphttpd config options --------------- @@ -113,18 +113,24 @@ COMPRESS_W_HTMLCOMPRESSOR ?= yes HTML_COMPRESSOR ?= htmlcompressor-1.5.3.jar YUI_COMPRESSOR ?= yuicompressor-2.4.8.jar + +# use this option to place the ESP FS in the other partition of the flash +# which is currently not booted. +# ONLY works with wifi update. +USE_OTHER_PARTITION_FOR_ESPFS ?= yes + # -------------- End of config options ------------- HTML_PATH = $(abspath ./html)/ WIFI_PATH = $(HTML_PATH)wifi/ -ESP_FLASH_MAX ?= 503808 # max bin file ifeq ("$(FLASH_SIZE)","512KB") # Winbond 25Q40 512KB flash, typ for esp-01 thru esp-11 ESP_SPI_SIZE ?= 0 # 0->512KB (256KB+256KB) ESP_FLASH_MODE ?= 0 # 0->QIO ESP_FLASH_FREQ_DIV ?= 0 # 0->40Mhz +ESP_FLASH_MAX ?= 241664 # max bin file for 512KB flash: 236KB ET_FS ?= 4m # 4Mbit flash size in esptool flash command ET_FF ?= 40m # 40Mhz flash speed in esptool flash command ET_BLANK ?= 0x7E000 # where to flash blank.bin to erase wireless settings @@ -134,6 +140,7 @@ else ifeq ("$(FLASH_SIZE)","1MB") ESP_SPI_SIZE ?= 2 # 2->1MB (512KB+512KB) ESP_FLASH_MODE ?= 0 # 0->QIO ESP_FLASH_FREQ_DIV ?= 15 # 15->80MHz +ESP_FLASH_MAX ?= 503808 # max bin file for 1MB flash: 492KB ET_FS ?= 8m # 8Mbit flash size in esptool flash command ET_FF ?= 80m # 80Mhz flash speed in esptool flash command ET_BLANK ?= 0xFE000 # where to flash blank.bin to erase wireless settings @@ -146,6 +153,7 @@ else ifeq ("$(FLASH_SIZE)","2MB") ESP_SPI_SIZE ?= 4 # 6->4MB (1MB+1MB) or 4->4MB (512KB+512KB) ESP_FLASH_MODE ?= 0 # 0->QIO, 2->DIO ESP_FLASH_FREQ_DIV ?= 15 # 15->80Mhz +ESP_FLASH_MAX ?= 503808 # max bin file for 1MB flash: 492KB ET_FS ?= 16m # 16Mbit flash size in esptool flash command ET_FF ?= 80m # 80Mhz flash speed in esptool flash command ET_BLANK ?= 0x1FE000 # where to flash blank.bin to erase wireless settings @@ -158,6 +166,7 @@ else ESP_SPI_SIZE ?= 4 # 6->4MB (1MB+1MB) or 4->4MB (512KB+512KB) ESP_FLASH_MODE ?= 0 # 0->QIO, 2->DIO ESP_FLASH_FREQ_DIV ?= 15 # 15->80Mhz +ESP_FLASH_MAX ?= 503808 # max bin file for 1MB flash: 492KB ET_FS ?= 32m # 32Mbit flash size in esptool flash command ET_FF ?= 80m # 80Mhz flash speed in esptool flash command ET_BLANK ?= 0x3FE000 # where to flash blank.bin to erase wireless settings @@ -253,7 +262,11 @@ SDK_TOOLS := $(addprefix $(SDK_BASE)/,$(SDK_TOOLSDIR)) APPGEN_TOOL := $(addprefix $(SDK_TOOLS)/,$(APPGEN_TOOL)) SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) -OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC)) $(BUILD_BASE)/espfs_img.o +OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC)) +ifneq ("$(USE_OTHER_PARTITION_FOR_ESPFS)","yes") +OBJ += $(BUILD_BASE)/espfs_img.o +endif + LIBS := $(addprefix -l,$(LIBS)) APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a) USER1_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).user1.out) @@ -312,6 +325,10 @@ ifeq ("$(CHANGE_TO_STA)","yes") CFLAGS += -DCHANGE_TO_STA endif +ifeq ("$(USE_OTHER_PARTITION_FOR_ESPFS)","yes") +CFLAGS += -DUSE_OTHER_PARTITION_FOR_ESPFS +endif + vpath %.c $(SRC_DIR) define compile-objects @@ -322,7 +339,7 @@ endef .PHONY: all checkdirs clean webpages.espfs wiflash -all: echo_version checkdirs $(FW_BASE)/user1.bin $(FW_BASE)/user2.bin +all: echo_version checkdirs $(FW_BASE)/user1.bin $(FW_BASE)/user2.bin $(BUILD_BASE)/espfs_img.o echo_version: @echo VERSION: $(VERSION) diff --git a/esp-link/cgiflash.c b/esp-link/cgiflash.c index 8c39e36..c6f3ff2 100644 --- a/esp-link/cgiflash.c +++ b/esp-link/cgiflash.c @@ -18,6 +18,7 @@ Some flash handling cgi routines. Used for reading the existing flash and updati #include #include "cgi.h" #include "cgiflash.h" +#include "espfs.h" #ifdef CGIFLASH_DBG #define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0) @@ -47,6 +48,23 @@ static bool canOTA(void) { static char *flash_too_small = "Flash too small for OTA update"; +static int ICACHE_FLASH_ATTR getNextSPIFlashAddr(void) { + const uint8 id = system_upgrade_userbin_check(); + const int address = id == 1 ? 4*1024 // either start after 4KB boot partition + : 4*1024 + FIRMWARE_SIZE + 16*1024 + 4*1024; // 4KB boot, fw1, 16KB user param, 4KB reserved + + return address; +} + +uint32* const ICACHE_FLASH_ATTR getNextFlashAddr(void) { + const uint32 addr = 0x4200000 + getNextSPIFlashAddr(); + + /* cast as a pointer, because it is the real address in this system, + * for accessing the SPI flash position through the mem emu + */ + return (uint32*)addr; +} + //===== Cgi to query which firmware needs to be uploaded next int ICACHE_FLASH_ATTR cgiGetFirmwareNext(HttpdConnData *connData) { if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. @@ -95,7 +113,14 @@ int ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) { connData->post->len < 1024) err = "Invalid request"; // check that data starts with an appropriate header - if (err == NULL && offset == 0) err = check_header(connData->post->buff); + if (err == NULL && offset == 0) { + err = check_header(connData->post->buff); + + /* update anyway, if it is an ESP FS image */ + if (err != NULL && espFsIsImage(connData->post->buff)) { + err = NULL; + } + } // make sure we're buffering in 1024 byte chunks if (err == NULL && offset % 1024 != 0) { @@ -117,13 +142,12 @@ int ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) { } // let's see which partition we need to flash and what flash address that puts us at - uint8 id = system_upgrade_userbin_check(); - int address = id == 1 ? 4*1024 // either start after 4KB boot partition - : 4*1024 + FIRMWARE_SIZE + 16*1024 + 4*1024; // 4KB boot, fw1, 16KB user param, 4KB reserved + int address = getNextSPIFlashAddr(); address += offset; // erase next flash block if necessary if (address % SPI_FLASH_SEC_SIZE == 0){ + const uint8 id = system_upgrade_userbin_check(); DBG("Flashing 0x%05x (id=%d)\n", address, 2 - id); spi_flash_erase_sector(address/SPI_FLASH_SEC_SIZE); } @@ -155,9 +179,7 @@ int ICACHE_FLASH_ATTR cgiRebootFirmware(HttpdConnData *connData) { // sanity-check that the 'next' partition actually contains something that looks like // valid firmware - uint8 id = system_upgrade_userbin_check(); - int address = id == 1 ? 4*1024 // either start after 4KB boot partition - : 4*1024 + FIRMWARE_SIZE + 16*1024 + 4*1024; // 4KB boot, fw1, 16KB user param, 4KB reserved + const int address = getNextSPIFlashAddr(); uint32 buf[8]; DBG("Checking %p\n", (void *)address); spi_flash_read(address, buf, sizeof(buf)); @@ -197,4 +219,4 @@ int ICACHE_FLASH_ATTR cgiReset(HttpdConnData *connData) { os_timer_setfn(&flash_reboot_timer, (os_timer_func_t *)system_restart, NULL); os_timer_arm(&flash_reboot_timer, 2000, 1); return HTTPD_CGI_DONE; -} \ No newline at end of file +} diff --git a/esp-link/cgiflash.h b/esp-link/cgiflash.h index f03b8e0..6674125 100644 --- a/esp-link/cgiflash.h +++ b/esp-link/cgiflash.h @@ -3,6 +3,8 @@ #include "httpd.h" +uint32* const getNextFlashAddr(void); + int cgiReadFlash(HttpdConnData *connData); int cgiGetFirmwareNext(HttpdConnData *connData); int cgiUploadFirmware(HttpdConnData *connData); diff --git a/esp-link/main.c b/esp-link/main.c index 4f7de35..bfc0745 100644 --- a/esp-link/main.c +++ b/esp-link/main.c @@ -129,9 +129,14 @@ void user_init(void) { // Wifi wifiInit(); // init the flash filesystem with the html stuff +#ifdef USE_OTHER_PARTITION_FOR_ESPFS + uint32* addr = getNextFlashAddr(); + espFsInit(addr); +#else espFsInit(&_binary_espfs_img_start); //EspFsInitResult res = espFsInit(&_binary_espfs_img_start); //os_printf("espFsInit %s\n", res?"ERR":"ok"); +#endif // mount the http handlers httpdInit(builtInUrls, 80); // init the wifi-serial transparent bridge (port 23) diff --git a/espfs/espfs.c b/espfs/espfs.c index f9942f3..963075e 100644 --- a/espfs/espfs.c +++ b/espfs/espfs.c @@ -67,6 +67,13 @@ Accessing the flash through the mem emulation at 0x40200000 is a bit hairy: All a memory exception, crashing the program. */ +bool ICACHE_FLASH_ATTR espFsIsImage(const void* const flashAddress) { + // check if there is valid header at address + const EspFsHeader* const testHeader = (EspFsHeader*)flashAddress; + return (testHeader->magic == ESPFS_MAGIC); +} + + EspFsInitResult ICACHE_FLASH_ATTR espFsInit(void *flashAddress) { // base address must be aligned to 4 bytes if (((int)flashAddress & 3) != 0) { @@ -74,9 +81,7 @@ EspFsInitResult ICACHE_FLASH_ATTR espFsInit(void *flashAddress) { } // check if there is valid header at address - EspFsHeader testHeader; - os_memcpy(&testHeader, flashAddress, sizeof(EspFsHeader)); - if (testHeader.magic != ESPFS_MAGIC) { + if (espFsIsImage(flashAddress)) { return ESPFS_INIT_RESULT_NO_IMAGE; } diff --git a/espfs/espfs.h b/espfs/espfs.h index c8e13e7..b57a7d6 100644 --- a/espfs/espfs.h +++ b/espfs/espfs.h @@ -1,6 +1,8 @@ #ifndef ESPFS_H #define ESPFS_H +#include + typedef enum { ESPFS_INIT_RESULT_OK, ESPFS_INIT_RESULT_NO_IMAGE, @@ -9,6 +11,7 @@ typedef enum { typedef struct EspFsFile EspFsFile; +bool espFsIsImage(const void* const flashAddress); EspFsInitResult espFsInit(void *flashAddress); EspFsFile *espFsOpen(char *fileName); int espFsFlags(EspFsFile *fh); @@ -16,4 +19,4 @@ int espFsRead(EspFsFile *fh, char *buff, int len); void espFsClose(EspFsFile *fh); -#endif \ No newline at end of file +#endif