Flash Map 与分区

本页依据 文档基线与后续更新 中记录的 Zephyr main 快照更新。

Flash Map 用 struct flash_area 描述分区。公共接口位于 <zephyr/storage/flash_map.h>,启用 CONFIG_FLASH_MAP=y 及底层 Flash 驱动。 area 包含设备指针、设备内偏移和分区大小。

Devicetree 固定分区

下面是已有 flash0 节点上的示意片段;实际地址、大小必须按目标板的空闲空间调整, 不能覆盖引导程序、应用镜像或其他持久数据:

&flash0 {
    partitions {
        compatible = "fixed-partitions";
        #address-cells = <1>;
        #size-cells = <1>;

        storage_partition: partition@f0000 {
            label = "storage";
            reg = <0x000f0000 0x00010000>;
        };
    };
};

这里 storage_partition 是 节点标签,label = "storage" 是节点属性, 它们不能互换用于宏参数。现有板卡常已定义同名分区,应修改其配置而不是重复定义。 分区范围还需满足擦除布局。

当前分区宏

本次核对的公共头文件提供 PARTITION_ID、PARTITION_OFFSET、PARTITION_SIZE 和 PARTITION_DEVICE,可按节点标签取得分区信息。 旧 FIXED_PARTITION_* 名称已标记弃用,旧页面中的示例应迁移到新名称。

这些宏也考虑了上游当前支持的分区类型。嵌套分区或 mapped partition 的地址规则 应查阅所用版本头文件与 binding,不能简单把所有父节点地址相加。 分区 ID 由构建生成,不应硬编码数值或作为跨固件稳定的存储标识。

打开与访问

#include <zephyr/device.h>
#include <zephyr/storage/flash_map.h>
#include <errno.h>

int read_partition(void *buffer, 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 = flash_area_read(area, 0, buffer, length);
    flash_area_close(area);
    return rc;
}

flash_area_read/write/erase 的偏移是 分区内偏移,包装器检查范围再转换为设备偏移。 它们不免除底层驱动的写块和擦除对齐要求。直接调用 flash_write(area->fa_dev, ...) 则必须提供设备内偏移,并自行控制范围。

其他接口

flash_area_get_sectors() / flash_area_sectors() 获取分区的擦除布局。 调用者先提供数组容量,检查返回状态与实际数量,不能假设每个分区只有一个擦除块。 启用相应校验选项后,flash_area_check_int_sha256() 可校验内容摘要; 数据完整性校验本身不等于固件签名认证。

应用可自行构造 struct flash_area 并使用相关操作,但这不等于把它注册进由 Devicetree 生成的 ID 查找表。一般应用优先使用预定义分区和 flash_area_open()。

上游依据