Skip to content

Commit 34b69d8

Browse files
committed
Support for OTA in nonos-sdk and rtos-sdk
Requires package tool-genbin https://github.com/freedib/tool-genbin.git @ 1.0.0 OTA is build if board contains a build.partitions entry containing the word "ota". a good practice is to use "partitions_two_ota.csv" as in esp-idf esp8266-nonos-sdk.py and esp8266-rtos-sdk.py - change linker script LDSCRIPT_PATH if OTA - change ElfToBin builder to use genbin.py instead of esptool genbin.py allows to create user1.bin and user2.bin in one call (named firmware.bin.user1.bin and firmware.bin.user2.bin) - set correct FLASH_EXTRA_IMAGES list for flashing main.py - allow a custom bootloader like firmware.bin.user1.bin to upload platform.json - add dependency to genbin boards/esp12e_ota.json - example board for use with OTA
1 parent 325b7bc commit 34b69d8

File tree

5 files changed

+224
-79
lines changed

5 files changed

+224
-79
lines changed

boards/esp12e_ota.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"build": {
3+
"arduino": {
4+
"ldscript": "eagle.flash.4m1m.ld"
5+
},
6+
"core": "esp8266",
7+
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP12",
8+
"f_cpu": "80000000L",
9+
"f_flash": "40000000L",
10+
"flash_mode": "dio",
11+
"mcu": "esp8266",
12+
"partitions": "partitions_two_ota.csv",
13+
"variant": "nodemcu"
14+
},
15+
"connectivity": [
16+
"wifi"
17+
],
18+
"frameworks": [
19+
"arduino",
20+
"esp8266-rtos-sdk",
21+
"esp8266-nonos-sdk"
22+
],
23+
"name": "Espressif ESP8266 ESP-12E",
24+
"upload": {
25+
"maximum_ram_size": 81920,
26+
"maximum_size": 4194304,
27+
"require_upload_port": true,
28+
"resetmethod": "nodemcu",
29+
"speed": 115200
30+
},
31+
"url": "http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family",
32+
"vendor": "Espressif"
33+
}

builder/frameworks/esp8266-nonos-sdk.py

Lines changed: 81 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -97,37 +97,28 @@
9797
"airkiss", "at", "c", "crypto", "driver", "espnow", "gcc", "json",
9898
"lwip", "main", "mbedtls", "net80211", "phy", "pp", "pwm",
9999
"smartconfig", "ssl", "upgrade", "wpa", "wpa2", "wps"
100-
],
101-
102-
BUILDERS=dict(
103-
ElfToBin=Builder(
104-
action=env.VerboseAction(" ".join([
105-
'"%s"' % join(platform.get_package_dir("tool-esptool"), "esptool"),
106-
"-eo", "$SOURCE",
107-
"-bo", "${TARGET}",
108-
"-bm", "$BOARD_FLASH_MODE",
109-
"-bf", "${__get_board_f_flash(__env__)}",
110-
"-bz", "${__get_flash_size(__env__)}",
111-
"-bs", ".text",
112-
"-bs", ".data",
113-
"-bs", ".rodata",
114-
"-bc", "-ec",
115-
"-eo", "$SOURCE",
116-
"-es", ".irom0.text", "${TARGET}.irom0text.bin",
117-
"-ec", "-v"
118-
]), "Building $TARGET"),
119-
suffix=".bin"
120-
)
121-
)
100+
]
122101
)
123102

124-
if not env.BoardConfig().get("build.ldscript", ""):
125-
env.Replace(
103+
104+
###################################################################################
105+
# OTA support
106+
# common code between esp8266-nonos-sdk and esp8266-rtos-sdk for OTA support
107+
108+
board = env.BoardConfig()
109+
partitions_csv = board.get("build.partitions", "partitions_singleapp.csv")
110+
111+
# choose LDSCRIPT_PATH based on OTA
112+
if not board.get("build.ldscript", ""):
113+
if "ota" in partitions_csv: # flash map size >= 5 only!!!
114+
LDSCRIPT_PATH=join(FRAMEWORK_DIR, "ld", "eagle.app.v6.new.2048.ld")
115+
else:
126116
LDSCRIPT_PATH=join(FRAMEWORK_DIR, "ld", "eagle.app.v6.ld")
127-
)
117+
env.Replace(LDSCRIPT_PATH=LDSCRIPT_PATH)
118+
128119

