fix(esp8266): Fix esp8266 load RTC segment when reset from deep sleep

Now only 1MB flash is mapped to SoC bus.
This commit is contained in:
dongheng
2019-03-15 10:04:39 +08:00
parent 3c68b66934
commit eef781f9b9
4 changed files with 56 additions and 11 deletions

View File

@ -178,10 +178,17 @@
#define IRAM_SIZE (48 * 1024) #define IRAM_SIZE (48 * 1024)
#define FLASH_BASE (0x40200000) #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_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_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_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_ #endif //_EAGLE_SOC_H_

View File

@ -15,6 +15,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <esp_system.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -48,6 +49,13 @@ void esp_reset_reason_init(void);
*/ */
void esp_reset_reason_set_hint(esp_reset_reason_t hint); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -21,8 +21,6 @@
#include "esp_log.h" #include "esp_log.h"
#include "esp_libc.h" #include "esp_libc.h"
#if CONFIG_RESET_REASON
#define RTC_RESET_SW_CAUSE_REG RTC_STORE0 #define RTC_RESET_SW_CAUSE_REG RTC_STORE0
#define RTC_RESET_HW_CAUSE_REG RTC_STATE1 #define RTC_RESET_HW_CAUSE_REG RTC_STATE1
#define RTC_WAKEUP_HW_CAUSE_REG RTC_STATE2 #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(); const uint32_t hw_reset = esp_rtc_get_reset_reason();
#if CONFIG_RESET_REASON_CHECK_WAKEUP #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); const uint32_t hint = esp_reset_reason_get_hint(hw_reset);
s_reset_reason = get_reset_reason(hw_reset, hint); 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_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 * @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 */ #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;
}

View File

@ -30,9 +30,7 @@
#include "esp_task_wdt.h" #include "esp_task_wdt.h"
#include "internal/esp_wifi_internal.h" #include "internal/esp_wifi_internal.h"
#include "internal/esp_system_internal.h" #include "internal/esp_system_internal.h"
#include "esp8266/eagle_soc.h"
#define FLASH_MAP_ADDR 0x40200000
#define FLASH_MAP_SIZE 0x00100000
extern void chip_boot(void); extern void chip_boot(void);
extern int rtc_init(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 esp_err_t esp_pthread_init(void);
extern void phy_get_bb_evm(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) static void user_init_entry(void *param)
{ {
void (**func)(void); void (**func)(void);
@ -97,7 +105,7 @@ void call_user_start(size_t start_addr)
extern int _bss_start, _bss_end; 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)); 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. */ /* 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++) { 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); 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 *dest = (uint32_t *)segment->load_addr;
uint32_t *src = (uint32_t *)((uintptr_t)segment + sizeof(esp_image_segment_header_t)); uint32_t *src = (uint32_t *)((uintptr_t)segment + sizeof(esp_image_segment_header_t));
uint32_t size = segment->data_len / sizeof(uint32_t); uint32_t size = segment->data_len / sizeof(uint32_t);