#ifndef PORTABLE_FLASH_STORAGE_H #define PORTABLE_FLASH_STORAGE_H #include #include #ifdef __cplusplus extern "C" { #endif #define FLASH_STORAGE_IMAGE_SIZE 512U #define FLASH_STORAGE_RECORD_SIZE 544U #define FLASH_STORAGE_V1_RECORD_SIZE 288U typedef enum { FLASH_STORAGE_OK = 0, FLASH_STORAGE_E_ARGUMENT = -1, FLASH_STORAGE_E_LAYOUT = -2, FLASH_STORAGE_E_IO = -3, FLASH_STORAGE_E_NOT_FOUND = -4, FLASH_STORAGE_E_CORRUPT = -5, FLASH_STORAGE_E_BUSY = -6, FLASH_STORAGE_E_BOUNDS = -7 } flash_storage_status_t; typedef struct { flash_storage_status_t (*read)(void *context, uint32_t address, void *data, size_t size); flash_storage_status_t (*program)(void *context, uint32_t address, const void *data, size_t size); flash_storage_status_t (*erase)(void *context, uint32_t address, size_t size); uint32_t (*tick_ms)(void *context); } flash_storage_ops_t; typedef struct { uint32_t bank_address[2]; uint32_t bank_size; uint32_t program_alignment; uint32_t erase_alignment; uint32_t minimum_write_ms; uint8_t reserve_percent; } flash_storage_layout_t; typedef struct { const flash_storage_ops_t *ops; void *platform_context; flash_storage_layout_t layout; uint32_t latest_address; uint32_t latest_sequence; uint32_t next_address; uint32_t last_write_tick; uint32_t valid_records; uint32_t programmed_slots; uint16_t latest_version; uint8_t initialized; uint8_t busy; uint8_t wrote_this_boot; /* Рабочая запись принадлежит экземпляру: Flash API не расходует малый * embedded-стек на 544-байтные автоматические структуры. */ uint32_t workspace[FLASH_STORAGE_RECORD_SIZE / sizeof(uint32_t)]; } flash_storage_t; typedef struct { flash_storage_t journal; uint8_t image[FLASH_STORAGE_IMAGE_SIZE]; uint8_t next_image[FLASH_STORAGE_IMAGE_SIZE]; uint8_t initialized; } eeprom_store_t; typedef struct { uint32_t sequence; uint32_t valid_records; uint32_t programmed_slots; uint32_t allocated_bytes; uint32_t reserved_bytes; } flash_storage_info_t; flash_storage_status_t flash_storage_init(flash_storage_t *instance, const flash_storage_ops_t *ops, void *platform_context, const flash_storage_layout_t *layout); flash_storage_status_t flash_storage_read_latest(flash_storage_t *instance, void *data, size_t capacity, size_t *length, uint32_t *sequence); flash_storage_status_t flash_storage_write(flash_storage_t *instance, const void *data, size_t length); flash_storage_status_t flash_storage_format(flash_storage_t *instance); flash_storage_status_t flash_storage_get_info(flash_storage_t *instance, flash_storage_info_t *info); flash_storage_status_t eeprom_store_init(eeprom_store_t *instance, const flash_storage_ops_t *ops, void *platform_context, const flash_storage_layout_t *layout); flash_storage_status_t eeprom_store_read(eeprom_store_t *instance, size_t offset, void *data, size_t size); flash_storage_status_t eeprom_store_write(eeprom_store_t *instance, size_t offset, const void *data, size_t size); flash_storage_status_t eeprom_store_format(eeprom_store_t *instance); /* API не ISR-safe: erase/program могут надолго блокировать CPU. Один экземпляр * обслуживается последовательно; разные экземпляры допустимы на независимых * областях, а общий HAL Flash должен сериализовать платформенный адаптер. */ #ifdef __cplusplus } #endif #endif