Files
templates/c/spi-nor/README.md

114 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Переносимая библиотека SPI NOR
`SpiNor` — самостоятельный синхронный драйвер последовательной NOR Flash. Он
не зависит от STM32, HAL, `main.c`, GPIO проекта, Modbus, GUI и FlashStorage.
Память для контекста предоставляет приложение; `malloc` и глобальное изменяемое
состояние не используются.
## Поддержанные микросхемы
| Модель | JEDEC | Ёмкость | Program | Erase |
|---|---:|---:|---:|---:|
| W25Q64 | `EF 40 17` | 8 МиБ | страницы до 256 байт | 4 КиБ |
| W25Q128 | `EF 40 18` | 16 МиБ | страницы до 256 байт | 4 КиБ |
| SST25VF016B | `BF 25 41` | 2 МиБ | безопасный Byte Program | 4 КиБ |
Ядро использует команды с 24-битным адресом и намеренно не принимает
микросхемы больше 16 МиБ. Неизвестный JEDEC возвращает
`SPI_NOR_E_UNSUPPORTED`; пустая шина `00 00 00` или `FF FF FF` —
`SPI_NOR_E_NOT_FOUND`.
## Структура
- `Inc/spi_nor.h` — публичные типы, callbacks, конфигурация и API;
- `Src/spi_nor.c` — переносимый протокол, JEDEC, bounds, тайм-ауты и verify;
- `Port/STM32F4_HAL` — единственное место с зависимостью от STM32F4 HAL;
- `Examples/portable_init.c` — минимальная интеграция без имён текущей платы;
- `PORTING.md` — пошаговый перенос на другой STM32 или другой MCU;
- `Tests` — mock-шина и сценарии без HAL и реального оборудования.
- `Diagnostics` — два bounded read-only сервиса без HAL/Modbus/GUI;
`spi_nor_read_service` читает физический диапазон через callback, а
`spi_nor_command_service` выполняет одну разрешённую сервисную транзакцию.
Адаптер журнала находится отдельно в
`Libraries/FlashStorage/Adapter/SPI_NOR`: FlashStorage не проникает в ядро
SPI NOR, а SPI NOR не знает формат журнала.
Диагностический сервис принимает только capacity и callback чтения, ограничивает
один пакет 64 байт и не имеет `program`/`erase` API. Приложение может связать
его с Modbus, не добавляя GUI или прикладные зависимости в ядро `SpiNor`.
### Сервис коротких SPI-команд
`spi_nor_command_service` принимает `spi_nor_t`, request с `sequence`, TX до
4 байт и RX до 64 байт, а response возвращает status, echo TX и RX. Владельцем
контекста остаётся приложение; сервис не выделяет память и не хранит историю.
Allowlist одинаков для всех трёх поддержанных моделей:
| Opcode | Строгая форма | Причина допуска |
|---:|---|---|
| `9F` | TX 1, RX 3 | JEDEC ID |
| `05` | TX 1, RX 1 | status register 1 |
| `03` | TX 4 (`03 A2 A1 A0`), RX 1–64 | обычное 24-битное чтение с bounds |
Любой другой opcode возвращает `BLOCKED`. В частности, запрещены WREN/WRDI,
program, все erase, status/protection writes, power-down/release, reset и
неизвестные команды. Это fail-closed read-only API, а не универсальный SPI
terminal. Изменяющий сервисный режим не требуется и в библиотеку не включён.
Одна операция имеет порядок `CS active -> TX -> dummy RX -> CS inactive`.
После ошибки или тайм-аута TX/RX сервис безусловно освобождает CS и очищает
частичный RX. Он использует тот же `busy` и необязательные `lock/unlock`, что
основной экземпляр `spi_nor_t`.
## Публичный API
```c
spi_nor_io_t io;
spi_nor_t flash;
/* Порт приложения заполняет callbacks и собственный io.context. */
FillPlatformCallbacks(&io);
if (spi_nor_init(&flash, &io, NULL) == SPI_NOR_OK &&
spi_nor_probe(&flash) == SPI_NOR_OK) {
uint8_t bytes[16];
(void)spi_nor_read(&flash, 0U, bytes, sizeof(bytes));
}
```
`spi_nor_program()` автоматически делит поток по страницам и проверяет каждый
chunk обратным чтением. `spi_nor_erase()` принимает только полные выровненные
4-КиБ секторы и проверяет каждый стёртый байт на `0xFF`.
## Электрическое подключение
Нужны `SCK`, `MOSI`, `MISO`, отдельный active-low `CS`, питание и земля.
Питание и допустимую частоту следует брать из datasheet конкретной модели.
Для текущей платы используются SPI2: `PB10/SCK`, `PC3/MOSI`, `PC2/MISO` и
`PE3/CS`, но эти имена находятся только в `app_storage.c`.
## Ограничения выполнения
- API синхронный и не предназначен для ISR;
- erase может блокировать вызывающий поток до заданного тайм-аута;
- один `spi_nor_t` не допускает рекурсивных операций;
- при RTOS callbacks `lock/unlock` должны защищать всю составную операцию;
- общий SPI bus требует согласованного mutex и корректного управления CS всех
подключённых устройств;
- DMA callback нельзя считать завершённым до фактического окончания обмена;
- библиотека не меняет SPI mode и clock: это обязанность платформенного порта.
## Гарантии ошибок
При любой ошибке обмена CS возвращается в неактивное состояние. Ошибка program
или erase не маскируется: результат считается успешным только после ожидания
BUSY и полного readback verify. Повторять изменяющую операцию автоматически
библиотека не будет, потому что политика повторов принадлежит приложению.
## Shared source
Canonical source: `templates/c/spi-nor`. Used by `home/climate`; its old paths are compatibility includes. Board-specific ports remain in the application. Change this library, not the forwarding files.