flash ESP FS to the other (currently not used) partition of the

pull/112/head
Timo Wischer 9 years ago
parent 3b60f88a6e
commit a3fd9bfd51
  1. 27
      Makefile
  2. 38
      esp-link/cgiflash.c
  3. 2
      esp-link/cgiflash.h
  4. 5
      esp-link/main.c
  5. 11
      espfs/espfs.c
  6. 5
      espfs/espfs.h

@ -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)

@ -18,6 +18,7 @@ Some flash handling cgi routines. Used for reading the existing flash and updati
#include <osapi.h>
#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;
}
}

@ -3,6 +3,8 @@
#include "httpd.h"
uint32* const getNextFlashAddr(void);
int cgiReadFlash(HttpdConnData *connData);
int cgiGetFirmwareNext(HttpdConnData *connData);
int cgiUploadFirmware(HttpdConnData *connData);

@ -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)

@ -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;
}

@ -1,6 +1,8 @@
#ifndef ESPFS_H
#define ESPFS_H
#include <stdbool.h>
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
#endif

Loading…
Cancel
Save