From eef781f9b9d3e5d47be3da6f9d07cfff80f0737c Mon Sep 17 00:00:00 2001 From: dongheng Date: Fri, 15 Mar 2019 10:04:39 +0800 Subject: [PATCH] fix(esp8266): Fix esp8266 load RTC segment when reset from deep sleep Now only 1MB flash is mapped to SoC bus. --- .../esp8266/include/esp8266/eagle_soc.h | 9 +++++- .../include/internal/esp_system_internal.h | 8 +++++ components/esp8266/source/reset_reason.c | 31 +++++++++++++++---- components/esp8266/source/startup.c | 19 +++++++++--- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/components/esp8266/include/esp8266/eagle_soc.h b/components/esp8266/include/esp8266/eagle_soc.h index ec5318a9..aef152cf 100644 --- a/components/esp8266/include/esp8266/eagle_soc.h +++ b/components/esp8266/include/esp8266/eagle_soc.h @@ -178,10 +178,17 @@ #define IRAM_SIZE (48 * 1024) #define FLASH_BASE (0x40200000) -#define FLASH_SIZE (16 * 1024 * 1024) +#define FLASH_SIZE (1 * 1024 * 1024) + +#define RTC_SYS_BASE (0x60001000) +#define RTC_SYS_SIZE (0x200) + +#define RTC_USER_BASE (0x60001200) +#define RTC_USER_SIZE (0x200) #define IS_DRAM(a) ((size_t)(a) >= DRAM_BASE && (size_t)(a) < (DRAM_BASE + DRAM_SIZE)) #define IS_IRAM(a) ((size_t)(a) >= IRAM_BASE && (size_t)(a) < (IRAM_BASE + IRAM_SIZE)) #define IS_FLASH(a) ((size_t)(a) >= FLASH_BASE && (size_t)(a) < (FLASH_BASE + FLASH_SIZE)) +#define IS_USR_RTC(a) ((size_t)(a) >= RTC_USER_BASE && (size_t)(a) < (RTC_USER_BASE + RTC_USER_SIZE)) #endif //_EAGLE_SOC_H_ diff --git a/components/esp8266/include/internal/esp_system_internal.h b/components/esp8266/include/internal/esp_system_internal.h index 89bacd71..591d0216 100644 --- a/components/esp8266/include/internal/esp_system_internal.h +++ b/components/esp8266/include/internal/esp_system_internal.h @@ -15,6 +15,7 @@ #pragma once #include +#include #ifdef __cplusplus extern "C" { @@ -48,6 +49,13 @@ void esp_reset_reason_init(void); */ void esp_reset_reason_set_hint(esp_reset_reason_t hint); +/** + * @brief Get reason of last reset but not clear it for next reset + * + * @return See description of esp_reset_reason_t for explanation of each value. + */ +esp_reset_reason_t esp_reset_reason_early(void); + #ifdef __cplusplus } #endif diff --git a/components/esp8266/source/reset_reason.c b/components/esp8266/source/reset_reason.c index ec337069..e0f1c0c9 100644 --- a/components/esp8266/source/reset_reason.c +++ b/components/esp8266/source/reset_reason.c @@ -21,8 +21,6 @@ #include "esp_log.h" #include "esp_libc.h" -#if CONFIG_RESET_REASON - #define RTC_RESET_SW_CAUSE_REG RTC_STORE0 #define RTC_RESET_HW_CAUSE_REG RTC_STATE1 #define RTC_WAKEUP_HW_CAUSE_REG RTC_STATE2 @@ -96,9 +94,9 @@ static inline uint32_t get_reset_reason(uint32_t rtc_reset_reason, uint32_t rese } /** - * @brief Internal function to get SoC reset reason at system initialization + * Internal function to initialize SoC reset reason at system initialization */ -void esp_reset_reason_init(void) +static void __esp_reset_reason_init(int init) { const uint32_t hw_reset = esp_rtc_get_reset_reason(); #if CONFIG_RESET_REASON_CHECK_WAKEUP @@ -109,13 +107,24 @@ void esp_reset_reason_init(void) const uint32_t hint = esp_reset_reason_get_hint(hw_reset); s_reset_reason = get_reset_reason(hw_reset, hint); - if (hint != ESP_RST_UNKNOWN) { + if (init && hint != ESP_RST_UNKNOWN) { esp_reset_reason_clear_hint(); } - ESP_LOGI(TAG, "RTC reset %u wakeup %u store %u, reason is %u", hw_reset, hw_wakeup, hint, s_reset_reason); + if (init) + ESP_LOGI(TAG, "RTC reset %u wakeup %u store %u, reason is %u", hw_reset, hw_wakeup, hint, s_reset_reason); } +/** + * @brief Internal function to get SoC reset reason at system initialization + */ +void esp_reset_reason_init(void) +{ + __esp_reset_reason_init(1); +} + +#if CONFIG_RESET_REASON + /** * @brief Internal function to set reset reason hint */ @@ -143,3 +152,13 @@ void esp_reset_reason_set_hint(esp_reset_reason_t hint) } #endif /* CONFIG_RESET_REASON */ + +/** + * Get reason of last reset but not clear it for next reset + */ +esp_reset_reason_t esp_reset_reason_early(void) +{ + __esp_reset_reason_init(0); + + return (esp_reset_reason_t)s_reset_reason; +} diff --git a/components/esp8266/source/startup.c b/components/esp8266/source/startup.c index 96022e32..f3961907 100644 --- a/components/esp8266/source/startup.c +++ b/components/esp8266/source/startup.c @@ -30,9 +30,7 @@ #include "esp_task_wdt.h" #include "internal/esp_wifi_internal.h" #include "internal/esp_system_internal.h" - -#define FLASH_MAP_ADDR 0x40200000 -#define FLASH_MAP_SIZE 0x00100000 +#include "esp8266/eagle_soc.h" extern void chip_boot(void); extern int rtc_init(void); @@ -44,6 +42,16 @@ extern int wifi_nvs_init(void); extern esp_err_t esp_pthread_init(void); extern void phy_get_bb_evm(void); +static inline int should_load(uint32_t load_addr) +{ + if (IS_USR_RTC(load_addr)) { + if (esp_reset_reason_early() == ESP_RST_DEEPSLEEP) + return 0; + } + + return 1; +} + static void user_init_entry(void *param) { void (**func)(void); @@ -97,7 +105,7 @@ void call_user_start(size_t start_addr) extern int _bss_start, _bss_end; - esp_image_header_t *head = (esp_image_header_t *)(FLASH_MAP_ADDR + (start_addr & (FLASH_MAP_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)); /* The data in flash cannot be accessed by byte in this stage, so just access by word and get the segment count. */ @@ -106,6 +114,9 @@ void call_user_start(size_t start_addr) for (i = 0; i < segment_count - 1; i++) { segment = (esp_image_segment_header_t *)((uintptr_t)segment + sizeof(esp_image_segment_header_t) + segment->data_len); + if (!should_load(segment->load_addr)) + continue; + uint32_t *dest = (uint32_t *)segment->load_addr; uint32_t *src = (uint32_t *)((uintptr_t)segment + sizeof(esp_image_segment_header_t)); uint32_t size = segment->data_len / sizeof(uint32_t);