diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 5d2dad2e..50c7633c 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -19,6 +19,13 @@ config BOOTLOADER_DISABLE_JTAG_IO If users use JTAG to help develop, please disable this option. +config BOOTLOADER_FAST_BOOT + bool "Bootloader fast boot" + default n + help + Enable this option, after initializing hardware, bootloader will try to load boot image + information from RTC memory directly and then run image without verifying it. + choice LOG_BOOTLOADER_LEVEL bool "Bootloader log verbosity" default LOG_BOOTLOADER_LEVEL_INFO diff --git a/components/bootloader/subproject/main/bootloader_start.c b/components/bootloader/subproject/main/bootloader_start.c index cdcc9b20..3ba0adde 100644 --- a/components/bootloader/subproject/main/bootloader_start.c +++ b/components/bootloader/subproject/main/bootloader_start.c @@ -30,11 +30,19 @@ static int selected_boot_partition(const bootloader_state_t *bs); void call_start_cpu(void) { +#ifdef CONFIG_BOOTLOADER_FAST_BOOT + REG_SET_BIT(DPORT_CTL_REG, DPORT_CTL_DOUBLE_CLK); +#endif + // 1. Hardware initialization if(bootloader_init() != ESP_OK){ return; } +#ifdef CONFIG_BOOTLOADER_FAST_BOOT + bootloader_utility_fast_boot_image(); +#endif + // 2. Select image to boot esp_image_metadata_t image_data; if(select_image(&image_data) != ESP_OK){ diff --git a/components/bootloader_support/include_priv/bootloader_utility.h b/components/bootloader_support/include_priv/bootloader_utility.h index 6cf6a77e..a2bc8328 100644 --- a/components/bootloader_support/include_priv/bootloader_utility.h +++ b/components/bootloader_support/include_priv/bootloader_utility.h @@ -62,3 +62,8 @@ bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_ * @param[in] data Structure to hold on-flash image metadata. */ void bootloader_utility_load_image(const esp_image_metadata_t* image_data); + +/** + * @brief Loading boot image information from RTC memory and then running image without verifying. + */ +void bootloader_utility_fast_boot_image(void); diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index a792caf8..da06ce3d 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -493,6 +493,7 @@ static void set_cache_and_start_app( #include "esp_log.h" #include "esp_flash_partitions.h" +#include "esp_fast_boot.h" #include "internal/esp_system_internal.h" static const char* TAG = "boot"; @@ -743,6 +744,16 @@ static bool try_load_partition(const esp_partition_pos_t *partition, esp_image_m #define TRY_LOG_FORMAT "Trying partition index %d offs 0x%x size 0x%x" +static void bootloader_utility_start_image(uint32_t image_start, uint32_t image_size, uint32_t entry_addr) +{ + void (*user_start)(size_t start_addr); + + bootloader_mmap(image_start, image_size); + + user_start = (void *)entry_addr; + user_start(image_start); +} + bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index, esp_image_metadata_t *result) { int index = start_index; @@ -793,8 +804,6 @@ bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_ void bootloader_utility_load_image(const esp_image_metadata_t* image_data) { - void (*user_start)(size_t start_addr); - #if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED) esp_err_t err; #endif @@ -838,11 +847,18 @@ void bootloader_utility_load_image(const esp_image_metadata_t* image_data) copy loaded segments to RAM, set up caches for mapped segments, and start application unpack_load_app(image_data); #else - bootloader_mmap(image_data->start_addr, image_data->image_len); - - user_start = (void *)image_data->image.entry_addr; - user_start(image_data->start_addr); + bootloader_utility_start_image(image_data->start_addr, image_data->image_len, image_data->image.entry_addr); #endif /* BOOTLOADER_UNPACK_APP */ } +void bootloader_utility_fast_boot_image(void) +{ + uint32_t image_start, image_size, image_entry; + + if (!esp_fast_boot_get_info(&image_start, &image_size, &image_entry)) { + bootloader_utility_start_image(image_start, image_size, image_entry); + } + + ESP_LOGD(TAG, "fast boot image fail"); +} #endif diff --git a/components/esp8266/CMakeLists.txt b/components/esp8266/CMakeLists.txt index 882519a6..bb436422 100644 --- a/components/esp8266/CMakeLists.txt +++ b/components/esp8266/CMakeLists.txt @@ -2,7 +2,7 @@ if(BOOTLOADER_BUILD) # For bootloader, all we need from esp8266 is headers set(COMPONENT_ADD_INCLUDEDIRS include) # set(COMPONENT_REQUIRES ${COMPONENTS}) - set(COMPONENT_SRCS source/ets_printf.c source/crc.c) + set(COMPONENT_SRCS source/ets_printf.c source/crc.c source/esp_fast_boot.c) register_component(esp8266) # as cmake won't attach linker args to a header-only library, attach @@ -37,6 +37,7 @@ else() "source/task_wdt.c" "source/rom.c" "source/hw_random.c" + "source/esp_fast_boot.c" "driver/adc.c" "driver/gpio.c" "driver/hw_timer.c" @@ -53,7 +54,7 @@ else() set(include_dirs "include" "include/driver") set(requires "esp_common" "esp_event") - set(priv_requires "wpa_supplicant" "log" "spi_flash" "tcpip_adapter" "esp_ringbuf" "bootloader_support" "nvs_flash") + set(priv_requires "wpa_supplicant" "log" "spi_flash" "tcpip_adapter" "esp_ringbuf" "bootloader_support" "nvs_flash" "app_update") set(fragments linker.lf ld/esp8266_fragments.lf ld/esp8266_bss_fragments.lf) idf_component_register(SRCS "${srcs}" diff --git a/components/esp8266/component.mk b/components/esp8266/component.mk index dfcc9331..44c86d4b 100644 --- a/components/esp8266/component.mk +++ b/components/esp8266/component.mk @@ -2,7 +2,7 @@ # Component Makefile # ifdef IS_BOOTLOADER_BUILD -COMPONENT_OBJS := source/ets_printf.o source/crc.o +COMPONENT_OBJS := source/ets_printf.o source/crc.o source/esp_fast_boot.o COMPONENT_SRCDIRS := source else COMPONENT_ADD_INCLUDEDIRS += include diff --git a/components/esp8266/include/esp8266/eagle_soc.h b/components/esp8266/include/esp8266/eagle_soc.h index 2fc00d91..97aab970 100644 --- a/components/esp8266/include/esp8266/eagle_soc.h +++ b/components/esp8266/include/esp8266/eagle_soc.h @@ -205,6 +205,9 @@ #define CACHE_READ_EN_BIT BIT8 //}} +#define ESP_CACHE1_ADDR_MAX (0x100000) +#define ESP_CACHE2_ADDR_MAX (0x200000) + #define DRAM_BASE (0x3FFE8000) #define DRAM_SIZE (96 * 1024) diff --git a/components/esp8266/include/esp8266/rom_functions.h b/components/esp8266/include/esp8266/rom_functions.h index 012fde05..1c5a5d68 100644 --- a/components/esp8266/include/esp8266/rom_functions.h +++ b/components/esp8266/include/esp8266/rom_functions.h @@ -1,9 +1,16 @@ #ifndef _ROM_FUNCTIONS_H #define _ROM_FUNCTIONS_H +#include "sdkconfig.h" #include #include +#ifdef CONFIG_SOC_FULL_ICACHE +#define SOC_CACHE_SIZE 1 // 32KB +#else +#define SOC_CACHE_SIZE 0 // 16KB +#endif + #define ROM_FLASH_BUF_DECLARE(__name, __size) uint8_t __name[__size] __attribute__((aligned(4))) typedef struct { diff --git a/components/esp8266/include/esp_fast_boot.h b/components/esp8266/include/esp_fast_boot.h new file mode 100644 index 00000000..7aca7ec4 --- /dev/null +++ b/components/esp8266/include/esp_fast_boot.h @@ -0,0 +1,87 @@ +// Copyright 2020-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#ifndef BOOTLOADER_BUILD +#include "esp_partition.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BOOTLOADER_BUILD +/** + * @brief Setting target partition as fast boot partition and enable fast boot function. + * + * @param partition partition which has image to be booted + * + * @return + * - 0 on success + * - -EINVAL parameter error + * - -EIO read flash error + */ +int esp_fast_boot_enable_partition(const esp_partition_t *partition); + +/** + * @brief Setting current running partition as fast boot partition and enable fast boot function. + * + * @return + * - 0 on success + * - -EINVAL current running partition information error + * - -EIO read flash error + */ +int esp_fast_boot_enable(void); + +/** + * @brief Directly running the image which is to be booted after restart. + * + * @note It is just like jumping directly from one APP to another one without running ROM bootloader and level 2 bootloader. + * Using this API, system starting up is fastest. + * + * @return + * - 0 on success + * - -EINVAL booted partition information error + * - -EIO read flash error + */ +int esp_fast_boot_restart(void); +#endif + +/** + * @brief Disabling fast boot function and bootloader will not boot fast. + */ +void esp_fast_boot_disable(void); + +/** + * @brief Getting fast boot information. + * + * @param image_start image startting address in the SPI Flash + * @param image_size image max size in the SPI Flash + * @param image_entry image entry address in the SPI Flash + * + * @return + * - 0 on success + * - -EINVAL fast boot information error + */ +int esp_fast_boot_get_info(uint32_t *image_start, uint32_t *image_size, uint32_t *image_entry); + +/** + * @brief Printing fast boot information. + */ +void esp_fast_boot_print_info(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp8266/include/esp_system.h b/components/esp8266/include/esp_system.h index 06d2f52c..dfdf4f47 100644 --- a/components/esp8266/include/esp_system.h +++ b/components/esp8266/include/esp_system.h @@ -50,6 +50,7 @@ typedef enum { ESP_RST_DEEPSLEEP, //!< Reset after exiting deep sleep mode ESP_RST_BROWNOUT, //!< Brownout reset (software or hardware) ESP_RST_SDIO, //!< Reset over SDIO + ESP_RST_FAST_SW, //!< Fast reboot } esp_reset_reason_t; /** @@ -187,6 +188,13 @@ uint32_t esp_random(void); */ void esp_fill_random(void *buf, size_t len); +/** + * @brief Initialize MAC address + * + * @return 0 if sucess or others failed + */ +esp_err_t esp_mac_init(void); + typedef enum { FLASH_SIZE_4M_MAP_256_256 = 0, /**< Flash size : 4Mbits. Map : 256KBytes + 256KBytes */ FLASH_SIZE_2M, /**< Flash size : 2Mbits. Map : 256KBytes */ diff --git a/components/esp8266/include/internal/esp_system_internal.h b/components/esp8266/include/internal/esp_system_internal.h index 37702e77..ff468302 100644 --- a/components/esp8266/include/internal/esp_system_internal.h +++ b/components/esp8266/include/internal/esp_system_internal.h @@ -22,6 +22,7 @@ extern "C" { #endif #define RTC_SYS_RAM_SIZE 256 +#define ESP_SYSTEM_FAST_BOOT_IMAGE 0x5aa5a55a /** * @brief Station's AP base information of old SDK @@ -50,6 +51,13 @@ struct _rtc_sys_info { uint32_t hint; // software reset reason uint32_t old_sysconf_addr; /* +#include +#include +#include "esp_log.h" +#include "rom/crc.h" +#include "internal/esp_system_internal.h" +#include "esp_fast_boot.h" +#ifndef BOOTLOADER_BUILD +#include "esp_ota_ops.h" +#include "esp_image_format.h" +#include "esp_wifi.h" +#include "esp_system.h" +#include "esp8266/rom_functions.h" +#include "esp8266/eagle_soc.h" +#include "rom/uart.h" +#include "esp_spi_flash.h" +#include "FreeRTOS.h" +#include "task.h" +#endif + +static char *TAG = "fast_boot"; + +#ifndef BOOTLOADER_BUILD +int esp_fast_boot_enable_partition(const esp_partition_t *partition) +{ + int ret; + esp_image_header_t image; + + if (!partition || partition->type != ESP_PARTITION_TYPE_APP) + return -EINVAL; + + ret = spi_flash_read(partition->address, &image, sizeof(esp_image_header_t)); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "read image head from spi flash error"); + return -EIO; + } + + rtc_sys_info.fast_boot.image_start = partition->address; + rtc_sys_info.fast_boot.image_size = partition->size - 4; + rtc_sys_info.fast_boot.image_entry = image.entry_addr; + rtc_sys_info.fast_boot.magic = ESP_SYSTEM_FAST_BOOT_IMAGE; + rtc_sys_info.fast_boot.crc32 = crc32_le(UINT32_MAX, (uint8_t *)&rtc_sys_info.fast_boot, sizeof(rtc_sys_info.fast_boot) - 4); + + return 0; +} + +int esp_fast_boot_enable(void) +{ + const esp_partition_t *running = esp_ota_get_running_partition(); + + return esp_fast_boot_enable_partition(running); +} + +void IRAM_ATTR esp_fast_boot_restart_app(uint32_t image_start, uint32_t entry_addr, uint8_t region, uint8_t sub_region) +{ + const uint32_t sp = DRAM_BASE + DRAM_SIZE - 16; + void (*user_start)(size_t start_addr); + + Cache_Read_Disable(); + Cache_Read_Enable(sub_region, region, SOC_CACHE_SIZE); + + __asm__ __volatile__( + "mov a1, %0\n" + : : "a"(sp) : "memory" + ); + + user_start = (void *)entry_addr; + user_start(image_start); +} + +int esp_fast_boot_restart(void) +{ + extern void pm_goto_rf_on(void); + extern void clockgate_watchdog(int on); + + int ret; + uint8_t region, sub_region; + uint32_t image_start, image_size, image_entry, image_mask; + const esp_partition_t *to_boot; + esp_image_header_t image; + + to_boot = esp_ota_get_boot_partition(); + if (!to_boot) { + ESP_LOGI(TAG, "no OTA boot partition"); + to_boot = esp_ota_get_running_partition(); + if (!to_boot) { + ESP_LOGE(TAG, "ERROR: Fail to get running partition"); + return -EINVAL; + } + } + + image_start = to_boot->address; + image_size = to_boot->size - 4; + + ret = spi_flash_read(image_start, &image, sizeof(esp_image_header_t)); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "ERROR: Fail to read image head from spi flash error=%d", ret); + return -EIO; + } + + image_entry = image.entry_addr; + + if (image_start < 0x200000) { + region = 0; + } else if (image_start < 0x400000) { + region = 1; + } else if (image_start < 0x600000) { + region = 2; + } else if (image_start < 0x800000) { + region = 3; + } else { + ESP_LOGE(TAG, "ERROR: App bin error, start_addr 0x%08x image_len %d\n", image_start, image_size); + return -EINVAL; + } + + image_mask = image_start & 0x1fffff; + if (image_mask < 0x100000) { + sub_region = 0; + } else { + sub_region = 1; + } + + if (esp_wifi_stop() != ESP_OK) { + ESP_LOGD(TAG, "ERROR: Fail to stop Wi-Fi"); + } + + uart_tx_wait_idle(1); + uart_tx_wait_idle(0); + + vTaskDelay(40 / portTICK_RATE_MS); + + pm_goto_rf_on(); + clockgate_watchdog(0); + REG_WRITE(0x3ff00018, 0xffff00ff); + SET_PERI_REG_MASK(0x60000D48, BIT1); + CLEAR_PERI_REG_MASK(0x60000D48, BIT1); + + /* Get startup time */ + //ets_printf("\nets\n"); + + uart_disable_swap_io(); + + vPortEnterCritical(); + REG_WRITE(INT_ENA_WDEV, 0); + _xt_isr_mask(UINT32_MAX); + + esp_reset_reason_set_hint(ESP_RST_FAST_SW); + + esp_fast_boot_restart_app(image_start, image_entry, region, sub_region); + + return 0; +} +#endif + +void esp_fast_boot_disable(void) +{ + memset(&rtc_sys_info.fast_boot, 0, sizeof(rtc_sys_info.fast_boot)); +} + +int esp_fast_boot_get_info(uint32_t *image_start, uint32_t *image_size, uint32_t *image_entry) +{ + if (rtc_sys_info.fast_boot.magic != ESP_SYSTEM_FAST_BOOT_IMAGE) { + ESP_LOGE(TAG, "magic error"); + return -EINVAL; + } + + if (rtc_sys_info.fast_boot.crc32 != crc32_le(UINT32_MAX, (uint8_t *)&rtc_sys_info.fast_boot, sizeof(rtc_sys_info.fast_boot) - 4)) { + ESP_LOGE(TAG, "CRC32 error"); + esp_fast_boot_disable(); + return -EINVAL; + } + + *image_start = rtc_sys_info.fast_boot.image_start; + *image_size = rtc_sys_info.fast_boot.image_size; + *image_entry = rtc_sys_info.fast_boot.image_entry; + + esp_fast_boot_disable(); + + return 0; +} + +void esp_fast_boot_print_info(void) +{ + ets_printf("\nmagic is %x\n", rtc_sys_info.fast_boot.magic); + ets_printf("image start is %x\n", rtc_sys_info.fast_boot.image_start); + ets_printf("image size is %x\n", rtc_sys_info.fast_boot.image_size); + ets_printf("image entry is %x\n", rtc_sys_info.fast_boot.image_entry); + ets_printf("CRC32 is %x\n", rtc_sys_info.fast_boot.crc32); +} diff --git a/components/esp8266/source/esp_wifi.c b/components/esp8266/source/esp_wifi.c index b42a76cb..e1d1fab9 100644 --- a/components/esp8266/source/esp_wifi.c +++ b/components/esp8266/source/esp_wifi.c @@ -30,6 +30,7 @@ const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = true; const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = false; #endif +esp_err_t mac_init(void); esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config); ESP_EVENT_DEFINE_BASE(WIFI_EVENT); @@ -129,6 +130,10 @@ static void esp_wifi_set_debug_log() */ esp_err_t esp_wifi_init(const wifi_init_config_t *config) { + mac_init(); + + esp_wifi_set_rx_pbuf_mem_type(WIFI_RX_PBUF_DRAM); + esp_err_t result = esp_wifi_init_internal(config); if (result == ESP_OK) { esp_wifi_set_debug_log(); diff --git a/components/esp8266/source/phy_init.c b/components/esp8266/source/phy_init.c index 24247c9f..9fc23207 100644 --- a/components/esp8266/source/phy_init.c +++ b/components/esp8266/source/phy_init.c @@ -72,11 +72,6 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibrat esp_err_t status = ESP_OK; uint8_t sta_mac[6]; uint8_t *local_init_data = calloc(1, 256); -#ifdef CONFIG_ESP_CONSOLE_UART_BAUDRATE - const uint32_t uart_baudrate = CONFIG_ESP_CONSOLE_UART_BAUDRATE; -#else - const uint32_t uart_baudrate = 74880; // ROM default baudrate -#endif memcpy(local_init_data, init_data->params, 128); memcpy(local_init_data + 128, calibration_data->rf_cal_data, 128); @@ -102,12 +97,7 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibrat * so UARTs must be flush here, then reconfigurate the UART frequency dividor */ uart_tx_wait_idle(0); - uart_div_modify(0, UART_CLK_FREQ / uart_baudrate); - uart_tx_wait_idle(1); - uart_div_modify(1, UART_CLK_FREQ / uart_baudrate); - - rtc_init_clk(local_init_data); int ret = register_chipv6_phy(local_init_data); if (ret) { diff --git a/components/esp8266/source/reset_reason.c b/components/esp8266/source/reset_reason.c index e47d4d5a..b7956d4b 100644 --- a/components/esp8266/source/reset_reason.c +++ b/components/esp8266/source/reset_reason.c @@ -41,7 +41,7 @@ static inline void esp_reset_reason_clear_hint() static inline uint32_t esp_reset_reason_get_hint(uint32_t hw_reset) { - if (hw_reset == POWERON_RESET && rtc_sys_info.hint != ESP_RST_SW) + if (hw_reset == POWERON_RESET && ((rtc_sys_info.hint != ESP_RST_SW) && (rtc_sys_info.hint != ESP_RST_FAST_SW))) rtc_sys_info.hint = 0; return rtc_sys_info.hint; @@ -63,7 +63,8 @@ static inline uint32_t get_reset_reason(uint32_t rtc_reset_reason, uint32_t rese { switch (rtc_reset_reason) { case POWERON_RESET: - if (reset_reason_hint == ESP_RST_SW) + if (reset_reason_hint == ESP_RST_SW || + reset_reason_hint == ESP_RST_FAST_SW) return reset_reason_hint; return ESP_RST_POWERON; case EXT_RESET: @@ -108,7 +109,7 @@ static void __esp_reset_reason_init(int init) } if (init) - ESP_LOGI(TAG, "RTC reset %u wakeup %u store %u, reason is %u", hw_reset, hw_wakeup, hint, s_reset_reason); + ESP_LOGD(TAG, "RTC reset %u wakeup %u store %u, reason is %u", hw_reset, hw_wakeup, hint, s_reset_reason); } /** diff --git a/components/esp8266/source/rom.c b/components/esp8266/source/rom.c index 7369f09b..d8aa83db 100644 --- a/components/esp8266/source/rom.c +++ b/components/esp8266/source/rom.c @@ -31,3 +31,8 @@ void uart_tx_wait_idle(uint8_t uart_no) ets_delay_us(byte_delay_us); } + +void uart_disable_swap_io(void) +{ + CLEAR_PERI_REG_MASK(UART_SWAP_REG, 0x4); +} diff --git a/components/esp8266/source/startup.c b/components/esp8266/source/startup.c index fb573d8a..6465cb4c 100644 --- a/components/esp8266/source/startup.c +++ b/components/esp8266/source/startup.c @@ -39,18 +39,10 @@ #include "esp_newlib.h" #endif -extern void chip_boot(void); -extern int rtc_init(void); -extern int mac_init(void); -extern int base_gpio_init(void); -extern int watchdog_init(void); -extern int wifi_timer_init(void); -extern int wifi_nvs_init(void); extern esp_err_t esp_pthread_init(void); -extern void phy_get_bb_evm(void); -extern void uart_div_modify(uint8_t uart_no, uint16_t DivLatchValue); -/*Only for calling esp_wifi_set_ps can compile successfully */ -uint32_t LwipTimOutLim = 0; +extern void chip_boot(void); +extern int base_gpio_init(void); +extern int rtc_init(void); static inline int should_load(uint32_t load_addr) { @@ -73,23 +65,19 @@ static void user_init_entry(void *param) extern void (*__init_array_end)(void); extern void app_main(void); + extern uint32_t esp_get_time(void); /* initialize C++ construture function */ for (func = &__init_array_start; func < &__init_array_end; func++) func[0](); - /*enable tsf0 interrupt for pwm*/ - REG_WRITE(PERIPHS_DPORT_BASEADDR, (REG_READ(PERIPHS_DPORT_BASEADDR) & ~0x1F) | 0x1); - REG_WRITE(INT_ENA_WDEV, REG_READ(INT_ENA_WDEV) | WDEV_TSF0_REACH_INT); - - assert(nvs_flash_init() == 0); - assert(rtc_init() == 0); - assert(mac_init() == 0); + rtc_init(); + esp_phy_init_clk(); assert(base_gpio_init() == 0); - esp_wifi_set_rx_pbuf_mem_type(WIFI_RX_PBUF_DRAM); - - esp_phy_init_clk(); + if (esp_reset_reason_early() != ESP_RST_FAST_SW) { + assert(esp_mac_init() == ESP_OK); + } #if CONFIG_RESET_REASON esp_reset_reason_init(); @@ -103,6 +91,10 @@ static void user_init_entry(void *param) assert(esp_pthread_init() == 0); #endif +#ifdef CONFIG_BOOTLOADER_FAST_BOOT + REG_CLR_BIT(DPORT_CTL_REG, DPORT_CTL_DOUBLE_CLK); +#endif + #ifdef CONFIG_ESP8266_DEFAULT_CPU_FREQ_160 esp_set_cpu_freq(ESP_CPU_FREQ_160M); #endif @@ -120,6 +112,10 @@ void call_start_cpu(size_t start_addr) extern int _bss_start, _bss_end; extern int _iram_bss_start, _iram_bss_end; +#ifdef CONFIG_BOOTLOADER_FAST_BOOT + REG_SET_BIT(DPORT_CTL_REG, DPORT_CTL_DOUBLE_CLK); +#endif + esp_image_header_t *head = (esp_image_header_t *)(FLASH_BASE + (start_addr & (FLASH_SIZE - 1))); esp_image_segment_header_t *segment = (esp_image_segment_header_t *)((uintptr_t)head + sizeof(esp_image_header_t)); diff --git a/components/esp8266/source/system_api.c b/components/esp8266/source/system_api.c index 8bc65846..913e9502 100644 --- a/components/esp8266/source/system_api.c +++ b/components/esp8266/source/system_api.c @@ -313,6 +313,34 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type) return ESP_OK; } +esp_err_t esp_mac_init(void) +{ + esp_err_t ret; + uint8_t efuse_mac[6]; + + if ((ret = nvs_flash_init()) != ESP_OK) { + ESP_LOGE(TAG, "Init NVS error=%d", ret); + return ESP_ERR_INVALID_MAC; + } + + if (load_backup_mac_data(efuse_mac) == ESP_OK) { + ESP_LOGD(TAG, "Load MAC from NVS error=%d", ret); + return ESP_OK; + } + + if ((ret = esp_efuse_mac_get_default(efuse_mac)) != ESP_OK) { + ESP_LOGE(TAG, "Get mac address error=%d", ret); + return ESP_ERR_INVALID_MAC; + } + + if ((ret = store_backup_mac_data()) != ESP_OK) { + ESP_LOGE(TAG, "Store mac address error=%d", ret); + return ESP_ERR_INVALID_MAC; + } + + return ESP_OK; +} + /** * Get IDF version */