Flash 驱动模型与公共接口
本页依据 文档基线与后续更新 中记录的 Zephyr main 快照更新。
Flash 驱动接口位于 <zephyr/drivers/flash.h>,设备接口位于 <zephyr/device.h>。
应用先取得设备并检查 device_is_ready(),再调用读、写、擦除或查询接口。
使能 CONFIG_FLASH=y,以及实际控制器/芯片所需的驱动选项。
设备、地址与分区
设备层 flash_read/write/erase 的偏移相对于该 Flash 设备起点,不是 CPU 的映射地址,
也不是分区内偏移。若操作某个分区,优先使用 Flash Map 与分区,
由 flash area 包装器进行边界检查。
下面的函数读取应用定义的 storage_partition 起点,不改变存储内容:
#include <zephyr/device.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/storage/flash_map.h>
#include <errno.h>
int read_storage(void *buffer, size_t length)
{
const struct device *dev = PARTITION_DEVICE(storage_partition);
if (!device_is_ready(dev)) {
return -ENODEV;
}
if (length > PARTITION_SIZE(storage_partition)) {
return -EINVAL;
}
return flash_read(dev, PARTITION_OFFSET(storage_partition), buffer, length);
}
此例要求 Devicetree 已定义并启用对应分区;分区宏的迁移说明见 Flash Map 章节。
读、写与擦除
API |
调用前需要确认的条件 |
|---|---|
|
地址有效、目标缓冲区足够大;实际限制由驱动决定 |
|
地址与长度满足最小写块要求,介质状态允许写入 |
|
地址与范围满足擦除布局,不覆盖其他应用数据 |
|
查询写入对齐单位,不等于擦除页大小 |
|
查询写块与擦除值等参数,并检查返回指针 |
读写擦除一般成功返回 0,失败返回负 errno。不同设备对“写入”与“擦除”的语义并不完全 相同,不要假设全部介质都要求相同的擦除值、页大小或读写并发行为。 NOR Flash 通常需要擦除后再写,NVS 等上层组件负责相应存储策略。
擦除布局
启用 CONFIG_FLASH_PAGE_LAYOUT=y 后,可使用 struct flash_pages_info 及:
flash_get_page_info_by_offs():按设备偏移查询页。flash_get_page_info_by_idx():按页索引查询。flash_get_page_count():查询页数量。flash_page_foreach():遍历,回调返回 false 可停止。
部分 Flash 有非均匀擦除区域。不能从第一个页的大小推断整个设备布局。 写块、擦除块和上层 NVS sector 是不同层次的概念。
JEDEC 与驱动实现
支持相应能力的驱动可提供 flash_read_jedec_id() 和 flash_sfdp_read()。
JEDEC ID 用于芯片识别,JESD216/SFDP 用于描述参数,是否可用要看驱动支持与配置。
不支持的操作可能返回 -ENOTSUP 等错误。
编写驱动时,控制器和芯片节点通过 binding 描述硬件属性,Kconfig 决定编译, 设备初始化决定运行时可用状态。应用只依赖公共 API;旧教程中的驱动函数表与私有宏 应结合当前版本源码阅读,不能直接当作稳定的应用接口。