bootloader: API for the fast wakeup and custom using RTC mem
Added "Reserve RTC FAST memory for custom purposes" option. Added a boot counter.
This commit is contained in:
parent
abffc3b11d
commit
c543aac91e
8 changed files with 198 additions and 3 deletions
|
@ -235,7 +235,7 @@ menu "Bootloader config"
|
||||||
|
|
||||||
config BOOTLOADER_RESERVE_RTC_SIZE
|
config BOOTLOADER_RESERVE_RTC_SIZE
|
||||||
hex
|
hex
|
||||||
default 0x10 if BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
|
default 0x10 if BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP || BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||||
default 0
|
default 0
|
||||||
help
|
help
|
||||||
Reserve RTC FAST memory for Skip image validation. This option in bytes.
|
Reserve RTC FAST memory for Skip image validation. This option in bytes.
|
||||||
|
@ -244,6 +244,28 @@ menu "Bootloader config"
|
||||||
When a wakeup occurs (from Deep sleep), the bootloader retrieves it and
|
When a wakeup occurs (from Deep sleep), the bootloader retrieves it and
|
||||||
loads the application without validation.
|
loads the application without validation.
|
||||||
|
|
||||||
|
config BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||||
|
bool "Reserve RTC FAST memory for custom purposes"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option allows the customer to place data in the RTC FAST memory,
|
||||||
|
this area remains valid when rebooted, except for power loss.
|
||||||
|
This memory is located at a fixed address and is available
|
||||||
|
for both the bootloader and the application.
|
||||||
|
(The application and bootoloader must be compiled with the same option).
|
||||||
|
The RTC FAST memory has access only through PRO_CPU.
|
||||||
|
|
||||||
|
config BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE
|
||||||
|
hex "Size in bytes for custom purposes"
|
||||||
|
range 0 0x10
|
||||||
|
default 0
|
||||||
|
depends on BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||||
|
help
|
||||||
|
This option reserves in RTC FAST memory the area for custom purposes.
|
||||||
|
If you want to create your own bootloader and save more information
|
||||||
|
in this area of memory, you can increase it. It must be a multiple of 4 bytes.
|
||||||
|
This area (rtc_retain_mem_t) is reserved and has access from the bootloader and an application.
|
||||||
|
|
||||||
endmenu # Bootloader
|
endmenu # Bootloader
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,14 @@ void __attribute__((noreturn)) call_start_cpu0(void)
|
||||||
bootloader_reset();
|
bootloader_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
|
||||||
|
// If this boot is a wake up from the deep sleep then go to the short way,
|
||||||
|
// try to load the application which worked before deep sleep.
|
||||||
|
// It skips a lot of checks due to it was done before (while first boot).
|
||||||
|
bootloader_utility_load_boot_image_from_deep_sleep();
|
||||||
|
// If it is not successful try to load an application as usual.
|
||||||
|
#endif
|
||||||
|
|
||||||
// 2. Select the number of boot partition
|
// 2. Select the number of boot partition
|
||||||
bootloader_state_t bs = { 0 };
|
bootloader_state_t bs = { 0 };
|
||||||
int boot_index = select_partition_number(&bs);
|
int boot_index = select_partition_number(&bs);
|
||||||
|
|
|
@ -146,6 +146,68 @@ esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t
|
||||||
*/
|
*/
|
||||||
void bootloader_common_vddsdio_configure(void);
|
void bootloader_common_vddsdio_configure(void);
|
||||||
|
|
||||||
|
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
|
||||||
|
/**
|
||||||
|
* @brief Returns partition from rtc_retain_mem
|
||||||
|
*
|
||||||
|
* Uses to get the partition of application which was worked before to go to the deep sleep.
|
||||||
|
* This partition was stored in rtc_retain_mem.
|
||||||
|
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
|
||||||
|
* Make sure that this function is used only PRO_CPU.
|
||||||
|
*
|
||||||
|
* @return partition: If rtc_retain_mem is valid.
|
||||||
|
* - NULL: If it is not valid.
|
||||||
|
*/
|
||||||
|
esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update the partition and reboot_counter in rtc_retain_mem.
|
||||||
|
*
|
||||||
|
* This function saves the partition of application for fast booting from the deep sleep.
|
||||||
|
* An algorithm uses this partition to avoid reading the otadata and does not validate an image.
|
||||||
|
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
|
||||||
|
* Make sure that this function is used only PRO_CPU.
|
||||||
|
*
|
||||||
|
* @param[in] partition App partition description. Can be NULL, in this case rtc_retain_mem.partition is not updated.
|
||||||
|
* @param[in] reboot_counter If true then update reboot_counter.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset entire rtc_retain_mem.
|
||||||
|
*
|
||||||
|
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
|
||||||
|
* Make sure that this function is used only PRO_CPU.
|
||||||
|
*/
|
||||||
|
void bootloader_common_reset_rtc_retain_mem(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns reboot_counter from rtc_retain_mem
|
||||||
|
*
|
||||||
|
* The reboot_counter counts the number of reboots. Reset only when power is off.
|
||||||
|
* The very first launch of the application will be from 1.
|
||||||
|
* Overflow is not possible, it will stop at the value UINT16_MAX.
|
||||||
|
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
|
||||||
|
* Make sure that this function is used only PRO_CPU.
|
||||||
|
*
|
||||||
|
* @return reboot_counter: 1..65535
|
||||||
|
* - 0: If rtc_retain_mem is not valid.
|
||||||
|
*/
|
||||||
|
uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns rtc_retain_mem
|
||||||
|
*
|
||||||
|
* Note: This function operates the RTC FAST memory which available only for PRO_CPU.
|
||||||
|
* Make sure that this function is used only PRO_CPU.
|
||||||
|
*
|
||||||
|
* @return rtc_retain_mem
|
||||||
|
*/
|
||||||
|
rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,6 +51,34 @@ typedef enum {
|
||||||
#endif
|
#endif
|
||||||
} esp_image_load_mode_t;
|
} esp_image_load_mode_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
esp_partition_pos_t partition; /*!< Partition of application which worked before goes to the deep sleep. */
|
||||||
|
uint16_t reboot_counter; /*!< Reboot counter. Reset only when power is off. */
|
||||||
|
uint16_t reserve; /*!< Reserve */
|
||||||
|
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||||
|
uint8_t custom[CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE]; /*!< Reserve for custom propose */
|
||||||
|
#endif
|
||||||
|
uint32_t crc; /*!< Check sum crc32 */
|
||||||
|
} rtc_retain_mem_t;
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||||
|
_Static_assert(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) || defined(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC)
|
||||||
|
_Static_assert(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE % 4 == 0, "CONFIG_BOOTLOADER_RESERVE_RTC_SIZE must be a multiple of 4 bytes");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||||
|
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
|
||||||
|
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
|
||||||
|
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) || defined(CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC)
|
||||||
|
_Static_assert(sizeof(rtc_retain_mem_t) <= ESP_BOOTLOADER_RESERVE_RTC, "Reserved RTC area must exceed size of rtc_retain_mem_t");
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Verify and (optionally, in bootloader mode) load an app image.
|
* @brief Verify and (optionally, in bootloader mode) load an app image.
|
||||||
*
|
*
|
||||||
|
|
|
@ -54,6 +54,16 @@ int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
|
||||||
*/
|
*/
|
||||||
__attribute__((noreturn)) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index);
|
__attribute__((noreturn)) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index);
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
|
||||||
|
/**
|
||||||
|
* @brief Load that application which was worked before we go to the deep sleep.
|
||||||
|
*
|
||||||
|
* Checks the reboot reason if it is the deep sleep and has a valid partition in the RTC memory
|
||||||
|
* then try to load the application which was worked before we go to the deep sleep.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void bootloader_utility_load_boot_image_from_deep_sleep(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Software reset the ESP32
|
* @brief Software reset the ESP32
|
||||||
|
|
|
@ -270,3 +270,66 @@ void bootloader_common_vddsdio_configure(void)
|
||||||
}
|
}
|
||||||
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
|
||||||
|
|
||||||
|
rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)(SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t));
|
||||||
|
|
||||||
|
static bool check_rtc_retain_mem(void)
|
||||||
|
{
|
||||||
|
return crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, sizeof(rtc_retain_mem_t) - sizeof(rtc_retain_mem->crc)) == rtc_retain_mem->crc && rtc_retain_mem->crc != UINT32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_rtc_retain_mem_crc(void)
|
||||||
|
{
|
||||||
|
rtc_retain_mem->crc = crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, sizeof(rtc_retain_mem_t) - sizeof(rtc_retain_mem->crc));
|
||||||
|
}
|
||||||
|
|
||||||
|
void bootloader_common_reset_rtc_retain_mem(void)
|
||||||
|
{
|
||||||
|
memset(rtc_retain_mem, 0, sizeof(rtc_retain_mem_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void)
|
||||||
|
{
|
||||||
|
if (check_rtc_retain_mem()) {
|
||||||
|
return rtc_retain_mem->reboot_counter;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void)
|
||||||
|
{
|
||||||
|
if (check_rtc_retain_mem()) {
|
||||||
|
return &rtc_retain_mem->partition;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter)
|
||||||
|
{
|
||||||
|
if (reboot_counter) {
|
||||||
|
if (!check_rtc_retain_mem()) {
|
||||||
|
bootloader_common_reset_rtc_retain_mem();
|
||||||
|
}
|
||||||
|
if (++rtc_retain_mem->reboot_counter == 0) {
|
||||||
|
// do not allow to overflow. Stop it.
|
||||||
|
--rtc_retain_mem->reboot_counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (partition != NULL) {
|
||||||
|
rtc_retain_mem->partition.offset = partition->offset;
|
||||||
|
rtc_retain_mem->partition.size = partition->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_rtc_retain_mem_crc();
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void)
|
||||||
|
{
|
||||||
|
return rtc_retain_mem;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -417,7 +417,7 @@ static void set_actual_ota_seq(const bootloader_state_t *bs, int index)
|
||||||
update_anti_rollback(&bs->ota[index]);
|
update_anti_rollback(&bs->ota[index]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP )
|
#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
|
||||||
esp_partition_pos_t partition = index_to_partition(bs, index);
|
esp_partition_pos_t partition = index_to_partition(bs, index);
|
||||||
bootloader_common_update_rtc_retain_mem(&partition, true);
|
bootloader_common_update_rtc_retain_mem(&partition, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
#define CONFIG_BT_RESERVE_DRAM 0
|
#define CONFIG_BT_RESERVE_DRAM 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
|
#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
|
||||||
|
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE)
|
||||||
|
#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP)
|
||||||
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
|
#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE)
|
||||||
#else
|
#else
|
||||||
#define ESP_BOOTLOADER_RESERVE_RTC 0
|
#define ESP_BOOTLOADER_RESERVE_RTC 0
|
||||||
|
|
Loading…
Reference in a new issue