129120
# evaluate SPI_FLASH_SIZE_MAP flag for NONOS_SDK 3.x and set CCFLAG
130-
board_flash_size = int(env.BoardConfig().get("upload.maximum_size", 524288))
121+
board_flash_size = int(board.get("upload.maximum_size", 524288))
131122
flash_size_maps = [0.5, 0.25, 1.0, 0.0, 0.0, 2.0, 4.0, 0.0, 8.0, 16.0] # ignore maps 3 and 4.prefer 5 and 6
132123
flash_sizes_str = ['512KB','256KB','1MB','2MB','4MB','2MB-c1','4MB-c1','4MB-c2','8MB','16MB']
133124
try:
@@ -139,24 +130,81 @@
139130
# for OTA, only size maps 5, 6, 8 and 9 are supported to avoid linking twice for user1 and user2
140131

141132
env.Append(CCFLAGS=["-DSPI_FLASH_SIZE_MAP="+str(flash_size_map)]) # NONOS-SDK 3.x user_main.c need it
133+
env.Append(FLASH_SIZE_STR=flash_size_str) # required for custom uploader
134+
135+
136+
# create binaries list to upload
142137

143-
init_data_flash_address = board_flash_size-0x4000 # 3fc000 for 4M board data_bin
138+
if "ota" in partitions_csv: # if OTA, flash user1 but generate user1 and user2
139+
boot_bin = join(FRAMEWORK_DIR, "bin", "boot_v1.7.bin")
140+
user_bin = join("$BUILD_DIR", "${PROGNAME}.bin.user1.bin") # firmware.bin.user1.bin # user1.4096.new.6.bin
141+
user_addr = 0x1000
142+
else: # non ota
143+
boot_bin = join("$BUILD_DIR", "${PROGNAME}.bin") # firmware.bin # eagle.flash.bin
144+
user_bin = join("$BUILD_DIR", "${PROGNAME}.bin.irom0text.bin") # firmware.bin.irom0text.bin # eagle.irom0text.bin
145+
if (env['PIOFRAMEWORK'][0] == "esp8266-rtos-sdk"):
146+
user_addr = 0x20000
147+
else:
148+
user_addr = 0x10000
144149

145150

146-
esp_init_data_default_file = "esp_init_data_default_v08.bin" # new in NONS 3.04
151+
# check the init_data_default file to use
152+
esp_init_data_default_file = "esp_init_data_default_v08.bin" # new in NONOS 3.04
147153
if not isfile(join(FRAMEWORK_DIR, "bin", esp_init_data_default_file)):
148154
esp_init_data_default_file = "esp_init_data_default.bin"
155+
156+
data_bin = join(FRAMEWORK_DIR, "bin", esp_init_data_default_file)
157+
blank_bin = join(FRAMEWORK_DIR, "bin", "blank.bin")
158+
rf_cal_addr = board_flash_size-0x5000 # 3fb000 for 4M board blank_bin
159+
phy_data_addr = board_flash_size-0x4000 # 3fc000 for 4M board data_bin
160+
sys_param_addr = board_flash_size-0x2000 # 3fe000 for 4M board blank_bin
149161

150162
env.Append(
151163
FLASH_EXTRA_IMAGES=[
152-
("0x10000", join("$BUILD_DIR", "${PROGNAME}.bin.irom0text.bin")),
153-
(hex(init_data_flash_address),
154-
join(FRAMEWORK_DIR, "bin", esp_init_data_default_file)),
155-
(hex(init_data_flash_address + 0x2000),
156-
join(FRAMEWORK_DIR, "bin", "blank.bin"))
164+
(hex(0), boot_bin),
165+
(hex(user_addr), user_bin),
166+
(hex(phy_data_addr), data_bin),
167+
(hex(sys_param_addr), blank_bin),
168+
(hex(rf_cal_addr), blank_bin),
169+
("--flash_mode", "$BOARD_FLASH_MODE"),
170+
("--flash_freq", "$${__get_board_f_flash(__env__)}m"),
171+
("--flash_size", "$FLASH_SIZE_STR") # required by NONOS 3.0.4
157172
]
158173
)
159174

