# FlashStorage Переносимый журнал двух банков Flash с подтверждёнными записями и восстановлением после прерванной записи. Предоставляет также EEPROM-подобный образ 512 байт. Не содержит HAL, файловой системы, адресов конкретной платы или malloc. Приложение → `flash_storage` / `eeprom_store` → callbacks → Flash-порт платы. | Файл | Назначение | |---|---| | `Inc/flash_storage.h` | Контекст, раскладка банков, read/program/erase/tick callbacks | | `Inc/flash_storage_config.h` | Версия формата, magic, commit marker | | `Src/flash_storage.c` | Восстановление, запись, ротация банков; только стандартный C | | `Tests/test_flash_storage.c` | Прерывание записи, восстановление, несколько экземпляров | Порт получает контекст, адрес и длину. `read`/`program`/`erase` возвращают `flash_storage_status_t`; `tick_ms` возвращает uint32_t. Буферы принадлежат экземпляру. Стирание и программирование могут блокировать процессор: API не предназначен для ISR. Раскладку и резерв места задаёт `flash_storage_layout_t`. ```c /* board_ops, board_context и layout определяет порт конкретной платы. */ flash_storage_t journal; uint8_t payload[512] = {0}, restored[512]; size_t length = 0; flash_storage_status_t result; result = flash_storage_init(&journal, &board_ops, board_context, &layout); if (result == FLASH_STORAGE_OK) { result = flash_storage_write(&journal, payload, sizeof(payload)); } if (result == FLASH_STORAGE_OK) { result = flash_storage_read_latest(&journal, restored, sizeof(restored), &length, 0); } ``` Существующий потребитель — climate. Порты STM32F4 и SPI NOR остаются там. Проверка: `python tools/test_shared_libraries.py` из корня templates. ## Shared source Canonical source: `templates/c/flash-storage`. Used by `home/climate`; its old paths are compatibility includes. Board-specific ports remain in the application. Change this library, not the forwarding files.