Stream Flash 流式写入
本页依据 文档基线与后续更新 中记录的 Zephyr main 快照更新。
Stream Flash 把连续到达的数据片段汇聚到应用缓冲区,再按底层 Flash 写块要求写入。
它适合固件传输等场景,公共接口位于 <zephyr/storage/stream_flash.h>。
组件不负责网络协议、镜像认证或应用级传输重试。
初始化与最后一次 flush
启用 CONFIG_STREAM_FLASH=y、底层 Flash 驱动,以及示例需要的 CONFIG_FLASH_MAP=y。
stream_flash_init() 接收设备、缓冲区、缓冲区大小、设备内偏移、可用范围和可选回调。
缓冲区长度应是设备写块大小的整数倍,且不能超过适用擦除页大小。
下面的函数向应用专用、已按要求准备好的 storage_partition 写入一段数据:
#include <zephyr/device.h>
#include <zephyr/storage/flash_map.h>
#include <zephyr/storage/stream_flash.h>
#include <errno.h>
static struct stream_flash_ctx stream;
static uint8_t write_buffer[256];
int store_stream(const uint8_t *data, size_t length)
{
const struct flash_area *area;
int rc = flash_area_open(PARTITION_ID(storage_partition), &area);
if (rc != 0) {
return rc;
}
if (!device_is_ready(area->fa_dev)) {
flash_area_close(area);
return -ENODEV;
}
rc = stream_flash_init(&stream, area->fa_dev, write_buffer,
sizeof(write_buffer), area->fa_off,
area->fa_size, NULL);
if (rc == 0) {
rc = stream_flash_buffered_write(&stream, data, length, true);
}
flash_area_close(area);
return rc;
}
这是单次会话示例,不可由多个调用者并发复用同一个上下文。
实际分片传输先多次以 flush=false 写入,结束时调用一次 flush=true,
可用 NULL, 0, true 刷出最后剩余数据。flush 结束该会话,再次写入前必须重新初始化。
stream_flash_buffered_write() 返回状态码,不是本次写入字节数。
用 stream_flash_bytes_written() 查询已写载荷字节数,
stream_flash_bytes_buffered() 查询仍在 RAM 中的字节数。
底层对齐填充可能占用额外存储空间,应在传输前确认分区容量。
擦除与回读
是否由组件处理擦除取决于 CONFIG_STREAM_FLASH_ERASE 等配置;未启用自动擦除时,
调用者按介质要求准备目标区域。旧 stream_flash_erase_page() 已弃用,
需要主动擦除时使用 Flash Map 或 Flash 驱动接口,并明确擦除范围。
开启 CONFIG_STREAM_FLASH_POST_WRITE_CALLBACK 后,可传入回读校验回调。
回调得到写后读回的内容,能够更新摘要等;写缓冲区也用于回读,不能在回调中假设
原始发送缓冲区或网络片段仍在其中。
持久化进度
CONFIG_STREAM_FLASH_PROGRESS 提供基于 Settings 的进度保存、加载和清除接口。
需要配置可用的 Settings 后端,并在相应存储初始化完成后使用。
进度表示已经提交的写入位置,不会自动保存尚在 RAM 的片段,也不能自动证明前缀内容 与新下载镜像一致。恢复时应核对镜像身份、分区、已写数据和协议偏移, 从确认的提交位置继续,完成后清除对应进度。