175+
# register genbin.py BUILDER which allows to create OTA files
176+
if "ota" in partitions_csv: # if OTA, flash user1 but generate user1 and user2
177+
env.Append(
178+
BUILDERS=dict(
179+
ElfToBin=Builder(
180+
action=env.VerboseAction(" ".join([
181+
'"%s"' % env.subst("$PYTHONEXE"), join(platform.get_package_dir("tool-genbin"), "genbin.py"),
182+
"12", # create firmware.bin.user1.bin and firmware.bin.user2.bin
183+
"$BOARD_FLASH_MODE", "${__get_board_f_flash(__env__)}m", "$FLASH_SIZE_STR",
184+
"$SOURCE", "${TARGET}.user1.bin", "${TARGET}.user2.bin"
185+
# could have used espressif naming: user1.4096.new.6.bin or user1.16384.new.9.bin
186+
]), "Building $TARGET"),
187+
suffix=".bin"
188+
)
189+
)
190+
)
191+
else:
192+
env.Append(
193+
BUILDERS=dict(
194+
ElfToBin=Builder(
195+
action=env.VerboseAction(" ".join([
196+
'"%s"' % env.subst("$PYTHONEXE"), join(platform.get_package_dir("tool-genbin"), "genbin.py"),
197+
"0", # create firmware.bin and firmware.bin.irom0text.bin
198+
"$BOARD_FLASH_MODE", "${__get_board_f_flash(__env__)}m", "$FLASH_SIZE_STR",
199+
"$SOURCE", "${TARGET}", "${TARGET}.irom0text.bin"
200+
]), "Building $TARGET"),
201+
suffix=".bin"
202+
)
203+
)
204+
)
205+
206+
###################################################################################
207+
160208

161209
#
162210
# Target: Build Driver Library

builder/frameworks/esp8266-rtos-sdk.py

