mirror of
https://github.com/esphome/esphome.git
synced 2026-10-14 10:12:52 +00:00
Let the fit helper pick the store from both flash facts, guard the crash handler words, add tests
This commit is contained in:
@@ -37,15 +37,20 @@ def preference_words(value_bytes: int) -> int:
|
||||
return (value_bytes + 3) // 4 + 1
|
||||
|
||||
|
||||
def preference_slots(value_bytes: int, restore_from_flash: bool) -> int:
|
||||
"""How many values of this size fit, given where restore_from_flash sends them."""
|
||||
def preference_slots(value_bytes: int, in_flash: bool, restore_from_flash: bool) -> int:
|
||||
"""How many values of this size fit where make_preference() puts them."""
|
||||
words = preference_words(value_bytes)
|
||||
regions = (
|
||||
(PREFERENCES_FLASH_WORDS,)
|
||||
if restore_from_flash
|
||||
else (PREFERENCES_RTC_NORMAL_WORDS, PREFERENCES_RTC_EBOOT_WORDS)
|
||||
if in_flash or restore_from_flash:
|
||||
store = (
|
||||
PREFERENCES_FLASH_WORDS
|
||||
if restore_from_flash
|
||||
else PREFERENCES_FLASH_WORDS_WITHOUT_RESTORE
|
||||
)
|
||||
return store // words
|
||||
return sum(
|
||||
region // words
|
||||
for region in (PREFERENCES_RTC_NORMAL_WORDS, PREFERENCES_RTC_EBOOT_WORDS)
|
||||
)
|
||||
return sum(region // words for region in regions)
|
||||
|
||||
|
||||
# esp8266 namespace is already defined by arduino, manually prefix esphome
|
||||
|
||||
@@ -27,7 +27,9 @@ static constexpr uint32_t ESP_RTC_USER_MEM_SIZE_BYTES = ESP_RTC_USER_MEM_SIZE_WO
|
||||
static constexpr uint32_t RTC_EBOOT_REGION_WORDS = ESP8266_PREFERENCES_RTC_EBOOT_WORDS;
|
||||
static constexpr uint32_t RTC_NORMAL_REGION_WORDS = ESP8266_PREFERENCES_RTC_NORMAL_WORDS;
|
||||
static constexpr uint32_t PREF_TOTAL_WORDS = RTC_EBOOT_REGION_WORDS + RTC_NORMAL_REGION_WORDS; // 110
|
||||
static_assert(PREF_TOTAL_WORDS <= ESP_RTC_USER_MEM_SIZE_WORDS, "preference regions overflow RTC memory");
|
||||
static constexpr uint32_t RTC_CRASH_HANDLER_WORDS = 18; // Words 110-127, see crash_handler.cpp
|
||||
static_assert(PREF_TOTAL_WORDS + RTC_CRASH_HANDLER_WORDS <= ESP_RTC_USER_MEM_SIZE_WORDS,
|
||||
"preference regions overlap the crash handler's RTC words");
|
||||
|
||||
// Maximum preference size in words (limited by uint8_t length_words field)
|
||||
static constexpr uint32_t MAX_PREFERENCE_WORDS = 255;
|
||||
@@ -54,7 +56,7 @@ static inline bool esp_rtc_user_mem_write(uint32_t index, uint32_t value) {
|
||||
if (index >= ESP_RTC_USER_MEM_SIZE_WORDS) {
|
||||
return false;
|
||||
}
|
||||
if (index < 32 && s_prevent_write) {
|
||||
if (index < RTC_EBOOT_REGION_WORDS && s_prevent_write) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
"""The config-time fit rule must match make_preference() in preferences.cpp."""
|
||||
|
||||
import pytest
|
||||
|
||||
from esphome.components.esp8266.const import preference_slots, preference_words
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("value_bytes", "words"), [(0, 1), (1, 2), (4, 2), (5, 3), (94, 25)]
|
||||
)
|
||||
def test_preference_words_rounds_up_and_adds_the_checksum(
|
||||
value_bytes: int, words: int
|
||||
) -> None:
|
||||
assert preference_words(value_bytes) == words
|
||||
|
||||
|
||||
def test_rtc_values_cannot_straddle_the_regions() -> None:
|
||||
# 25 words each: 3 fit in the 78-word region and 1 in the 32-word one
|
||||
assert preference_slots(94, in_flash=False, restore_from_flash=False) == 4
|
||||
# 32 words each: 2 + 1, where 110 // 32 would also say 3
|
||||
assert preference_slots(124, in_flash=False, restore_from_flash=False) == 3
|
||||
# 39 words each: 2 + 0, where 110 // 39 would say 2 as well but the eboot region is skipped
|
||||
assert preference_slots(152, in_flash=False, restore_from_flash=False) == 2
|
||||
# Larger than the biggest region
|
||||
assert preference_slots(400, in_flash=False, restore_from_flash=False) == 0
|
||||
|
||||
|
||||
def test_flash_store_size_follows_restore_from_flash() -> None:
|
||||
assert preference_slots(94, in_flash=True, restore_from_flash=True) == 5
|
||||
assert preference_slots(94, in_flash=False, restore_from_flash=True) == 5
|
||||
assert preference_slots(94, in_flash=True, restore_from_flash=False) == 2
|
||||
Reference in New Issue
Block a user