Skip to content

Commit a2b7521

Browse files
committed
Merge branch 'feature/v2_bootloader_load_v3_firmware' into 'master'
Support V2 firmware update to V3 by OTA See merge request sdk/ESP8266_RTOS_SDK!628
2 parents ef79175 + 11db1b0 commit a2b7521

File tree

18 files changed

+752
-15
lines changed

18 files changed

+752
-15
lines changed

components/app_update/esp_ota_ops.c

-6
Original file line numberDiff line numberDiff line change
@@ -539,13 +539,10 @@ const esp_partition_t* esp_ota_get_running_partition(void)
539539
/* Find the flash address of this exact function. By definition that is part
540540
of the currently running firmware. Then find the enclosing partition. */
541541

542-
#ifdef CONFIG_TARGET_PLATFORM_ESP32
543542
size_t phys_offs = spi_flash_cache2phys(esp_ota_get_running_partition);
544543

545544
assert (phys_offs != SPI_FLASH_CACHE2PHYS_FAIL); /* indicates cache2phys lookup is buggy */
546-
#endif
547545

548-
#if CONFIG_TARGET_PLATFORM_ESP32
549546
esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_APP,
550547
ESP_PARTITION_SUBTYPE_ANY,
551548
NULL);
@@ -561,9 +558,6 @@ const esp_partition_t* esp_ota_get_running_partition(void)
561558
}
562559

563560
abort(); /* Partition table is invalid or corrupt */
564-
#else
565-
return esp_ota_get_boot_partition();
566-
#endif
567561
}
568562

569563

components/bootloader/subproject/main/bootloader_start.c

+13
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "bootloader_common.h"
2222
#include "esp_image_format.h"
2323
#include "esp_log.h"
24+
#include "esp_spi_flash.h"
2425

2526
static const char* TAG = "boot";
2627

@@ -112,6 +113,18 @@ static int selected_boot_partition(const bootloader_state_t *bs)
112113
}
113114
#endif
114115
}
116+
#endif
117+
#ifdef CONFIG_ESP8266_BOOT_COPY_APP
118+
if (boot_index == 1) {
119+
ESP_LOGI(TAG, "Copy application from OAT1 to OTA0, please wait ...");
120+
int ret = esp_patition_copy_ota1_to_ota0(bs);
121+
if (ret) {
122+
ESP_LOGE(TAG, "Fail to initialize OTA0");
123+
return INVALID_INDEX;
124+
}
125+
126+
boot_index = 0;
127+
}
115128
#endif
116129
// Customer implementation.
117130
// if (gpio_pin_1 == true && ...){

components/bootloader/subproject/main/esp8266.bootloader.ld

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ MEMORY
1212
{
1313
dport0_seg : org = 0x3FF00000, len = 0x10
1414

15-
/* All .data/.bss/heap are in this segment. */
16-
dram_seg : org = 0x3FFE8000, len = 0x18000
15+
/* All .data/.bss/heap are in this segment. Reserve 1KB for old boot or ROM boot */
16+
dram_seg : org = 0x3FFE8000, len = 0x18000 - 0x400
1717

1818
/* Functions which are critical should be put in this segment. */
1919
iram_seg : org = 0x40100000, len = 0x8000

components/bootloader/subproject/main/esp8266.bootloader.rom.ld

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
PROVIDE ( ets_memcpy = 0x400018b4 );
22

33
PROVIDE ( SPIRead = 0x40004b1c );
4+
PROVIDE ( SPIWrite = 0x40004a4c );
5+
PROVIDE ( SPIEraseSector = 0x40004a00 );
46

57
PROVIDE ( gpio_input_get = 0x40004cf0 );
68

components/bootloader_support/src/bootloader_init.c

+2
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,8 @@ static void update_flash_config(const esp_image_header_t* pfhdr)
648648

649649
ESP_LOGD(TAG, "bootloader initialize SPI flash clock and I/O");
650650
#endif /* CONFIG_BOOTLOADER_INIT_SPI_FLASH */
651+
652+
Cache_Read_Disable();
651653
}
652654

