Support building an OTA-compatible flash image

Image is suitable for SDK v1.2 bootloader or rBoot.
This commit is contained in:
Angus Gratton 2015-07-21 15:02:09 +10:00
parent 5bbbc1f144
commit 87dc2317f5
2 changed files with 108 additions and 25 deletions

View file

@ -14,38 +14,52 @@
# BSD Licensed as described in the file LICENSE at top level. # BSD Licensed as described in the file LICENSE at top level.
# #
# This makefile is adapted from the esp-mqtt makefile by @tuanpmt # This makefile is adapted from the esp-mqtt makefile by @tuanpmt
# https://github.com/tuanpmt/esp_mqtt, but it has changed significantly # https://github.com/tuanpmt/esp_mqtt, but it has changed very significantly
# since then. # since then.
#
# assume the 'root' directory (ie top of the tree) is the directory common.mk is in # assume the 'root' directory (ie top of the tree) is the directory common.mk is in
ROOT := $(dir $(lastword $(MAKEFILE_LIST))) ROOT := $(dir $(lastword $(MAKEFILE_LIST)))
# include optional local overrides at the root level, then in program directory # include optional local overrides at the root level, then in program directory
#
# Create either of these files for local system overrides if possible,
# instead of editing this makefile directly.
-include $(ROOT)local.mk -include $(ROOT)local.mk
-include local.mk -include local.mk
ifndef PROGRAM # Flash size in megabits
$(error "Set the PROGRAM environment variable in your Makefile before including common.mk" # Valid values are same as for esptool.py - 2m,4m,8m,16m,32m
endif FLASH_SIZE ?= 16
# esptool defaults
ESPTOOL ?= esptool.py
ESPBAUD ?= 115200
# Output directories to store intermediate compiled files # Output directories to store intermediate compiled files
# relative to the program directory # relative to the program directory
BUILD_DIR ?= $(PROGRAM_DIR)build/ BUILD_DIR ?= $(PROGRAM_DIR)build/
FW_BASE ?= $(PROGRAM_DIR)firmware/ FW_BASE ?= $(PROGRAM_DIR)firmware/
# we create two different files for uploading into the flash # esptool.py from https://github.com/themadinventor/esptool
# these are the names and options to generate them ESPTOOL ?= esptool.py
FW_1 = 0x00000 # serial port settings for esptool.py
FW_2 = 0x40000 ESPPORT ?= /dev/ttyUSB0
ESPBAUD ?= 115200
# Set OTA to 1 to build an image that supports rBoot OTA bootloader
#
# Currently only works with 16mbit or more flash sizes, with 8mbit
# images for each "slot"
OTA ?= 0
ifeq ($(OTA),1)
# for OTA, we build a "SDK v1.2 bootloader" compatible image where everything is in
# one file (should work with the v1.2 binary bootloader, and the FOSS rBoot bootloader).
IMGTOOL ?= esptool2
# Tell C preprocessor that we're building for OTA
CPPFLAGS = -DOTA
endif
FLAVOR ?= release # or debug FLAVOR ?= release # or debug
# Compiler names, etc. assume gdb # Compiler names, etc. assume gdb
ESPPORT ?= /dev/ttyUSB0
CROSS ?= xtensa-lx106-elf- CROSS ?= xtensa-lx106-elf-
AR = $(CROSS)ar AR = $(CROSS)ar
@ -71,8 +85,8 @@ LIBS ?= hal gcc c
# set to 0 if you want to use the toolchain libc instead of esp-open-rtos newlib # set to 0 if you want to use the toolchain libc instead of esp-open-rtos newlib
OWN_LIBC ?= 1 OWN_LIBC ?= 1
# Note: this isn't overridable without a not-yet-merged patch to esptool # Note: you will need a recent esp
ENTRY_SYMBOL = call_user_start ENTRY_SYMBOL ?= call_user_start
CFLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals -std=gnu99 $(CPPFLAGS) CFLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals -std=gnu99 $(CPPFLAGS)
LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map
@ -86,7 +100,7 @@ else
endif endif
GITSHORTREV=\"$(shell cd $(ROOT); git rev-parse --short -q HEAD)\" GITSHORTREV=\"$(shell cd $(ROOT); git rev-parse --short -q HEAD)\"
CPPFLAGS += -DGITSHORTREV=$(GITSHORTREV) CPPFLAGS += -DGITSHORTREV=$(GITSHORTREV) -DFLASH_SIZE=$(FLASH_SIZE)
# Linker scripts, all found in $(ROOT)/ld # Linker scripts, all found in $(ROOT)/ld
LINKER_SCRIPTS = eagle.app.v6.ld eagle.rom.addr.v6.ld LINKER_SCRIPTS = eagle.app.v6.ld eagle.rom.addr.v6.ld
@ -95,6 +109,10 @@ LINKER_SCRIPTS = eagle.app.v6.ld eagle.rom.addr.v6.ld
#### no user configurable options below here #### no user configurable options below here
#### ####
ifndef PROGRAM
$(error "Set the PROGRAM environment variable in your Makefile before including common.mk"
endif
# hacky way to get a single space value # hacky way to get a single space value
empty := empty :=
space := $(empty) $(empty) space := $(empty) $(empty)
@ -106,15 +124,30 @@ lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(s
PROGRAM_DIR := $(dir $(firstword $(MAKEFILE_LIST))) PROGRAM_DIR := $(dir $(firstword $(MAKEFILE_LIST)))
# linker scripts get run through the C preprocessor # linker scripts get run through the C preprocessor
LINKER_SCRIPTS_PROCESSED = $(addprefix $(BUILD_DIR)ld/,$(LINKER_SCRIPTS)) ifeq ($(OTA),1)
LD_DIR = $(BUILD_DIR)ld-$(FLASH_SIZE)-ota/
else
LD_DIR = $(BUILD_DIR)ld-$(FLASH_SIZE)/
endif
LINKER_SCRIPTS_PROCESSED = $(addprefix $(LD_DIR),$(LINKER_SCRIPTS))
# derive various parts of compiler/linker arguments # derive various parts of compiler/linker arguments
SDK_LIB_ARGS = $(addprefix -l,$(SDK_LIBS)) SDK_LIB_ARGS = $(addprefix -l,$(SDK_LIBS))
LIB_ARGS = $(addprefix -l,$(LIBS)) LIB_ARGS = $(addprefix -l,$(LIBS))
PROGRAM_OUT = $(BUILD_DIR)$(PROGRAM).out PROGRAM_OUT = $(BUILD_DIR)$(PROGRAM).out
LDFLAGS += $(addprefix -T,$(LINKER_SCRIPTS_PROCESSED)) LDFLAGS += $(addprefix -T,$(LINKER_SCRIPTS_PROCESSED))
FW_FILE_1 = $(addprefix $(FW_BASE),$(FW_1).bin)
FW_FILE_2 = $(addprefix $(FW_BASE),$(FW_2).bin) ifeq ($(OTA),0)
# for non-OTA, we create two different files for uploading into the flash
# these are the names and options to generate them
FW_ADDR_1 = 0x00000
FW_ADDR_2 = 0x40000
FW_FILE_1 = $(addprefix $(FW_BASE),$(FW_ADDR_1).bin)
FW_FILE_2 = $(addprefix $(FW_BASE),$(FW_ADDR_2).bin)
else
# for OTA, it's a single monolithic image
FW_FILE = $(addprefix $(FW_BASE),$(FW_NAME).bin)
endif
# Common include directories, shared across all "components" # Common include directories, shared across all "components"
# components will add their include directories to this argument # components will add their include directories to this argument
@ -139,7 +172,7 @@ endif
.PHONY: all clean debug_print .PHONY: all clean debug_print
all: $(PROGRAM_OUT) $(FW_FILE_1) $(FW_FILE_2) all: $(PROGRAM_OUT) $(FW_FILE_1) $(FW_FILE_2) $(FW_FILE)
# component_compile_rules: Produces compilation rules for a given # component_compile_rules: Produces compilation rules for a given
# component # component
@ -259,7 +292,7 @@ $(foreach component,$(COMPONENTS), $(eval include $(ROOT)$(component)/component.
## Run linker scripts via C preprocessor to evaluate macros ## Run linker scripts via C preprocessor to evaluate macros
$(BUILD_DIR)ld/%.ld: $(ROOT)ld/%.ld | $(BUILD_DIR)ld $(LD_DIR)%.ld: $(ROOT)ld/%.ld | $(LD_DIR)
$(Q) $(CPP) $(CPPFLAGS) -E -C -P $< > $@ $(Q) $(CPP) $(CPPFLAGS) -E -C -P $< > $@
# final linking step to produce .elf # final linking step to produce .elf
@ -267,15 +300,24 @@ $(PROGRAM_OUT): $(COMPONENT_ARS) $(SDK_PROCESSED_LIBS) $(LINKER_SCRIPTS_PROCESSE
$(vecho) "LD $@" $(vecho) "LD $@"
$(Q) $(LD) $(LDFLAGS) -Wl,--start-group $(LIB_ARGS) $(SDK_LIB_ARGS) $(COMPONENT_ARS) -Wl,--end-group -o $@ $(Q) $(LD) $(LDFLAGS) -Wl,--start-group $(LIB_ARGS) $(SDK_LIB_ARGS) $(COMPONENT_ARS) -Wl,--end-group -o $@
$(BUILD_DIR) $(FW_BASE) $(BUILD_DIR)sdklib $(BUILD_DIR)ld: $(BUILD_DIR) $(FW_BASE) $(BUILD_DIR)sdklib $(LD_DIR):
$(Q) mkdir -p $@ $(Q) mkdir -p $@
$(FW_FILE_1) $(FW_FILE_2): $(PROGRAM_OUT) $(FW_BASE) $(FW_FILE_1) $(FW_FILE_2): $(PROGRAM_OUT) $(FW_BASE)
$(vecho) "FW $@" $(vecho) "FW $@"
$(ESPTOOL) elf2image $< -o $(FW_BASE) $(ESPTOOL) elf2image $< -o $(FW_BASE)
$(FW_FILE): $(PROGRAM_OUT) $(FW_BASE)
$(IMGTOOL) -bin -boot2 $(PROGRAM_OUT) $(FW_FILE) .text .data .rodata
ifeq ($(OTA),0)
flash: $(FW_FILE_1) $(FW_FILE_2) flash: $(FW_FILE_1) $(FW_FILE_2)
$(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) write_flash $(FW_1) $(FW_FILE_1) $(FW_2) $(FW_FILE_2) $(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) write_flash $(FW_ADDR_1) $(FW_FILE_1) $(FW_ADDR_2) $(FW_FILE_2)
else
flash: $(FW_FILE)
$(vecho) "Flashing OTA image slot 0 (bootloader not updated)"
$(ESPTOOL) -p $(ESPPORT) --baud $(ESPBAUD) write_flash 0x2000 $(FW_FILE)
endif
size: $(PROGRAM_OUT) size: $(PROGRAM_OUT)
$(Q) $(CROSS)size --format=sysv $(PROGRAM_OUT) $(Q) $(CROSS)size --format=sysv $(PROGRAM_OUT)

View file

@ -28,13 +28,54 @@ _lock_release_recursive = vPortExitCritical;
/* SDK compatibility */ /* SDK compatibility */
ets_printf = printf; ets_printf = printf;
/* Evaluate FLASH_SIZE to calculate irom size, etc.
*/
#ifndef OTA
#define IROM0_START 0x40240000
/* Non-OTA sizes */
#if FLASH_SIZE == 2 /* 256kB */
#define IROM0_LEN 0x3C000
#elif FLASH_SIZE == 4 /* 512kB */
#define IROM0_LEN 0x7C000
#elif FLASH_SIZE == 8 /* 1MB */
#define IROM0_LEN 0xFC000
#elif FLASH_SIZE == 16 /* 2MB */
#define IROM0_LEN 0x1FC000
#elif FLASH_SIZE == 32 /* 4MB */
#define IROM0_LEN 0x3FC000
#else /*FLASH_SIZE*/
#error "Unknown flash size for linker script. Check the FLASH_SIZE variable in your Makefile."
#endif
#else /* OTA */
/* IROM0 becomes an actual "section" of the bootloader image, so we need to leave
space for the bootloader (0x2000 bytes) and space for the bootloader & section
headers (0x10 bytes)
*/
#define IROM0_START 0x40202010
/* OTA sizes */
#if FLASH_SIZE < 16
#error "OTA support currently requires 16 or 32 megabit flash"
#elif FLASH_SIZE == 16 || FLASH_SIZE == 32
/* 1MB irom0 section regardless, minus the space for the bootloader */
#define IROM0_LEN (0x100000 - 0x2010)
#else /*FLASH_SIZE*/
#error "Unknown flash size for linker script. Check the FLASH_SIZE variable in your Makefile."
#endif
#endif
/* Linker Script for ld -N */ /* Linker Script for ld -N */
MEMORY MEMORY
{ {
dport0_0_seg : org = 0x3FF00000, len = 0x10 dport0_0_seg : org = 0x3FF00000, len = 0x10
dram0_0_seg : org = 0x3FFE8000, len = 0x14000 dram0_0_seg : org = 0x3FFE8000, len = 0x14000
iram1_0_seg : org = 0x40100000, len = 0x08000 iram1_0_seg : org = 0x40100000, len = 0x08000
irom0_0_seg : org = 0x40240000, len = 0x7C000 irom0_0_seg : org = IROM0_START, len = IROM0_LEN
} }
PHDRS PHDRS