Lines changed: 101 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
https://github.com/espressif/ESP8266_RTOS_SDK
2222
"""
2323

24-
from os.path import isdir, join
24+
from os.path import isdir, join, isfile
2525

2626
from SCons.Script import Builder, DefaultEnvironment
2727

@@ -106,60 +106,115 @@
106106
"cirom", "crypto", "driver", "espconn", "espnow", "freertos", "gcc",
107107
"json", "hal", "lwip", "main", "mbedtls", "mesh", "mirom", "net80211", "nopoll",
108108
"phy", "pp", "pwm", "smartconfig", "spiffs", "ssl", "wpa", "wps"
109-
],
110-
111-
BUILDERS=dict(
112-
ElfToBin=Builder(
113-
action=env.VerboseAction(" ".join([
114-
'"%s"' % join(platform.get_package_dir("tool-esptool"), "esptool"),
115-
"-eo", "$SOURCE",
116-
"-bo", "${TARGET}",
117-
"-bm", "$BOARD_FLASH_MODE",
118-
"-bf", "${__get_board_f_flash(__env__)}",
119-
"-bz", "${__get_flash_size(__env__)}",
120-
"-bs", ".text",
121-
"-bs", ".data",
122-
"-bs", ".rodata",
123-
"-bc", "-ec",
124-
"-eo", "$SOURCE",
125-
"-es", ".irom0.text", "${TARGET}.irom0text.bin",
126-
"-ec", "-v"
127-
]), "Building $TARGET"),
128-
suffix=".bin"
129-
)
130-
)
109+
]
131110
)
132111

133-
if not env.BoardConfig().get("build.ldscript", ""):
134-
env.Replace(
135-
LDSCRIPT_PATH=join(FRAMEWORK_DIR, "ld", "eagle.app.v6.ld"),
136-
)
137112

138-
# Extra flash images
139-
board_flash_size = int(env.BoardConfig().get("upload.maximum_size", 0))
140-
if board_flash_size > 8388608:
141-
init_data_flash_address = 0xffc000 # for 16 MB
142-
elif board_flash_size > 4194304:
143-
init_data_flash_address = 0x7fc000 # for 8 MB
144-
elif board_flash_size > 2097152:
145-
init_data_flash_address = 0x3fc000 # for 4 MB
146-
elif board_flash_size > 1048576:
147-
init_data_flash_address = 0x1fc000 # for 2 MB
148-
elif board_flash_size > 524288:
149-
init_data_flash_address = 0xfc000 # for 1 MB
150-
else:
151-
init_data_flash_address = 0x7c000 # for 512 kB
113+
###################################################################################
114+
# OTA support
115+
# common code between esp8266-nonos-sdk and esp8266-rtos-sdk for OTA support
116+
117+
board = env.BoardConfig()
118+
partitions_csv = board.get("build.partitions", "partitions_singleapp.csv")
119+
120+
# choose LDSCRIPT_PATH based on OTA
121+
if not board.get("build.ldscript", ""):
122+
if "ota" in partitions_csv: # flash map size >= 5 only!!!
123+
LDSCRIPT_PATH=join(FRAMEWORK_DIR, "ld", "eagle.app.v6.new.2048.ld")
124+
else:
125+
LDSCRIPT_PATH=join(FRAMEWORK_DIR, "ld", "eagle.app.v6.ld")
126+
env.Replace(LDSCRIPT_PATH=LDSCRIPT_PATH)
127+
128+
129+
# evaluate SPI_FLASH_SIZE_MAP flag for NONOS_SDK 3.x and set CCFLAG
130+
board_flash_size = int(board.get("upload.maximum_size", 524288))
131+
flash_size_maps = [0.5, 0.25, 1.0, 0.0, 0.0, 2.0, 4.0, 0.0, 8.0, 16.0] # ignore maps 3 and 4.prefer 5 and 6
132+
flash_sizes_str = ['512KB','256KB','1MB','2MB','4MB','2MB-c1','4MB-c1','4MB-c2','8MB','16MB']
133+
try:
134+
flash_size_map = flash_size_maps.index(board_flash_size/1048576)
135+
flash_size_str = flash_sizes_str[flash_size_map]
136+
except:
137+
flash_size_map = 6
138+
flash_size_str = '4MB-c1'
139+
# for OTA, only size maps 5, 6, 8 and 9 are supported to avoid linking twice for user1 and user2
140+
141+
env.Append(CCFLAGS=["-DSPI_FLASH_SIZE_MAP="+str(flash_size_map)]) # NONOS-SDK 3.x user_main.c need it
142+
env.Append(FLASH_SIZE_STR=flash_size_str) # required for custom uploader
143+
144+
145+
# create binaries list to upload
146+
147+
if "ota" in partitions_csv: # if OTA, flash user1 but generate user1 and user2
148+
boot_bin = join(FRAMEWORK_DIR, "bin", "boot_v1.7.bin")
149+
user_bin = join("$BUILD_DIR", "${PROGNAME}.bin.user1.bin") # firmware.bin.user1.bin # user1.4096.new.6.bin
150+
user_addr = 0x1000
151+
else: # non ota
152+
boot_bin = join("$BUILD_DIR", "${PROGNAME}.bin") # firmware.bin # eagle.flash.bin
153+
user_bin = join("$BUILD_DIR", "${PROGNAME}.bin.irom0text.bin") # firmware.bin.irom0text.bin # eagle.irom0text.bin
154+
if (env['PIOFRAMEWORK'][0] == "esp8266-rtos-sdk"):
155+
user_addr = 0x20000
156+
else:
157+
user_addr = 0x10000
158+
159+
160+
# check the init_data_default file to use
161+
esp_init_data_default_file = "esp_init_data_default_v08.bin" # new in NONOS 3.04
162+
if not isfile(join(FRAMEWORK_DIR, "bin", esp_init_data_default_file)):
163+
esp_init_data_default_file = "esp_init_data_default.bin"
164+
165+
data_bin = join(FRAMEWORK_DIR, "bin", esp_init_data_default_file)
166+
blank_bin = join(FRAMEWORK_DIR, "bin", "blank.bin")
167+
rf_cal_addr = board_flash_size-0x5000 # 3fb000 for 4M board blank_bin
168+
phy_data_addr = board_flash_size-0x4000 # 3fc000 for 4M board data_bin
169+
sys_param_addr = board_flash_size-0x2000 # 3fe000 for 4M board blank_bin
152170

153171
env.Append(
154172
FLASH_EXTRA_IMAGES=[
155-
("0x20000", join("$BUILD_DIR", "${PROGNAME}.bin.irom0text.bin")),
156-
(hex(init_data_flash_address),
157-
join(FRAMEWORK_DIR, "bin", "esp_init_data_default.bin")),
158-
(hex(init_data_flash_address + 0x2000),
159-
join(FRAMEWORK_DIR, "bin", "blank.bin"))
173+
(hex(0), boot_bin),
174+
(hex(user_addr), user_bin),
175+
(hex(phy_data_addr), data_bin),
176+
(hex(sys_param_addr), blank_bin),
177+
(hex(rf_cal_addr), blank_bin),
178+
("--flash_mode", "$BOARD_FLASH_MODE"),
179+
("--flash_freq", "$${__get_board_f_flash(__env__)}m"),
180+
("--flash_size", "$FLASH_SIZE_STR") # required by NONOS 3.0.4
160181
]
161182
)
162183

184+
# register genbin.py BUILDER which allows to create OTA files
185+
if "ota" in partitions_csv: # if OTA, flash user1 but generate user1 and user2
186+
env.Append(
187+
BUILDERS=dict(
188+
ElfToBin=Builder(
189+
action=env.VerboseAction(" ".join([
190+
'"%s"' % env.subst("$PYTHONEXE"), join(platform.get_package_dir("tool-genbin"), "genbin.py"),
191+
"12", # create firmware.bin.user1.bin and firmware.bin.user2.bin
192+
"$BOARD_FLASH_MODE", "${__get_board_f_flash(__env__)}m", "$FLASH_SIZE_STR",
193+
"$SOURCE", "${TARGET}.user1.bin", "${TARGET}.user2.bin"
194+
# could have used espressif naming: user1.4096.new.6.bin or user1.16384.new.9.bin
195+
]), "Building $TARGET"),
196+
suffix=".bin"
197+
)
198+
)
199+
)
200+
else:
201+
env.Append(
202+
BUILDERS=dict(
203+
ElfToBin=Builder(
204+
action=env.VerboseAction(" ".join([
205+
'"%s"' % env.subst("$PYTHONEXE"), join(platform.get_package_dir("tool-genbin"), "genbin.py"),
206+
"0", # create firmware.bin and firmware.bin.irom0text.bin
207+
"$BOARD_FLASH_MODE", "${__get_board_f_flash(__env__)}m", "$FLASH_SIZE_STR",
208+
"$SOURCE", "${TARGET}", "${TARGET}.irom0text.bin"
209+
]), "Building $TARGET"),
210+
suffix=".bin"
211+
)
212+
)
213+
)
214+
215+
###################################################################################
216+
217+
163218
#
164219
# Target: Build Driver Library
165220
#

builder/main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ def get_esptoolpy_reset_flags(resetmethod):
325325
UPLOADCMD='"$PYTHONEXE" "$UPLOADER" $UPLOADERFLAGS 0x0 $SOURCE'
326326
)
327327
for image in env.get("FLASH_EXTRA_IMAGES", []):
328+
if image[0]=='0x0': # a bootloader is furnished. clean the UPLOADCMD
329+
env.Replace(
330+
UPLOADCMD='"$PYTHONEXE" "$UPLOADER" $UPLOADERFLAGS'
331+
)
328332
env.Append(UPLOADERFLAGS=[image[0], env.subst(image[1])])
329333

330334
if "uploadfs" in COMMAND_LINE_TARGETS:

platform.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@
6363
"owner": "platformio",
6464
"version": "~3.0.5"
6565
},
66+
"tool-genbin": {
67+
"type": "uploader",
68+
"owner": "platformio",
69+
"version": "~1.0.0"
70+
},
6671
"tool-esptool": {
6772
"type": "uploader",
6873
"owner": "platformio",

0 commit comments

Comments
 (0)