Skip to content

Commit

Permalink
esp8266: generate OTA-ready binaries for 4MB flash
Browse files Browse the repository at this point in the history
  • Loading branch information
tve committed Sep 29, 2015
1 parent 4d782c9 commit 8323a8a
Showing 1 changed file with 77 additions and 39 deletions.
116 changes: 77 additions & 39 deletions Makefile
Expand Up @@ -478,26 +478,26 @@ 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

else ifdef ESP8266_4M
else ifdef ESP8266_4MB
# esp8266 with 4MB flash chip with OTA support: we get 492KB in the first 512, 492 KB in the
# second 512KB for firmware; and then we have 3MB-16KB for SPIFFS of which we're gonna use the
# late 2MB-16KB to leave 1MB unused for future plans
EMBEDDED=1
USE_NET=1
BOARD=ESP8266_BOARD
DEFINES += -D__ETS__ -DICACHE_FLASH -DXTENSA -DUSE_ESP8266_BOARD
# Enable link-time optimisations (inlining across files)
OPTIMIZEFLAGS+=-O3 -std=gnu11 -fgnu89-inline -flto -fno-fat-lto-objects -Wl,--allow-multiple-definition
DEFINES += -DLINK_TIME_OPTIMISATION
ESP_SPI_SIZE ?= 4 # 4->4MB (512KB+512KB)
# Enable link-time optimisations (inlining across files) but don't go beyond -O2 'cause of
# code size explosion, also -DLINK_TIME_OPTIMISATION leads to too big a firmware
OPTIMIZEFLAGS+=-O2 -std=gnu11 -fgnu89-inline -flto -fno-fat-lto-objects -Wl,--allow-multiple-definition
ESP_FLASH_SIZE ?= 4 # 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 512KB flash partition: 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

else ifdef ESP8266_2M
else ifdef ESP8266_2MB
# *** WARNING: THIS FLASH SIZE HAS NOT BEEN TESTED ***
# esp8266 with 2MB flash chip with OTA support: same as 4MB except we have 1MB-16KB for SPIFFS
EMBEDDED=1
Expand All @@ -507,15 +507,15 @@ DEFINES += -D__ETS__ -DICACHE_FLASH -DXTENSA -DUSE_ESP8266_BOARD
# Enable link-time optimisations (inlining across files)
OPTIMIZEFLAGS+=-O3 -std=gnu11 -fgnu89-inline -flto -fno-fat-lto-objects -Wl,--allow-multiple-definition
DEFINES += -DLINK_TIME_OPTIMISATION
ESP_SPI_SIZE ?= 3 # 3->2MB (512KB+512KB)
ESP_FLASH_SIZE ?= 3 # 3->2MB (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 512KB flash partition: 492KB
ET_FS ?= 16m # 32Mbit 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

else ifdef ESP8266_1M
else ifdef ESP8266_1MB
# *** WARNING: THIS FLASH SIZE HAS NOT BEEN TESTED ***
# esp8266 with 1MB flash chip with OTA support: this is a mix between the 512KB and 2MB versions:
# we get two partitions for firmware but we need to turn optimization off to leave some space
Expand All @@ -526,7 +526,7 @@ BOARD=ESP8266_BOARD
DEFINES += -D__ETS__ -DICACHE_FLASH -DXTENSA -DUSE_ESP8266_BOARD
# We have to disable inlining to keep code size in check
OPTIMIZEFLAGS+=-O2 -fno-inline-functions
ESP_SPI_SIZE ?= 2 # 2->1MB (512KB+512KB)
ESP_FLASH_SIZE ?= 2 # 2->1MB (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 512KB flash partition: 492KB
Expand Down Expand Up @@ -1235,6 +1235,17 @@ ifdef NRF5X

endif #NRF5X

ifeq ($(FAMILY),ESP8266)
ESP8266=1
LIBS += -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lmain
CFLAGS+= -fno-builtin -fno-strict-aliasing \
-Wno-maybe-uninitialized -Wno-old-style-declaration -Wno-conversion -Wno-unused-variable \
-Wno-unused-parameter -Wno-ignored-qualifiers -Wno-discarded-qualifiers -Wno-float-conversion \
-Wno-parentheses -Wno-type-limits -Wno-unused-function -Wno-unused-value \
-Wl,EL -Wl,--gc-sections -nostdlib -mlongcalls -mtext-section-literals
endif


ifdef MBED
ARCHFLAGS += -mcpu=cortex-m3 -mthumb
ARM=1
Expand Down Expand Up @@ -1292,16 +1303,6 @@ ifdef RASPBERRYPI
endif
endif

