Skip to content

Commit

Permalink
Merge branch 'feature/v2_bootloader_load_v3_firmware' into 'master'
Browse files Browse the repository at this point in the history
Support V2 firmware update to V3 by OTA

See merge request sdk/ESP8266_RTOS_SDK!628
  • Loading branch information
donghengqaz committed Jan 16, 2019
2 parents ef79175 + 11db1b0 commit a2b7521
Show file tree
Hide file tree
Showing 18 changed files with 752 additions and 15 deletions.
6 changes: 0 additions & 6 deletions components/app_update/esp_ota_ops.c
Expand Up @@ -539,13 +539,10 @@ const esp_partition_t* esp_ota_get_running_partition(void)
/* Find the flash address of this exact function. By definition that is part
of the currently running firmware. Then find the enclosing partition. */

#ifdef CONFIG_TARGET_PLATFORM_ESP32
size_t phys_offs = spi_flash_cache2phys(esp_ota_get_running_partition);

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

#if CONFIG_TARGET_PLATFORM_ESP32
esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_APP,
ESP_PARTITION_SUBTYPE_ANY,
NULL);
Expand All @@ -561,9 +558,6 @@ const esp_partition_t* esp_ota_get_running_partition(void)
}

abort(); /* Partition table is invalid or corrupt */
#else
return esp_ota_get_boot_partition();
#endif
}


Expand Down
13 changes: 13 additions & 0 deletions components/bootloader/subproject/main/bootloader_start.c
Expand Up @@ -21,6 +21,7 @@
#include "bootloader_common.h"
#include "esp_image_format.h"
#include "esp_log.h"
#include "esp_spi_flash.h"

static const char* TAG = "boot";

Expand Down Expand Up @@ -112,6 +113,18 @@ static int selected_boot_partition(const bootloader_state_t *bs)
}
#endif
}
#endif
#ifdef CONFIG_ESP8266_BOOT_COPY_APP
if (boot_index == 1) {
ESP_LOGI(TAG, "Copy application from OAT1 to OTA0, please wait ...");
int ret = esp_patition_copy_ota1_to_ota0(bs);
if (ret) {
ESP_LOGE(TAG, "Fail to initialize OTA0");
return INVALID_INDEX;
}

boot_index = 0;
}
#endif
// Customer implementation.
// if (gpio_pin_1 == true && ...){
Expand Down
4 changes: 2 additions & 2 deletions components/bootloader/subproject/main/esp8266.bootloader.ld
Expand Up @@ -12,8 +12,8 @@ MEMORY
{
dport0_seg : org = 0x3FF00000, len = 0x10

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

/* Functions which are critical should be put in this segment. */
iram_seg : org = 0x40100000, len = 0x8000
Expand Down
@@ -1,6 +1,8 @@
PROVIDE ( ets_memcpy = 0x400018b4 );

PROVIDE ( SPIRead = 0x40004b1c );
PROVIDE ( SPIWrite = 0x40004a4c );
PROVIDE ( SPIEraseSector = 0x40004a00 );

PROVIDE ( gpio_input_get = 0x40004cf0 );

Expand Down
2 changes: 2 additions & 0 deletions components/bootloader_support/src/bootloader_init.c
Expand Up @@ -648,6 +648,8 @@ static void update_flash_config(const esp_image_header_t* pfhdr)

ESP_LOGD(TAG, "bootloader initialize SPI flash clock and I/O");
#endif /* CONFIG_BOOTLOADER_INIT_SPI_FLASH */

Cache_Read_Disable();
}

static void print_flash_info(const esp_image_header_t* phdr)
Expand Down
15 changes: 15 additions & 0 deletions components/bootloader_support/src/bootloader_utility.c
Expand Up @@ -512,6 +512,13 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs)
esp_err_t err;
int num_partitions;

#ifdef CONFIG_ESP8266_OTA_FROM_OLD
if (esp_patition_table_init_location()) {
ESP_LOGE(TAG, "Failed to update partition table location");
return false;
}
#endif

#ifdef CONFIG_SECURE_BOOT_ENABLED
if(esp_secure_boot_enabled()) {
ESP_LOGI(TAG, "Verifying partition table signature...");
Expand Down Expand Up @@ -605,6 +612,14 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs)

bootloader_munmap(partitions);

#ifdef CONFIG_ESP8266_OTA_FROM_OLD
ESP_LOGI(TAG, "Copy firmware ...");
if (esp_patition_table_init_data(bs)) {
ESP_LOGE(TAG,"Failed to update partition data");
return false;
}
#endif

ESP_LOGI(TAG,"End of partition table");
return true;
}
Expand Down
22 changes: 22 additions & 0 deletions components/esp8266/Kconfig
Expand Up @@ -213,6 +213,28 @@ config CRYSTAL_USED_40MHZ
bool "40MHz"
endchoice

