mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-21 17:16:29 +08:00
Merge branch 'feature/speed_up_system_startup' into 'master'
feat(startup): add fast boot and fast restart function See merge request sdk/ESP8266_RTOS_SDK!1302
This commit is contained in:
@ -19,6 +19,13 @@ config BOOTLOADER_DISABLE_JTAG_IO
|
|||||||
|
|
||||||
If users use JTAG to help develop, please disable this option.
|
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
|
choice LOG_BOOTLOADER_LEVEL
|
||||||
bool "Bootloader log verbosity"
|
bool "Bootloader log verbosity"
|
||||||
default LOG_BOOTLOADER_LEVEL_INFO
|
default LOG_BOOTLOADER_LEVEL_INFO
|
||||||
|
@ -30,11 +30,19 @@ static int selected_boot_partition(const bootloader_state_t *bs);
|
|||||||
|
|
||||||
void call_start_cpu(void)
|
void call_start_cpu(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_BOOTLOADER_FAST_BOOT
|
||||||
|
REG_SET_BIT(DPORT_CTL_REG, DPORT_CTL_DOUBLE_CLK);
|
||||||
|
#endif
|
||||||
|
|
||||||
// 1. Hardware initialization
|
// 1. Hardware initialization
|
||||||
if(bootloader_init() != ESP_OK){
|
if(bootloader_init() != ESP_OK){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOOTLOADER_FAST_BOOT
|
||||||
|
bootloader_utility_fast_boot_image();
|
||||||
|
#endif
|
||||||
|
|
||||||
// 2. Select image to boot
|
// 2. Select image to boot
|
||||||
esp_image_metadata_t image_data;
|
esp_image_metadata_t image_data;
|
||||||
if(select_image(&image_data) != ESP_OK){
|
if(select_image(&image_data) != ESP_OK){
|
||||||
|
@ -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.
|
* @param[in] data Structure to hold on-flash image metadata.
|
||||||
*/
|
*/
|
||||||
void bootloader_utility_load_image(const esp_image_metadata_t* image_data);
|
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);
|
||||||
|
@ -493,6 +493,7 @@ static void set_cache_and_start_app(
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
#include "esp_flash_partitions.h"
|
#include "esp_flash_partitions.h"
|
||||||
|
#include "esp_fast_boot.h"
|
||||||
#include "internal/esp_system_internal.h"
|
#include "internal/esp_system_internal.h"
|
||||||
|
|
||||||
static const char* TAG = "boot";
|
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"
|
#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)
|
bool bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index, esp_image_metadata_t *result)
|
||||||
{
|
{
|
||||||
int index = start_index;
|
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 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)
|
#if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED)
|
||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
#endif
|
#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
|
copy loaded segments to RAM, set up caches for mapped segments, and start application
|
||||||
unpack_load_app(image_data);
|
unpack_load_app(image_data);
|
||||||
#else
|
#else
|
||||||
bootloader_mmap(image_data->start_addr, image_data->image_len);
|
bootloader_utility_start_image(image_data->start_addr, image_data->image_len, image_data->image.entry_addr);
|
||||||
|
|
||||||
user_start = (void *)image_data->image.entry_addr;
|
|
||||||
user_start(image_data->start_addr);
|
|
||||||
#endif /* BOOTLOADER_UNPACK_APP */
|
#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
|
#endif
|
||||||
|
@ -2,7 +2,7 @@ if(BOOTLOADER_BUILD)
|
|||||||
# For bootloader, all we need from esp8266 is headers
|
# For bootloader, all we need from esp8266 is headers
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS include)
|
set(COMPONENT_ADD_INCLUDEDIRS include)
|
||||||
# set(COMPONENT_REQUIRES ${COMPONENTS})
|
# 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)
|
register_component(esp8266)
|
||||||
|
|
||||||
# as cmake won't attach linker args to a header-only library, attach
|
# as cmake won't attach linker args to a header-only library, attach
|
||||||
@ -37,6 +37,7 @@ else()
|
|||||||
"source/task_wdt.c"
|
"source/task_wdt.c"
|
||||||
"source/rom.c"
|
"source/rom.c"
|
||||||
"source/hw_random.c"
|
"source/hw_random.c"
|
||||||
|
"source/esp_fast_boot.c"
|
||||||
"driver/adc.c"
|
"driver/adc.c"
|
||||||
"driver/gpio.c"
|
"driver/gpio.c"
|
||||||
"driver/hw_timer.c"
|
"driver/hw_timer.c"
|
||||||
@ -53,7 +54,7 @@ else()
|
|||||||
set(include_dirs "include" "include/driver")
|
set(include_dirs "include" "include/driver")
|
||||||
|
|
||||||
set(requires "esp_common" "esp_event")
|
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)
|
set(fragments linker.lf ld/esp8266_fragments.lf ld/esp8266_bss_fragments.lf)
|
||||||
|
|
||||||
idf_component_register(SRCS "${srcs}"
|
idf_component_register(SRCS "${srcs}"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# Component Makefile
|
# Component Makefile
|
||||||
#
|
#
|
||||||
ifdef IS_BOOTLOADER_BUILD
|
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
|
COMPONENT_SRCDIRS := source
|
||||||
else
|
else
|
||||||
COMPONENT_ADD_INCLUDEDIRS += include
|
COMPONENT_ADD_INCLUDEDIRS += include
|
||||||
|
@ -205,6 +205,9 @@
|
|||||||
#define CACHE_READ_EN_BIT BIT8
|
#define CACHE_READ_EN_BIT BIT8
|
||||||
//}}
|
//}}
|
||||||
|
|
||||||
|
#define ESP_CACHE1_ADDR_MAX (0x100000)
|
||||||
|
#define ESP_CACHE2_ADDR_MAX (0x200000)
|
||||||
|
|
||||||
#define DRAM_BASE (0x3FFE8000)
|
#define DRAM_BASE (0x3FFE8000)
|
||||||
#define DRAM_SIZE (96 * 1024)
|
#define DRAM_SIZE (96 * 1024)
|
||||||
|
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
#ifndef _ROM_FUNCTIONS_H
|
#ifndef _ROM_FUNCTIONS_H
|
||||||
#define _ROM_FUNCTIONS_H
|
#define _ROM_FUNCTIONS_H
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#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)))
|
#define ROM_FLASH_BUF_DECLARE(__name, __size) uint8_t __name[__size] __attribute__((aligned(4)))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
87
components/esp8266/include/esp_fast_boot.h
Normal file
87
components/esp8266/include/esp_fast_boot.h
Normal file
@ -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
|
@ -50,6 +50,7 @@ typedef enum {
|
|||||||
ESP_RST_DEEPSLEEP, //!< Reset after exiting deep sleep mode
|
ESP_RST_DEEPSLEEP, //!< Reset after exiting deep sleep mode
|
||||||
ESP_RST_BROWNOUT, //!< Brownout reset (software or hardware)
|
ESP_RST_BROWNOUT, //!< Brownout reset (software or hardware)
|
||||||
ESP_RST_SDIO, //!< Reset over SDIO
|
ESP_RST_SDIO, //!< Reset over SDIO
|
||||||
|
ESP_RST_FAST_SW, //!< Fast reboot
|
||||||
} esp_reset_reason_t;
|
} esp_reset_reason_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,6 +188,13 @@ uint32_t esp_random(void);
|
|||||||
*/
|
*/
|
||||||
void esp_fill_random(void *buf, size_t len);
|
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 {
|
typedef enum {
|
||||||
FLASH_SIZE_4M_MAP_256_256 = 0, /**< Flash size : 4Mbits. Map : 256KBytes + 256KBytes */
|
FLASH_SIZE_4M_MAP_256_256 = 0, /**< Flash size : 4Mbits. Map : 256KBytes + 256KBytes */
|
||||||
FLASH_SIZE_2M, /**< Flash size : 2Mbits. Map : 256KBytes */
|
FLASH_SIZE_2M, /**< Flash size : 2Mbits. Map : 256KBytes */
|
||||||
|
@ -22,6 +22,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RTC_SYS_RAM_SIZE 256
|
#define RTC_SYS_RAM_SIZE 256
|
||||||
|
#define ESP_SYSTEM_FAST_BOOT_IMAGE 0x5aa5a55a
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Station's AP base information of old SDK
|
* @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 hint; // software reset reason
|
||||||
uint32_t old_sysconf_addr; /*<! old SDK system configuration parameters base address,
|
uint32_t old_sysconf_addr; /*<! old SDK system configuration parameters base address,
|
||||||
if your bootloader is older than v3.2, please don't use this */
|
if your bootloader is older than v3.2, please don't use this */
|
||||||
|
struct {
|
||||||
|
uint32_t magic;
|
||||||
|
uint32_t image_start;
|
||||||
|
uint32_t image_size;
|
||||||
|
uint32_t image_entry;
|
||||||
|
uint32_t crc32;
|
||||||
|
} fast_boot;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,6 +101,11 @@ static inline STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable UART0 I/O swap and don't care about if TX FIFO is empty
|
||||||
|
*/
|
||||||
|
void uart_disable_swap_io(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
205
components/esp8266/source/esp_fast_boot.c
Normal file
205
components/esp8266/source/esp_fast_boot.c
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
// Copyright 2020 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.
|
||||||
|
|
||||||
|
// #define LOG_LOCAL_LEVEL ESP_LOG_ERROR
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#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);
|
||||||
|
}
|
@ -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;
|
const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
esp_err_t mac_init(void);
|
||||||
esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config);
|
esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config);
|
||||||
|
|
||||||
ESP_EVENT_DEFINE_BASE(WIFI_EVENT);
|
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)
|
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);
|
esp_err_t result = esp_wifi_init_internal(config);
|
||||||
if (result == ESP_OK) {
|
if (result == ESP_OK) {
|
||||||
esp_wifi_set_debug_log();
|
esp_wifi_set_debug_log();
|
||||||
|
@ -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;
|
esp_err_t status = ESP_OK;
|
||||||
uint8_t sta_mac[6];
|
uint8_t sta_mac[6];
|
||||||
uint8_t *local_init_data = calloc(1, 256);
|
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, init_data->params, 128);
|
||||||
memcpy(local_init_data + 128, calibration_data->rf_cal_data, 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
|
* so UARTs must be flush here, then reconfigurate the UART frequency dividor
|
||||||
*/
|
*/
|
||||||
uart_tx_wait_idle(0);
|
uart_tx_wait_idle(0);
|
||||||
uart_div_modify(0, UART_CLK_FREQ / uart_baudrate);
|
|
||||||
|
|
||||||
uart_tx_wait_idle(1);
|
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);
|
int ret = register_chipv6_phy(local_init_data);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -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)
|
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;
|
rtc_sys_info.hint = 0;
|
||||||
|
|
||||||
return rtc_sys_info.hint;
|
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) {
|
switch (rtc_reset_reason) {
|
||||||
case POWERON_RESET:
|
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 reset_reason_hint;
|
||||||
return ESP_RST_POWERON;
|
return ESP_RST_POWERON;
|
||||||
case EXT_RESET:
|
case EXT_RESET:
|
||||||
@ -108,7 +109,7 @@ static void __esp_reset_reason_init(int init)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,3 +31,8 @@ void uart_tx_wait_idle(uint8_t uart_no)
|
|||||||
|
|
||||||
ets_delay_us(byte_delay_us);
|
ets_delay_us(byte_delay_us);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uart_disable_swap_io(void)
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(UART_SWAP_REG, 0x4);
|
||||||
|
}
|
||||||
|
@ -39,18 +39,10 @@
|
|||||||
#include "esp_newlib.h"
|
#include "esp_newlib.h"
|
||||||
#endif
|
#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 esp_err_t esp_pthread_init(void);
|
||||||
extern void phy_get_bb_evm(void);
|
extern void chip_boot(void);
|
||||||
extern void uart_div_modify(uint8_t uart_no, uint16_t DivLatchValue);
|
extern int base_gpio_init(void);
|
||||||
/*Only for calling esp_wifi_set_ps can compile successfully */
|
extern int rtc_init(void);
|
||||||
uint32_t LwipTimOutLim = 0;
|
|
||||||
|
|
||||||
static inline int should_load(uint32_t load_addr)
|
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 (*__init_array_end)(void);
|
||||||
|
|
||||||
extern void app_main(void);
|
extern void app_main(void);
|
||||||
|
extern uint32_t esp_get_time(void);
|
||||||
|
|
||||||
/* initialize C++ construture function */
|
/* initialize C++ construture function */
|
||||||
for (func = &__init_array_start; func < &__init_array_end; func++)
|
for (func = &__init_array_start; func < &__init_array_end; func++)
|
||||||
func[0]();
|
func[0]();
|
||||||
|
|
||||||
/*enable tsf0 interrupt for pwm*/
|
rtc_init();
|
||||||
REG_WRITE(PERIPHS_DPORT_BASEADDR, (REG_READ(PERIPHS_DPORT_BASEADDR) & ~0x1F) | 0x1);
|
esp_phy_init_clk();
|
||||||
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);
|
|
||||||
assert(base_gpio_init() == 0);
|
assert(base_gpio_init() == 0);
|
||||||
|
|
||||||
esp_wifi_set_rx_pbuf_mem_type(WIFI_RX_PBUF_DRAM);
|
if (esp_reset_reason_early() != ESP_RST_FAST_SW) {
|
||||||
|
assert(esp_mac_init() == ESP_OK);
|
||||||
esp_phy_init_clk();
|
}
|
||||||
|
|
||||||
#if CONFIG_RESET_REASON
|
#if CONFIG_RESET_REASON
|
||||||
esp_reset_reason_init();
|
esp_reset_reason_init();
|
||||||
@ -103,6 +91,10 @@ static void user_init_entry(void *param)
|
|||||||
assert(esp_pthread_init() == 0);
|
assert(esp_pthread_init() == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOOTLOADER_FAST_BOOT
|
||||||
|
REG_CLR_BIT(DPORT_CTL_REG, DPORT_CTL_DOUBLE_CLK);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ESP8266_DEFAULT_CPU_FREQ_160
|
#ifdef CONFIG_ESP8266_DEFAULT_CPU_FREQ_160
|
||||||
esp_set_cpu_freq(ESP_CPU_FREQ_160M);
|
esp_set_cpu_freq(ESP_CPU_FREQ_160M);
|
||||||
#endif
|
#endif
|
||||||
@ -120,6 +112,10 @@ void call_start_cpu(size_t start_addr)
|
|||||||
extern int _bss_start, _bss_end;
|
extern int _bss_start, _bss_end;
|
||||||
extern int _iram_bss_start, _iram_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_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));
|
esp_image_segment_header_t *segment = (esp_image_segment_header_t *)((uintptr_t)head + sizeof(esp_image_header_t));
|
||||||
|
|
||||||
|
@ -313,6 +313,34 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type)
|
|||||||
return ESP_OK;
|
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
|
* Get IDF version
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user