ifeq ($(FAMILY), ESP8266)
ESP8266=1
LIBS += -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lmain
CFLAGS+= -fno-builtin -fno-strict-aliasing \
-Wno-maybe-uninitialized -Wno-old-style-declaration -Wno-conversion -Wno-unused-variable \
-Wno-unused-parameter -Wno-ignored-qualifiers -Wno-discarded-qualifiers -Wno-float-conversion \
-Wno-parentheses -Wno-type-limits -Wno-unused-function -Wno-unused-value \
-Wl,EL -Wl,--gc-sections -nostdlib -mlongcalls -mtext-section-literals
endif

ifdef STM32
DEFINES += -DFAKE_STDLIB
# FAKE_STDLIB is for Espruino - it uses its own standard library so we don't have to link in the normal one + get bloated
Expand Down Expand Up @@ -1377,7 +1378,6 @@ CCPREFIX=xtensa-lx106-elf-

# Extra flags passed to the linker
LDFLAGS += -L$(ESP8266_SDK_ROOT)/lib \
-Ttargets/esp8266/eagle.app.v6.0x10000.ld \
-nostdlib \
-Wl,--no-check-sections \
-u call_user_start \
Expand Down Expand Up @@ -1492,7 +1492,7 @@ proj: $(PROJ_NAME).elf $(PROJ_NAME)_0x00000.bin $(PROJ_NAME)_0x10000.bin
$(PROJ_NAME).elf: $(OBJS) $(LINKER_FILE)
$(Q)$(LD) $(OPTIMIZEFLAGS) -nostdlib -Wl,--no-check-sections -Wl,-static -r -o partial.o $(OBJS)
$(Q)$(OBJCOPY) --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal partial.o
$(Q)$(LD) $(LDFLAGS) -o $@ partial.o -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)$(LD) $(LDFLAGS) -Ttargets/esp8266/eagle.app.v6.0x10000.ld -o $@ partial.o -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)rm partial.o
$(Q)$(OBJDUMP) --headers -j .irom0.text -j .text $(PROJ_NAME).elf | tail -n +4
@echo To disassemble: $(OBJDUMP) -d -l -x $(PROJ_NAME).elf
Expand All @@ -1514,7 +1514,18 @@ endif
else ifdef ESP8266
# for the non-512KB flash we generate a single OTA binary, but we generate two of them, one per
# OTA partition (Espressif calls these user1.bin and user2.bin)
proj: $(PROJ_NAME).elf $(PROJ_NAME)_user1.bin $(PROJ_NAME)_user2.bin
USER1_BIN = $(PROJ_NAME)_user1.bin
USER2_BIN = $(PROJ_NAME)_user2.bin
USER1_ELF = $(PROJ_NAME)_user1.elf
USER2_ELF = $(PROJ_NAME)_user2.elf
LD_SCRIPT1 = ./targets/esp8266/eagle.app.v6.new.1024.app1.ld
LD_SCRIPT2 = ./targets/esp8266/eagle.app.v6.new.1024.app2.ld
APPGEN_TOOL = $(ESP8266_SDK_ROOT)/tools/gen_appbin.py
BOOTLOADER = $(ESP8266_SDK_ROOT)/bin/boot_v1.4(b1).bin
BLANK = $(ESP8266_SDK_ROOT)/bin/blank.bin
INIT_DATA = $(ESP8266_SDK_ROOT)/bin/esp_init_data_default.bin

proj: $(USER1_BIN) $(USER2_BIN)

# linking is complicated. The Espruino source files get compiled into the .text section. The
# Espressif SDK libraries have .text and .irom0 sections. We need to put the libraries' .text into
Expand All @@ -1524,27 +1535,54 @@ proj: $(PROJ_NAME).elf $(PROJ_NAME)_user1.bin $(PROJ_NAME)_user2.bin
# Note that a previous method of renaming .text to .irom0 in each object file doesn't work when
# we enable the link-time optimizer for inlining because it generates fresh code that all ends
# up in .iram0.
$(PROJ_NAME).elf: $(OBJS) $(LINKER_FILE)
$(Q)$(LD) $(OPTIMIZEFLAGS) -nostdlib -Wl,--no-check-sections -Wl,-static -r -o partial.o $(OBJS)
$(Q)$(OBJCOPY) --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal partial.o
$(Q)$(LD) $(LDFLAGS) -o $@ partial.o -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)rm partial.o
$(Q)$(OBJDUMP) --headers -j .irom0.text -j .text $(PROJ_NAME).elf | tail -n +4
@echo To disassemble: $(OBJDUMP) -d -l -x $(PROJ_NAME).elf