653655
static void print_flash_info(const esp_image_header_t* phdr)

components/bootloader_support/src/bootloader_utility.c

+15
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,13 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs)
512512
esp_err_t err;
513513
int num_partitions;
514514

515+
#ifdef CONFIG_ESP8266_OTA_FROM_OLD
516+
if (esp_patition_table_init_location()) {
517+
ESP_LOGE(TAG, "Failed to update partition table location");
518+
return false;
519+
}
520+
#endif
521+
515522
#ifdef CONFIG_SECURE_BOOT_ENABLED
516523
if(esp_secure_boot_enabled()) {
517524
ESP_LOGI(TAG, "Verifying partition table signature...");
@@ -605,6 +612,14 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs)
605612

606613
bootloader_munmap(partitions);
607614

615+
#ifdef CONFIG_ESP8266_OTA_FROM_OLD
616+
ESP_LOGI(TAG, "Copy firmware ...");
617+
if (esp_patition_table_init_data(bs)) {
618+
ESP_LOGE(TAG,"Failed to update partition data");
619+
return false;
620+
}
621+
#endif
622+
608623
ESP_LOGI(TAG,"End of partition table");
609624
return true;
610625
}

components/esp8266/Kconfig

+22
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,28 @@ config CRYSTAL_USED_40MHZ
213213
bool "40MHz"
214214
endchoice
215215

216+
config ESP8266_OTA_FROM_OLD
217+
bool "(**Expected**)ESP8266 update from old SDK by OTA"
218+
default n
219+
depends on TARGET_PLATFORM_ESP8266
220+
select ESP8266_BOOT_COPY_APP
221+
help
222+
The function is not released.
223+
224+
Enable this option, script will generate the complete firmware for both old RTOS SDK(before V3.0)
225+
and NonOS SDK to update to v3 by OTA.
226+
227+
The old RTOS SDK(before V3.0) or NonOS SDK can download the firmware to its partition and run it as it self's application.
228+
229+
config ESP8266_BOOT_COPY_APP
230+
bool "(**Expected**)Boot copy app"
231+
default n
232+
help
233+
The function is not released.
234+
235+
Enable this option, when it is that "OTA1" application is to run after update by OTA,
236+
bootloader will copy "OTA1" application to "OTA0" partition and run "OTA0".
237+
216238
endmenu
217239

218240
menu WIFI

components/esp8266/Makefile.projbuild

+27-2
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,22 @@ OTA_BIN := ./build/$(PROJECT_NAME).ota.bin
8989
OTA1_BIN := ./build/$(PROJECT_NAME).app1.bin
9090
OTA2_BIN := ./build/$(PROJECT_NAME).app2.bin
9191

92+
OTA_V2_TO_V3_BIN := ./build/$(PROJECT_NAME).v2_to_v3.ota.bin
93+
94+
CONFIG_APP2_OFFSET ?= $(CONFIG_APP1_OFFSET)
95+
CONFIG_APP2_SIZE ?= $(CONFIG_APP1_SIZE)
96+
97+
OTA1_OFFSET := CONFIG_APP1_OFFSET
98+
ifdef CONFIG_ESP8266_BOOT_COPY_APP
99+
OTA2_LINK_OFFSET := $(CONFIG_APP1_OFFSET)
100+
else
101+
OTA2_LINK_OFFSET := $(CONFIG_APP2_OFFSET)
102+
endif
103+
92104
$(OTA2_BIN): all_binaries
93105
ifeq ($(CONFIG_ESPTOOLPY_FLASHSIZE), "1MB")
94106
@rm -f ./build/esp8266/esp8266_out.ld
95-
@make APP_OFFSET=$(CONFIG_APP2_OFFSET) APP_SIZE=$(CONFIG_APP2_SIZE) CFLAGS= CXXFLAGS=
107+
@make APP_OFFSET=$(OTA2_LINK_OFFSET) APP_SIZE=$(CONFIG_APP2_SIZE) CFLAGS= CXXFLAGS=
96108
endif
97109
@cp $(RAW_BIN) $(OTA2_BIN)
98110
@echo [GEN] $(OTA2_BIN)
@@ -113,9 +125,22 @@ endif
113125
@cp $(OTA1_BIN) $(RAW_BIN)
114126
@echo [GEN] $(OTA_BIN)
115127