config ESP8266_OTA_FROM_OLD
bool "(**Expected**)ESP8266 update from old SDK by OTA"
default n
depends on TARGET_PLATFORM_ESP8266
select ESP8266_BOOT_COPY_APP
help
The function is not released.

Enable this option, script will generate the complete firmware for both old RTOS SDK(before V3.0)
and NonOS SDK to update to v3 by OTA.

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.

config ESP8266_BOOT_COPY_APP
bool "(**Expected**)Boot copy app"
default n
help
The function is not released.

Enable this option, when it is that "OTA1" application is to run after update by OTA,
bootloader will copy "OTA1" application to "OTA0" partition and run "OTA0".

endmenu

menu WIFI
Expand Down
29 changes: 27 additions & 2 deletions components/esp8266/Makefile.projbuild
Expand Up @@ -89,10 +89,22 @@ OTA_BIN := ./build/$(PROJECT_NAME).ota.bin
OTA1_BIN := ./build/$(PROJECT_NAME).app1.bin
OTA2_BIN := ./build/$(PROJECT_NAME).app2.bin

OTA_V2_TO_V3_BIN := ./build/$(PROJECT_NAME).v2_to_v3.ota.bin

CONFIG_APP2_OFFSET ?= $(CONFIG_APP1_OFFSET)
CONFIG_APP2_SIZE ?= $(CONFIG_APP1_SIZE)

OTA1_OFFSET := CONFIG_APP1_OFFSET
ifdef CONFIG_ESP8266_BOOT_COPY_APP
OTA2_LINK_OFFSET := $(CONFIG_APP1_OFFSET)
else
OTA2_LINK_OFFSET := $(CONFIG_APP2_OFFSET)
endif

$(OTA2_BIN): all_binaries
ifeq ($(CONFIG_ESPTOOLPY_FLASHSIZE), "1MB")
@rm -f ./build/esp8266/esp8266_out.ld
@make APP_OFFSET=$(CONFIG_APP2_OFFSET) APP_SIZE=$(CONFIG_APP2_SIZE) CFLAGS= CXXFLAGS=
@make APP_OFFSET=$(OTA2_LINK_OFFSET) APP_SIZE=$(CONFIG_APP2_SIZE) CFLAGS= CXXFLAGS=
endif
@cp $(RAW_BIN) $(OTA2_BIN)
@echo [GEN] $(OTA2_BIN)
Expand All @@ -113,9 +125,22 @@ endif
@cp $(OTA1_BIN) $(RAW_BIN)
@echo [GEN] $(OTA_BIN)

ifdef CONFIG_ESP8266_OTA_FROM_OLD
$(OTA_V2_TO_V3_BIN): $(OTA_BIN)
@cp $(RAW_BIN) $(RAW_BIN).tmp.bak
@cp $(OTA1_BIN) $(RAW_BIN)
@python $(IDF_PATH)/tools/pack_fw.py --output $(OTA_V2_TO_V3_BIN) pack3 $(ESPTOOL_ALL_FLASH_ARGS)
@cp $(RAW_BIN).tmp.bak $(RAW_BIN)
@echo [GEN] $(OTA_V2_TO_V3_BIN)
endif

ifdef CONFIG_ESP8266_OTA_FROM_OLD
ota: $(OTA_V2_TO_V3_BIN)
else
ota: $(OTA_BIN)
endif

ota-clean:
@rm -f $(OTA_BIN) $(OTA1_BIN) $(OTA2_BIN)
@rm -f $(OTA_BIN) $(OTA1_BIN) $(OTA2_BIN) $(OTA_V2_TO_V3_BIN)

clean: ota-clean
6 changes: 6 additions & 0 deletions components/esp8266/include/esp8266/eagle_soc.h
Expand Up @@ -140,6 +140,12 @@
#define WDT_CTL_EN_LSB 0

#define WDT_FEED_VALUE 0x73

#define WDT_REG_READ(_reg) REG_READ(PERIPHS_WDT_BASEADDR + _reg)
#define WDT_REG_WRITE(_reg, _val) REG_WRITE(PERIPHS_WDT_BASEADDR + _reg, _val)
#define CLEAR_WDT_REG_MASK(_reg, _mask) WDT_REG_WRITE(_reg, WDT_REG_READ(_reg) & (~_mask))
#define WDT_FEED() WDT_REG_WRITE(WDT_RST_ADDRESS, WDT_FEED_VALUE)

//}}

//RTC reg {{
Expand Down
4 changes: 4 additions & 0 deletions components/esp8266/include/esp8266/rom_functions.h
Expand Up @@ -33,6 +33,10 @@ int SPI_write_status(esp_spi_flash_chip_t *chip, uint32_t status);
int SPI_read_status(esp_spi_flash_chip_t *chip, uint32_t *status);
int Enable_QMode(esp_spi_flash_chip_t *chip);

