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

View File

@@ -0,0 +1,82 @@
#ifndef SD_FILE_BROWSER_H
#define SD_FILE_BROWSER_H
#include <stdint.h>
/* Ограничения одинаковы для portable core, Modbus mailbox и GUI. */
#define SD_FILE_BROWSER_MAX_PATH 96U
#define SD_FILE_BROWSER_MAX_NAME 48U
#define SD_FILE_BROWSER_MAX_PAGE_ITEMS 3U
#define SD_FILE_BROWSER_MAX_CHUNK_BYTES 64U
typedef enum {
/* Успех означает полностью сформированную страницу, а не только open. */
SD_FILE_BROWSER_OK = 0,
/* BUSY оставляет retry политике приложения и ничего не пишет на носитель. */
SD_FILE_BROWSER_BUSY,
SD_FILE_BROWSER_NOT_READY,
SD_FILE_BROWSER_IO_ERROR,
SD_FILE_BROWSER_INVALID_PATH,
SD_FILE_BROWSER_INVALID_CURSOR,
SD_FILE_BROWSER_NAME_TOO_LONG,
SD_FILE_BROWSER_FILE_CHANGED,
SD_FILE_BROWSER_NOT_LOG_FILE
} SdFileBrowserStatus;
typedef struct {
/* Имя всегда завершается нулём и не содержит родительского пути. */
char name[SD_FILE_BROWSER_MAX_NAME + 1U];
uint32_t size;
uint16_t modified_date;
uint16_t modified_time;
uint8_t is_directory;
} SdFileBrowserEntry;
typedef struct {
/* Ответ имеет фиксированную RAM-ёмкость и никогда не выделяет heap. */
SdFileBrowserEntry items[SD_FILE_BROWSER_MAX_PAGE_ITEMS];
uint16_t next_offset;
uint8_t count;
uint8_t has_more;
} SdFileBrowserPage;
typedef struct {
/* Metadata повторяется в каждом chunk и защищает bridge от склейки разных версий файла. */
uint32_t total_size;
uint32_t offset;
uint16_t modified_date;
uint16_t modified_time;
uint8_t length;
uint8_t end_of_file;
uint8_t data[SD_FILE_BROWSER_MAX_CHUNK_BYTES];
} SdFileBrowserChunk;
typedef SdFileBrowserStatus (*SdFileBrowserListPageFn)(
void *context, const char *path, uint16_t offset, uint8_t limit,
SdFileBrowserPage *page);
typedef struct {
/* Context принадлежит платформе; portable core его не освобождает. */
void *context;
SdFileBrowserListPageFn list_page;
} SdFileBrowser;
/* Принимается только логический путь от корня карты: "/" или "/dir/file".
* Проверка не исправляет вход: неканонические строки отклоняются fail-closed. */
SdFileBrowserStatus SdFileBrowser_ValidatePath(const char *path);
/* Разрешает только legacy TEMPLOG.MD или суточный temperature_*.md внутри
* штатного корня niceOne/mounth; служебные JSON/прошивки сюда не попадают. */
SdFileBrowserStatus SdFileBrowser_ValidateLogFilePath(const char *path);
/* Разрешает только сырой образ .bin/.fw внутри каталога niceOne/firmware.
* Каталог отделён от журналов, чтобы прошивка и логи не смешивались. */
SdFileBrowserStatus SdFileBrowser_ValidateFirmwarePath(const char *path);
/* Вызов делегирует порту ровно одну ограниченную страницу каталога.
* Output предварительно очищается, поэтому ошибка не публикует старые имена. */
SdFileBrowserStatus SdFileBrowser_ListPage(
const SdFileBrowser *browser, const char *path, uint16_t offset,
uint8_t limit, SdFileBrowserPage *page);
#endif /* SD_FILE_BROWSER_H */