128+
ifdef CONFIG_ESP8266_OTA_FROM_OLD
129+
$(OTA_V2_TO_V3_BIN): $(OTA_BIN)
130+
@cp $(RAW_BIN) $(RAW_BIN).tmp.bak
131+
@cp $(OTA1_BIN) $(RAW_BIN)
132+
@python $(IDF_PATH)/tools/pack_fw.py --output $(OTA_V2_TO_V3_BIN) pack3 $(ESPTOOL_ALL_FLASH_ARGS)
133+
@cp $(RAW_BIN).tmp.bak $(RAW_BIN)
134+
@echo [GEN] $(OTA_V2_TO_V3_BIN)
135+
endif
136+
137+
ifdef CONFIG_ESP8266_OTA_FROM_OLD
138+
ota: $(OTA_V2_TO_V3_BIN)
139+
else
116140
ota: $(OTA_BIN)
141+
endif
117142

118143
ota-clean:
119-
@rm -f $(OTA_BIN) $(OTA1_BIN) $(OTA2_BIN)
144+
@rm -f $(OTA_BIN) $(OTA1_BIN) $(OTA2_BIN) $(OTA_V2_TO_V3_BIN)
120145

121146
clean: ota-clean

components/esp8266/include/esp8266/eagle_soc.h

+6
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@
140140
#define WDT_CTL_EN_LSB 0
141141

142142
#define WDT_FEED_VALUE 0x73
143+
144+
#define WDT_REG_READ(_reg) REG_READ(PERIPHS_WDT_BASEADDR + _reg)
145+
#define WDT_REG_WRITE(_reg, _val) REG_WRITE(PERIPHS_WDT_BASEADDR + _reg, _val)
146+
#define CLEAR_WDT_REG_MASK(_reg, _mask) WDT_REG_WRITE(_reg, WDT_REG_READ(_reg) & (~_mask))
147+
#define WDT_FEED() WDT_REG_WRITE(WDT_RST_ADDRESS, WDT_FEED_VALUE)
148+
143149
//}}
144150

145151
//RTC reg {{

components/esp8266/include/esp8266/rom_functions.h

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ int SPI_write_status(esp_spi_flash_chip_t *chip, uint32_t status);
3333
int SPI_read_status(esp_spi_flash_chip_t *chip, uint32_t *status);
3434
int Enable_QMode(esp_spi_flash_chip_t *chip);
3535

36+
int SPIWrite(uint32_t addr, const uint8_t *src, uint32_t size);
37+
int SPIRead(uint32_t addr, void *dst, uint32_t size);
38+
int SPIEraseSector(uint32_t sector_num);
39+
3640
void Cache_Read_Disable();
3741
void Cache_Read_Enable(uint8_t map, uint8_t p, uint8_t v);
3842

components/esp8266/include/esp8266/spi_register.h

+8
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@ extern "C" {
263263

264264
#define PERIPHS_SPI_FLASH_USRREG (0x60000200 + 0x1c)
265265

266+
#define CACHE_MAP_1M_HIGH BIT25
267+
#define CACHE_MAP_2M BIT24
268+
#define CACHE_MAP_SEGMENT_S 16
269+
#define CACHE_MAP_SEGMENT_MASK 0x3
270+
#define CACHE_BASE_ADDR 0x40200000
271+
#define CACHE_2M_SIZE 0x00200000
272+
#define CACHE_1M_SIZE 0x00100000
273+
266274
#ifdef __cplusplus
267275
}
268276
#endif

components/esp8266/source/task_wdt.c

-5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,6 @@
2121
#include "portmacro.h"
2222
#include "esp8266/eagle_soc.h"
2323

