Add embedded storage drivers and extend firmware metadata

This commit is contained in:
2026-09-27 01:44:59 +03:00
parent 795a1279b1
commit 2ad29e7ffd
52 changed files with 5801 additions and 3 deletions

140
c/spi-nor/Inc/spi_nor.h Normal file
View File

@@ -0,0 +1,140 @@
#ifndef PORTABLE_SPI_NOR_H
#define PORTABLE_SPI_NOR_H
/*
* Переносимое ядро SPI NOR.
*
* Ядро знает только стандартные SPI-команды и callbacks платформы. Оно не
* включает HAL, регистры MCU, GPIO проекта, Modbus или код приложения. Каждый
* экземпляр хранит собственное состояние и поэтому не использует глобальные
* изменяемые переменные.
*/
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Поддерживаемые микросхемы ограничены устройствами с 24-битной адресацией. */
typedef enum
{
SPI_NOR_MODEL_NONE = 0,
SPI_NOR_MODEL_W25Q64,
SPI_NOR_MODEL_W25Q128,
SPI_NOR_MODEL_SST25VF016B
} spi_nor_model_t;
/* Ошибки протокола не зависят от кодов конкретного HAL. */
typedef enum
{
SPI_NOR_OK = 0,
SPI_NOR_E_ARGUMENT = -1,
SPI_NOR_E_IO = -2,
SPI_NOR_E_TIMEOUT = -3,
SPI_NOR_E_NOT_FOUND = -4,
SPI_NOR_E_UNSUPPORTED = -5,
SPI_NOR_E_BOUNDS = -6,
SPI_NOR_E_ALIGNMENT = -7,
SPI_NOR_E_VERIFY = -8,
SPI_NOR_E_BUSY = -9
} spi_nor_status_t;
/* Callback SPI возвращает только переносимый результат физического обмена. */
typedef enum
{
SPI_NOR_IO_OK = 0,
SPI_NOR_IO_ERROR = -1,
SPI_NOR_IO_TIMEOUT = -2
} spi_nor_io_status_t;
/* Геометрия и JEDEC доступны приложению только как копируемая диагностика. */
typedef struct
{
spi_nor_model_t model;
uint8_t manufacturer_id;
uint8_t memory_type;
uint8_t capacity_code;
uint32_t capacity_bytes;
uint32_t sector_size;
uint16_t page_size;
} spi_nor_info_t;
/*
* Контракт платформы описывает одну SPI-шину и один сигнал CS.
*
* transfer выполняется при уже активном CS. NULL в tx означает передачу
* dummy-байтов, NULL в rx — игнорирование принятого потока. lock/unlock
* необязательны; RTOS-порт может ими сериализовать полную read/program/erase
* операцию, а не отдельный SPI пакет.
*/
typedef struct
{
void *context;
spi_nor_io_status_t (*transfer)(void *context, const uint8_t *tx,
uint8_t *rx, size_t size,
uint32_t timeout_ms);
void (*chip_select)(void *context, uint8_t active);
uint32_t (*tick_ms)(void *context);
void (*delay_ms)(void *context, uint32_t delay_ms);
spi_nor_io_status_t (*lock)(void *context, uint32_t timeout_ms);
void (*unlock)(void *context);
} spi_nor_io_t;
/* Тайм-ауты вынесены в конфигурацию для медленных шин и разных RTOS. */
typedef struct
{
uint32_t io_timeout_ms;
uint32_t lock_timeout_ms;
uint32_t program_timeout_ms;
uint32_t erase_timeout_ms;
uint32_t ready_poll_delay_ms;
} spi_nor_config_t;
/* Контекст полностью принадлежит вызывающему коду и не требует malloc. */
typedef struct
{
spi_nor_io_t io;
spi_nor_config_t config;
spi_nor_info_t info;
uint8_t initialized;
uint8_t detected;
uint8_t busy;
} spi_nor_t;
/* Возвращает документированные безопасные тайм-ауты библиотеки. */
spi_nor_config_t spi_nor_default_config(void);
/* Инициализация только копирует callbacks и не обращается к физической шине. */
spi_nor_status_t spi_nor_init(spi_nor_t *device, const spi_nor_io_t *io,
const spi_nor_config_t *config);
/* Probe будит память, читает JEDEC и разрешает работу известной геометрии. */
spi_nor_status_t spi_nor_probe(spi_nor_t *device);
/* Операции используют физические смещения микросхемы, начиная с нуля. */
spi_nor_status_t spi_nor_read(spi_nor_t *device, uint32_t address,
void *data, size_t size);
spi_nor_status_t spi_nor_program(spi_nor_t *device, uint32_t address,
const void *data, size_t size);
spi_nor_status_t spi_nor_erase(spi_nor_t *device, uint32_t address,
size_t size);
/* Информация выдаётся только после успешного распознавания поддержанной модели. */
spi_nor_status_t spi_nor_get_info(const spi_nor_t *device,
spi_nor_info_t *info);
/* Последний JEDEC доступен и для различения пустой шины и неизвестной модели. */
spi_nor_status_t spi_nor_get_last_jedec(const spi_nor_t *device,
uint8_t jedec[3]);
/* Read-only диагностика возвращает status register 1 под общей блокировкой. */
spi_nor_status_t spi_nor_read_status_register(spi_nor_t *device,
uint8_t *status);
#ifdef __cplusplus
}
#endif
#endif /* PORTABLE_SPI_NOR_H */