diff --git a/.gitignore b/.gitignore index 2672ca3..458f293 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ webpages.espfs espfs/espfstest/*.o espfs/espfstest/espfstest *.DS_Store -html_compressed/ \ No newline at end of file +html_compressed/ +ldscript_memspecific.ld +eagle.app.sym diff --git a/Makefile b/Makefile index e67aed0..0b0c655 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,18 @@ -#Position and maximum length of espfs in flash memory. This can be undefined. In this case -#the webpages will be linked in into the executable file. If this is defined, please do a -#'make htmlflash' to flash the espfs into the ESPs memory. +#You can build this example in three ways: +# 'separate' - Separate espfs and binaries, no OTA upgrade +# 'combined' - Combined firmware blob, no OTA upgrade +# 'ota' - Combined firmware blob with OTA upgrades. +OUTPUT_TYPE=ota + +#SPI flash size, in K +ESP_SPI_FLASH_SIZE=1024 + +ifeq ("$(OUTPUT_TYPE)","separate") +#Set the pos and length of the ESPFS here. If these are undefined, the rest of the Makefile logic +#will automatically put the webpages in the binary. ESPFS_POS = 0x12000 ESPFS_SIZE = 0x2E000 +endif # Output directors to store intermediate compiled files # relative to the project directory @@ -23,6 +33,13 @@ ESPPORT ?= /dev/ttyUSB0 ESPDELAY ?= 3 ESPBAUD ?= 460800 +#Appgen path and name +APPGEN ?= $(SDK_BASE)/tools/gen_appbin.py + +#0: QIO, 1: QOUT, 2: DIO, 3: DOUT +ESP_FLASH_MODE ?= 0 +#0: 40MHz, 1: 26MHz, 2: 20MHz, 0xf: 80MHz +ESP_FLASH_FREQ_DIV ?= 0 # name for the target project TARGET = httpd @@ -44,8 +61,6 @@ CFLAGS = -Os -ggdb -std=c99 -Werror -Wpointer-arith -Wundef -Wall -Wl,-EL -fno- # linker flags used to generate the main object file LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -# linker script used for the above linkier step -LD_SCRIPT = eagle.app.v6.ld # various paths from the SDK used in this project SDK_LIBDIR = lib @@ -56,6 +71,10 @@ SDK_INCDIR = include include/json CC := $(XTENSA_TOOLS_ROOT)xtensa-lx106-elf-gcc AR := $(XTENSA_TOOLS_ROOT)xtensa-lx106-elf-ar LD := $(XTENSA_TOOLS_ROOT)xtensa-lx106-elf-gcc +OBJCOPY := $(XTENSA_TOOLS_ROOT)xtensa-lx106-elf-objcopy + +#Additional (maybe generated) ld scripts to link in +EXTRA_LD_SCRIPTS:= #### @@ -69,15 +88,8 @@ SDK_INCDIR := $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR)) SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC)) -LIBS := $(addprefix -l,$(LIBS)) APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a) -TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) -LD_SCRIPT := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT)) - -INCDIR := $(addprefix -I,$(SRC_DIR)) -EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR)) -MODULE_INCDIR := $(addsuffix /include,$(INCDIR)) V ?= $(VERBOSE) ifeq ("$(V)","1") @@ -98,12 +110,31 @@ endif ifeq ("$(ESPFS_POS)","") #No hardcoded espfs position: link it in with the binaries. -LIBS += -lwebpages-espfs +LIBS += webpages-espfs else #Hardcoded espfs location: Pass espfs position to rest of code CFLAGS += -DESPFS_POS=$(ESPFS_POS) -DESPFS_SIZE=$(ESPFS_SIZE) endif +#Define default target. If not defined here the one in the included Makefile is used as the default one. +default-tgt: all + +#Include options and target specific to the OUTPUT_TYPE +include Makefile.$(OUTPUT_TYPE) + +#Add all prefixes to paths +LIBS := $(addprefix -l,$(LIBS)) +ifeq ("$(LD_SCRIPT_USR1)", "") +LD_SCRIPT := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT)) +else +LD_SCRIPT_USR1 := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT_USR1)) +LD_SCRIPT_USR2 := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT_USR2)) +endif +INCDIR := $(addprefix -I,$(SRC_DIR)) +EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR)) +MODULE_INCDIR := $(addsuffix /include,$(INCDIR)) + + vpath %.c $(SRC_DIR) define compile-objects @@ -112,7 +143,7 @@ $1/%.o: %.c $(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@ endef -.PHONY: all checkdirs clean libesphttpd +.PHONY: all checkdirs clean libesphttpd default-tgt all: checkdirs $(TARGET_OUT) $(FW_BASE) @@ -124,16 +155,7 @@ libesphttpd/Makefile: libesphttpd: libesphttpd/Makefile $(Q) make -C libesphttpd -$(TARGET_OUT): $(APP_AR) - $(vecho) "LD $@" - $(Q) $(LD) -Llibesphttpd -L$(SDK_LIBDIR) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ - -$(FW_BASE): $(TARGET_OUT) - $(vecho) "FW $@" - $(Q) mkdir -p $@ - $(Q) $(ESPTOOL) elf2image $(TARGET_OUT) --output $@/ - -$(APP_AR): libesphttpd $(OBJ) +$(APP_AR): libesphttpd $(OBJ) $(vecho) "AR $@" $(Q) $(AR) cru $@ $(OBJ) @@ -142,22 +164,12 @@ checkdirs: $(BUILD_DIR) $(BUILD_DIR): $(Q) mkdir -p $@ - -flash: $(TARGET_OUT) $(FW_BASE) - $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash 0x00000 $(FW_BASE)/0x00000.bin 0x40000 $(FW_BASE)/0x40000.bin - -blankflash: - $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash 0x7E000 $(SDK_BASE)/bin/blank.bin - -htmlflash: libesphttpd - $(Q) if [ $$(stat -c '%s' libesphttpd/webpages.espfs) -gt $$(( $(ESPFS_SIZE) )) ]; then echo "webpages.espfs too big!"; false; fi - $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash $(ESPFS_POS) libesphttpd/webpages.espfs - clean: $(Q) make -C libesphttpd clean $(Q) rm -f $(APP_AR) $(Q) rm -f $(TARGET_OUT) $(Q) find $(BUILD_BASE) -type f | xargs rm -f $(Q) rm -rf $(FW_BASE) + $(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir)))) diff --git a/Makefile.combined b/Makefile.combined new file mode 100644 index 0000000..09e5c20 --- /dev/null +++ b/Makefile.combined @@ -0,0 +1,32 @@ +#Makefile with the options specific to the build of a non-upgradable firmware with +#the espfs combined into the flash binary. + +# linker script used for the linker step +LD_SCRIPT = eagle.app.v6.ld +# Extra script to tell the linker the correct irom0 memory available +EXTRA_LD_SCRIPTS = ldscript_memspecific.ld + +TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) + +.PHONY: ldscript_memspecific.ld + +ldscript_memspecific.ld: + $(vecho) "GEN $@" + $(Q) echo "MEMORY { irom0_0_seg : org = 0x40240000, len = "$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE)-0x4000)))" }"> ldscript_memspecific.ld + +$(TARGET_OUT): $(APP_AR) $(EXTRA_LD_SCRIPTS) + $(vecho) "LD $@" + $(Q) $(LD) -Llibesphttpd -L$(SDK_LIBDIR) $(LD_SCRIPT) $(EXTRA_LD_SCRIPTS) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ + + +$(FW_BASE): $(TARGET_OUT) + $(vecho) "FW $@" + $(Q) mkdir -p $@ + $(Q) $(ESPTOOL) elf2image $(TARGET_OUT) --output $@/ + +flash: $(TARGET_OUT) $(FW_BASE) + $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash 0x00000 $(FW_BASE)/0x00000.bin 0x40000 $(FW_BASE)/0x40000.bin + +blankflash: + $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash 0x7E000 $(SDK_BASE)/bin/blank.bin + diff --git a/Makefile.ota b/Makefile.ota new file mode 100644 index 0000000..7e19c45 --- /dev/null +++ b/Makefile.ota @@ -0,0 +1,84 @@ +#Makefile with the options specific to the build of a non-upgradable firmware with +#the espfs combined into the flash binary. + +# linker script used for the linker step +LD_SCRIPT_USR1 := eagle.app.v6.new.$(ESP_SPI_FLASH_SIZE).app1.ld +LD_SCRIPT_USR2 := eagle.app.v6.new.$(ESP_SPI_FLASH_SIZE).app2.ld + +TARGET_OUT_USR1 := $(addprefix $(BUILD_BASE)/,$(TARGET).user1.out) +TARGET_OUT_USR2 := $(addprefix $(BUILD_BASE)/,$(TARGET).user2.out) +TARGET_OUT := $(TARGET_OUT_USR1) $(TARGET_OUT_USR2) + +TARGET_BIN_USR1 := $(addprefix $(BUILD_BASE)/,$(TARGET).user1.bin) +TARGET_BIN_USR2 := $(addprefix $(BUILD_BASE)/,$(TARGET).user2.bin) +TARGET_BIN := $(TARGET_BIN_USR1) $(TARGET_BIN_USR2) + +#Convert SPI size into arg for appgen. Format: no=size +FLASH_MAP_CONV:=0:512 2:1024 5:2048 6:4096 +ESP_FLASH_SIZE_IX:=$(patsubst %:$(ESP_SPI_FLASH_SIZE),%,$(filter %:$(ESP_SPI_FLASH_SIZE),$(FLASH_MAP_CONV))) + +define genappbin +$(1): $$(APP_AR) + $$(vecho) LD $$@ + $$(Q) $$(LD) -Llibesphttpd -L$$(SDK_LIBDIR) $(2) $$(LDFLAGS) -Wl,--start-group $$(LIBS) $$(APP_AR) -Wl,--end-group -o $$@ + +$(3): $(1) + $$(vecho) APPGEN $$@ + $$(Q) $$(OBJCOPY) --only-section .text -O binary $1 build/eagle.app.v6.text.bin + $$(Q) $$(OBJCOPY) --only-section .data -O binary $1 build/eagle.app.v6.data.bin + $$(Q) $$(OBJCOPY) --only-section .rodata -O binary $1 build/eagle.app.v6.rodata.bin + $$(Q) $$(OBJCOPY) --only-section .irom0.text -O binary $1 build/eagle.app.v6.irom0text.bin + $$(Q) cd build; COMPILE=gcc PATH=$$(XTENSA_TOOLS_ROOT):$$(PATH) python $$(APPGEN) $(1:build/%=%) 2 $$(ESP_FLASH_MODE) $$(ESP_FLASH_FREQ_DIV) $$(ESP_FLASH_SIZE_IX) + $$(Q) rm -f eagle.app.v6.*.bin + $$(Q) mv build/eagle.app.flash.bin $$@ + @echo "** user1.bin uses $$$$(stat -c '%s' $$@) bytes of" $$(ESP_FLASH_MAX) "available" +endef + +$(eval $(call genappbin,$(TARGET_OUT_USR1),$$(LD_SCRIPT_USR1),$$(TARGET_BIN_USR1))) +$(eval $(call genappbin,$(TARGET_OUT_USR2),$$(LD_SCRIPT_USR2),$$(TARGET_BIN_USR2))) + +.PHONY: ldscript_memspecific.ld + +ldscript_memspecific.ld: + $(vecho) "GEN $@" + $(Q) echo "MEMORY { irom0_0_seg : org = 0x40240000, len = "$$(printf "0x%X" $$(($(ESP_SPI_FLASH_SIZE)-0x4000)))" }"> ldscript_memspecific.ld + + +#define makeuser +#$1: $(APP_AR) +# $(vecho) "LD $@" +# $(Q) $(LD) -Llibesphttpd -L$(SDK_LIBDIR) $(LD_SCRIPT) $(EXTRA_LD_SCRIPTS) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ +# $(Q) $(OBJCP) --only-section .text -O binary $2 build/eagle.app.v6.text.bin +# $(Q) $(OBJCP) --only-section .data -O binary $2 build/eagle.app.v6.data.bin +# $(Q) $(OBJCP) --only-section .rodata -O binary $2 build/eagle.app.v6.rodata.bin +# $(Q) $(OBJCP) --only-section .irom0.text -O binary $2 build/eagle.app.v6.irom0text.bin +# ls -ls build/eagle*bin +# $(Q) COMPILE=gcc PATH=$(XTENSA_TOOLS_ROOT):$(PATH) python $(APPGEN_TOOL) $(USER1_OUT) 2 $(ESP_FLASH_MODE) $(ESP_FLASH_FREQ_DIV) $(ESP_SPI_SIZE) +# $(Q) rm -f eagle.app.v6.*.bin +# $(Q) mv eagle.app.flash.bin $@ +# @echo "** user1.bin uses $$(stat -c '%s' $@) bytes of" $(ESP_FLASH_MAX) "available" +# $(Q) if [ $$(stat -c '%s' $@) -gt $$(( $(ESP_FLASH_MAX) )) ]; then echo "$@ too big!"; false; fi +#endef + + +#user1.bin: +# $(call makeuser,user1.bin,1) + + +$(FW_BASE): $(TARGET_BIN) +# $(vecho) "FW $@" +# $(Q) mkdir -p $@ +# $(Q) $(ESPTOOL) elf2image $(TARGET_OUT) --output $@/ + + + + +flash: $(TARGET_OUT) $(FW_BASE) + $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash 0x00000 $(FW_BASE)/0x00000.bin 0x40000 $(FW_BASE)/0x40000.bin + +blankflash: + $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash 0x7E000 $(SDK_BASE)/bin/blank.bin + +htmlflash: libesphttpd + $(Q) if [ $$(stat -c '%s' libesphttpd/webpages.espfs) -gt $$(( $(ESPFS_SIZE) )) ]; then echo "webpages.espfs too big!"; false; fi + $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash $(ESPFS_POS) libesphttpd/webpages.espfs diff --git a/Makefile.separate b/Makefile.separate new file mode 100644 index 0000000..a059808 --- /dev/null +++ b/Makefile.separate @@ -0,0 +1,28 @@ +#Makefile with the options specific to the build of a non-upgradable firmware with +#the espfs included in the firmware binary. + +# linker script used for the linker step +LD_SCRIPT = eagle.app.v6.ld +# Extra script to tell the linker the correct irom0 memory available +EXTRA_LD_SCRIPTS = ldscript_memspecific.ld + +TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) + +$(TARGET_OUT): $(APP_AR) $(EXTRA_LD_SCRIPTS) + $(vecho) "LD $@" + $(Q) $(LD) -Llibesphttpd -L$(SDK_LIBDIR) $(LD_SCRIPT) $(EXTRA_LD_SCRIPTS) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ + +$(FW_BASE): $(TARGET_OUT) + $(vecho) "FW $@" + $(Q) mkdir -p $@ + $(Q) $(ESPTOOL) elf2image $(TARGET_OUT) --output $@/ + +flash: $(TARGET_OUT) $(FW_BASE) + $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash 0x00000 $(FW_BASE)/0x00000.bin 0x40000 $(FW_BASE)/0x40000.bin + +blankflash: + $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash 0x7E000 $(SDK_BASE)/bin/blank.bin + +htmlflash: libesphttpd + $(Q) if [ $$(stat -c '%s' libesphttpd/webpages.espfs) -gt $$(( $(ESPFS_SIZE) )) ]; then echo "webpages.espfs too big!"; false; fi + $(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash $(ESPFS_POS) libesphttpd/webpages.espfs diff --git a/user/user_main.c b/user/user_main.c index b262d40..8763a5b 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -70,9 +70,11 @@ HttpdBuiltInUrl builtInUrls[]={ {"/led.tpl", cgiEspFsTemplate, tplLed}, {"/index.tpl", cgiEspFsTemplate, tplCounter}, {"/led.cgi", cgiLed, NULL}, -#ifdef ESPFS_POS - {"/updateweb.cgi", cgiUploadEspfs, &espfsParams}, -#endif + {"/flash/download", cgiReadFlash, NULL}, + {"/flash/next", cgiGetFirmwareNext, NULL}, + {"/flash/upload", cgiUploadFirmware, NULL}, + {"/flash/reboot", cgiRebootFirmware, NULL}, + //Routines to make the /wifi URL and everything beneath it work. //Enable the line below to protect the WiFi configuration with an username/password combo.