24-
#define WDT_REG_READ(_reg) REG_READ(PERIPHS_WDT_BASEADDR + _reg)
25-
#define WDT_REG_WRITE(_reg, _val) REG_WRITE(PERIPHS_WDT_BASEADDR + _reg, _val)
26-
#define CLEAR_WDT_REG_MASK(_reg, _mask) WDT_REG_WRITE(_reg, WDT_REG_READ(_reg) & (~_mask))
27-
#define WDT_FEED() WDT_REG_WRITE(WDT_RST_ADDRESS, WDT_FEED_VALUE)
28-
2924
static const char *TAG = "wdt";
3025

3126
#ifdef CONFIG_TASK_WDT_PANIC

components/spi_flash/component.mk

+7
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,10 @@ COMPONENT_OBJS := src/spi_flash.o src/spi_flash_raw.o
99
endif
1010

1111
CFLAGS += -DPARTITION_QUEUE_HEADER=\"sys/queue.h\"
12+
13+
ifdef CONFIG_ESP8266_OTA_FROM_OLD
14+
ifdef IS_BOOTLOADER_BUILD
15+
COMPONENT_SRCDIRS += port
16+
COMPONENT_OBJS += port/port.o
17+
endif
18+
endif

components/spi_flash/include/spi_flash.h

+46
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ extern "C" {
3232

3333
#define SPI_READ_BUF_MAX 64
3434

35+
#define SPI_FLASH_CACHE2PHYS_FAIL UINT32_MAX /*<! Result from spi_flash_cache2phys() if flash cache address is invalid */
36+
3537
#ifdef CONFIG_ENABLE_FLASH_MMAP
3638
/**
3739
* @brief Enumeration which specifies memory space requested in an mmap call
@@ -149,6 +151,50 @@ void spi_flash_munmap(spi_flash_mmap_handle_t handle);
149151

150152
#endif /* CONFIG_ENABLE_FLASH_MMAP */
151153

154+
/**
155+
* @brief Given a memory address where flash is mapped, return the corresponding physical flash offset.
156+
*
157+
* Cache address does not have have been assigned via spi_flash_mmap(), any address in memory mapped flash space can be looked up.
158+
*
159+
* @param cached Pointer to flashed cached memory.
160+
*
161+
* @return
162+
* - SPI_FLASH_CACHE2PHYS_FAIL If cache address is outside flash cache region, or the address is not mapped.
163+
* - Otherwise, returns physical offset in flash
164+
*/
165+
uintptr_t spi_flash_cache2phys(const void *cached);
166+
167+
#ifdef CONFIG_ESP8266_OTA_FROM_OLD
168+
169+
/**
170+
* @brief Check if current firmware updates from V2 firmware and its location is at "APP2", if so, then V3 bootloader
171+
* will copy patition table from "APP2" location to "APP1" location of V2 partition map.
172+
*
173+
* @return 0 if success or others if failed
174+
*/
175+
int esp_patition_table_init_location(void);
176+
177+
/**
178+
* @brief Check if current firmware updates from V2 firmware and its location is at "APP2", if so, then V3 bootloader
179+
* will copy firmware from "APP2" location to "APP1" location.
180+
*
181+
* @note All data which is copied is "ota0" application and all data whose location is before "ota0".
182+
*
183+
* @return 0 if success or others if failed
184+
*/
185+
int esp_patition_table_init_data(void *partition_info);
186+
#endif
187+
188+
#ifdef CONFIG_ESP8266_BOOT_COPY_APP
189+
/**
190+
* @brief Check if current application which is to run is at "ota1" location, if so, bootloader will copy it to "ota0" location,
191+
* and clear OTA data partition.
192+
*
193+
* @return 0 if success or others if failed
194+
*/
195+
int esp_patition_copy_ota1_to_ota0(const void *partition_info);
196+
#endif
197+
152198
#ifdef __cplusplus
153199
}
154200
#endif

0 commit comments

Comments
 (0)