int SPIWrite(uint32_t addr, const uint8_t *src, uint32_t size);
int SPIRead(uint32_t addr, void *dst, uint32_t size);
int SPIEraseSector(uint32_t sector_num);

void Cache_Read_Disable();
void Cache_Read_Enable(uint8_t map, uint8_t p, uint8_t v);

Expand Down
8 changes: 8 additions & 0 deletions components/esp8266/include/esp8266/spi_register.h
Expand Up @@ -263,6 +263,14 @@ extern "C" {

#define PERIPHS_SPI_FLASH_USRREG (0x60000200 + 0x1c)

#define CACHE_MAP_1M_HIGH BIT25
#define CACHE_MAP_2M BIT24
#define CACHE_MAP_SEGMENT_S 16
#define CACHE_MAP_SEGMENT_MASK 0x3
#define CACHE_BASE_ADDR 0x40200000
#define CACHE_2M_SIZE 0x00200000
#define CACHE_1M_SIZE 0x00100000

#ifdef __cplusplus
}
#endif
5 changes: 0 additions & 5 deletions components/esp8266/source/task_wdt.c
Expand Up @@ -21,11 +21,6 @@
#include "portmacro.h"
#include "esp8266/eagle_soc.h"

#define WDT_REG_READ(_reg) REG_READ(PERIPHS_WDT_BASEADDR + _reg)
#define WDT_REG_WRITE(_reg, _val) REG_WRITE(PERIPHS_WDT_BASEADDR + _reg, _val)
#define CLEAR_WDT_REG_MASK(_reg, _mask) WDT_REG_WRITE(_reg, WDT_REG_READ(_reg) & (~_mask))
#define WDT_FEED() WDT_REG_WRITE(WDT_RST_ADDRESS, WDT_FEED_VALUE)

static const char *TAG = "wdt";

#ifdef CONFIG_TASK_WDT_PANIC
Expand Down
7 changes: 7 additions & 0 deletions components/spi_flash/component.mk
Expand Up @@ -9,3 +9,10 @@ COMPONENT_OBJS := src/spi_flash.o src/spi_flash_raw.o
endif

CFLAGS += -DPARTITION_QUEUE_HEADER=\"sys/queue.h\"

ifdef CONFIG_ESP8266_OTA_FROM_OLD
ifdef IS_BOOTLOADER_BUILD
COMPONENT_SRCDIRS += port
COMPONENT_OBJS += port/port.o
endif
endif
46 changes: 46 additions & 0 deletions components/spi_flash/include/spi_flash.h
Expand Up @@ -32,6 +32,8 @@ extern "C" {

#define SPI_READ_BUF_MAX 64

#define SPI_FLASH_CACHE2PHYS_FAIL UINT32_MAX /*<! Result from spi_flash_cache2phys() if flash cache address is invalid */

#ifdef CONFIG_ENABLE_FLASH_MMAP
/**
* @brief Enumeration which specifies memory space requested in an mmap call
Expand Down Expand Up @@ -149,6 +151,50 @@ void spi_flash_munmap(spi_flash_mmap_handle_t handle);

#endif /* CONFIG_ENABLE_FLASH_MMAP */

/**
* @brief Given a memory address where flash is mapped, return the corresponding physical flash offset.
*
* Cache address does not have have been assigned via spi_flash_mmap(), any address in memory mapped flash space can be looked up.
*
* @param cached Pointer to flashed cached memory.
*
* @return
* - SPI_FLASH_CACHE2PHYS_FAIL If cache address is outside flash cache region, or the address is not mapped.
* - Otherwise, returns physical offset in flash
*/
uintptr_t spi_flash_cache2phys(const void *cached);

#ifdef CONFIG_ESP8266_OTA_FROM_OLD

/**
* @brief Check if current firmware updates from V2 firmware and its location is at "APP2", if so, then V3 bootloader
* will copy patition table from "APP2" location to "APP1" location of V2 partition map.
*
* @return 0 if success or others if failed
*/
int esp_patition_table_init_location(void);

/**
* @brief Check if current firmware updates from V2 firmware and its location is at "APP2", if so, then V3 bootloader
* will copy firmware from "APP2" location to "APP1" location.
*
* @note All data which is copied is "ota0" application and all data whose location is before "ota0".
*
* @return 0 if success or others if failed
*/
int esp_patition_table_init_data(void *partition_info);
#endif

#ifdef CONFIG_ESP8266_BOOT_COPY_APP
/**
* @brief Check if current application which is to run is at "ota1" location, if so, bootloader will copy it to "ota0" location,
* and clear OTA data partition.
*
* @return 0 if success or others if failed
*/
int esp_patition_copy_ota1_to_ota0(const void *partition_info);
#endif

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit a2b7521

Please sign in to comment.