105 lines
3.7 KiB
C
105 lines
3.7 KiB
C
#ifndef PORTABLE_FLASH_STORAGE_H
|
||
#define PORTABLE_FLASH_STORAGE_H
|
||
#include <stddef.h>
|
||
#include <stdint.h>
|
||
|
||
#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
|