# binary image for idata0&iram0
$(PROJ_NAME)_0x00000.bin: $(PROJ_NAME).elf
-$(Q)$(ESPTOOL_CK) -eo $< -bo $@ -bs .text -bs .data -bs .rodata -bs .iram0.text -bc -ec

# binary image for irom0
$(PROJ_NAME)_0x10000.bin: $(PROJ_NAME).elf
-$(Q)$(ESPTOOL_CK) -eo $< -es .irom0.text $@ -ec

flash: all $(PROJ_NAME)_0x00000.bin $(PROJ_NAME)_0x10000.bin
# generate partially linked .o with all Esprunio source files linked
$(PROJ_NAME)_partial.o: $(OBJS) $(LINKER_FILE)
$(Q)$(LD) $(OPTIMIZEFLAGS) -nostdlib -Wl,--no-check-sections -Wl,-static -r -o $@ $(OBJS)
$(Q)$(OBJCOPY) --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal $@

# generate fully linked 'user1' .elf using linker script for first OTA partition
$(USER1_ELF): $(PROJ_NAME)_partial.o $(LINKER_FILE)
@echo Linking user1
$(Q)$(LD) $(LDFLAGS) -T$(LD_SCRIPT1) -o $@ $(PROJ_NAME)_partial.o -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)$(OBJDUMP) --headers -j .irom0.text -j .text $@ | tail -n +4
@echo To disassemble: $(OBJDUMP) -d -l -x $@

# generate fully linked 'user2' .elf using linker script for second OTA partition
$(USER2_ELF): $(PROJ_NAME)_partial.o $(LINKER_FILE)
@echo Linking user2
$(Q)$(LD) $(LDFLAGS) -T$(LD_SCRIPT2) -o $@ $(PROJ_NAME)_partial.o -Wl,--start-group $(LIBS) -Wl,--end-group
@echo To disassemble: $(OBJDUMP) -d -l -x $@

# generate binary image for user1, i.e. first OTA partition
$(USER1_BIN): $(USER1_ELF)
$(Q)$(OBJCOPY) --only-section .text -O binary $(USER1_ELF) eagle.app.v6.text.bin
$(Q)$(OBJCOPY) --only-section .data -O binary $(USER1_ELF) eagle.app.v6.data.bin
$(Q)$(OBJCOPY) --only-section .rodata -O binary $(USER1_ELF) eagle.app.v6.rodata.bin
$(Q)$(OBJCOPY) --only-section .irom0.text -O binary $(USER1_ELF) eagle.app.v6.irom0text.bin
ls -ls eagle*bin
$(Q)COMPILE=gcc python $(APPGEN_TOOL) $(USER1_ELF) 2 $(ESP_FLASH_MODE) $(ESP_FLASH_FREQ_DIV) $(ESP_FLASH_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

# generate binary image for user2, i.e. second OTA partition
$(USER2_BIN): $(USER2_ELF)
$(Q)$(OBJCOPY) --only-section .text -O binary $(USER2_ELF) eagle.app.v6.text.bin
$(Q)$(OBJCOPY) --only-section .data -O binary $(USER2_ELF) eagle.app.v6.data.bin
$(Q)$(OBJCOPY) --only-section .rodata -O binary $(USER2_ELF) eagle.app.v6.rodata.bin
$(Q)$(OBJCOPY) --only-section .irom0.text -O binary $(USER2_ELF) eagle.app.v6.irom0text.bin
ls -ls eagle*bin
$(Q)COMPILE=gcc python $(APPGEN_TOOL) $(USER2_ELF) 2 $(ESP_FLASH_MODE) $(ESP_FLASH_FREQ_DIV) $(ESP_FLASH_SIZE)
$(Q) rm -f eagle.app.v6.*.bin
$(Q) mv eagle.app.flash.bin $@

flash: all $(USER1_BIN) $(USER2_BIN)
ifndef COMPORT
$(error, "In order to flash, we need to have the COMPORT variable defined")
endif
-$(Q)$(ESPTOOL) --port $(COMPORT) --baud 115200 write_flash --flash_freq 40m --flash_mode qio --flash_size 4m 0x00000 $(PROJ_NAME)_0x00000.bin.bin 0x10000 $(PROJ_NAME)_0x10000.bin
-$(Q)$(ESPTOOL) --port $(COMPORT) --baud 460800 write_flash --flash_freq 40m --flash_mode qio --flash_size 4m 0x0000 "$(BOOTLOADER)" 0x1000 $(USER1_BIN) $(ET_BLANK) $(BLANK)

else # embedded, so generate bin, etc ---------------------------

Expand Down

0 comments on commit 8323a8a

Please sign in to comment.