# zephyr-nvs **Repository Path**: zouchuan/zephyr-nvs ## Basic Information - **Project Name**: zephyr-nvs - **Description**: zephyr-4.4.1 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-11 - **Last Updated**: 2026-07-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Zephyr-NVS — 可移植的非易失性存储(NVS)框架 ## 1. 项目简介 本项目提供一套**硬件无关、可独立移植**的非易失性存储(NVS,Non-Volatile Storage)框架, 源自 Zephyr RTOS 的 `subsys/kvss/nvs`,并进行了分层重构。 - **`NVS1/`** —— 重构后的框架主体:将 Flash 访问收敛到统一的 HAL 接口(`struct nvs_hal_ops`), 将日志 / 锁等 OS 相关能力收敛到弱符号平台钩子(`nvs_port_*`)。移植到新 MCU / 新 RTOS 时, **只需实现底层 HAL**,核心逻辑与上层应用代码零修改。 - **`NVS0/`** —— 原版 Zephyr NVS 代码的精确提取(未经改动),作为行为对照与迁移兼容性基准, 用于审计校验逻辑、CRC 实现是否与原版逐位一致。 核心特性:磨损均衡、垃圾回收(GC)、分配表项(ATE)管理、元数据 CRC8 与数据 CRC32 校验、 可选查找缓存。校验实现已对齐 Zephyr 原版(标准 CRC-32,含最终异或 `0xFFFFFFFF`), 可正确读取原有 Zephyr NVS 已格式化的 Flash。 --- ## 2. 目录结构 ``` zephyr-nvs/ ├── NVS0/ # 原版 Zephyr NVS(参考基准,未改动) │ ├── CMakeLists.txt │ ├── Kconfig │ ├── include/zephyr/kvss/nvs.h │ └── src/ │ ├── nvs.c │ └── nvs_priv.h ├── NVS1/ # 重构后的可移植 NVS 框架(主体) │ ├── include/ │ │ ├── nvs.h # 顶层统一 API(应用唯一需要包含的头) │ │ ├── nvs_hal.h # 底层 HAL 接口定义(移植契约) │ │ ├── nvs_config.h # 编译期特性开关(无 Kconfig 依赖) │ │ └── nvs_port.h # OS/工具链 钩子(日志、锁)声明 │ ├── src/ │ │ ├── nvs_core.c # 中间层核心逻辑(磨损均衡、GC、ATE、CRC) │ │ ├── nvs_core_priv.h# 核心私有类型(ATE、掩码、缓冲等) │ │ ├── nvs_crc.c # 可移植 CRC32 / CRC8 实现 │ │ └── nvs_port.c # 平台钩子默认弱实现(无锁 / stderr 日志) │ ├── ports/ │ │ ├── ram/ # 纯内存 HAL(主机 / 单测,无需硬件) │ │ └── zephyr/ # 参考移植:Zephyr flash 驱动 + Zephyr 平台钩子 │ ├── examples/ │ │ └── nvs_ram_example.c # 完整 API 使用示例 │ ├── CMakeLists.txt │ └── README.md └── README.md ``` ### 分层架构 ``` ┌─────────────────────────────────────────────────────┐ │ 应用层 #include "nvs.h" → nvs_mount / nvs_write ... │ └───────────────────────────┬─────────────────────────┘ ┌───────────────────────────┴─────────────────────────┐ │ 顶层 API (nvs.h) 统一对外接口 │ └───────────────────────────┬─────────────────────────┘ ┌───────────────────────────┴─────────────────────────┐ │ 中间层 Core (src/nvs_core.c) │ │ 磨损均衡 · GC · ATE · CRC 校验 · 查找缓存 │ │ 只通过 函数指针/结构体接口 访问下层 │ └───────────────────────────┬─────────────────────────┘ struct nvs_hal_ops(函数指针) ┌───────────────────────────┴─────────────────────────┐ │ 底层 HAL (nvs_hal.h + 各 port 实现) │ │ ports/ram : 内存模拟后端(主机 / 单测) │ │ ports/zephyr: Zephyr flash 驱动参考移植 │ └─────────────────────────────────────────────────────┘ ``` --- ## 3. 环境要求 | 组件 | 要求 | |------|------| | C 编译器 | 支持 C99 的 GCC / Clang(如 `gcc`、`arm-none-eabi-gcc`、`clang`) | | 构建系统(可选) | CMake ≥ 3.20(仅主机示例使用) | | 主机验证 | 任意带标准 C 库(提供 ``)的 PC,无需真实硬件 | | 目标平台 | MCU / RTOS(Zephyr 等),需提供 Flash 读写擦除驱动 | - 框架本身**不依赖任何 RTOS 或特定 libc**:日志与锁通过弱符号钩子 `nvs_port_*` 提供默认实现, 因此可在裸机、单线程、主机环境直接编译运行。 - 若工具链缺少 ``,编译时定义 `NVS_SSIZE_T`(例如 `-DNVS_SSIZE_T=int`)。 --- ## 4. 安装步骤 本项目为源码库,无需安装包,直接获取源码即可: ```bash git clone https://gitee.com/zouchuan/zephyr-nvs.git cd zephyr-nvs ``` 将 `NVS1/` 集成进你的工程只需: 1. 把 `NVS1/include/` 加入头文件搜索路径。 2. 编译 `NVS1/src/nvs_core.c`、`NVS1/src/nvs_crc.c`、`NVS1/src/nvs_port.c`。 3. 链接一个 HAL 后端:主机或单测用 `NVS1/ports/ram/nvs_hal_ram.c`; Zephyr 目标用 `NVS1/ports/zephyr/nvs_hal_zephyr.c` + `NVS1/ports/zephyr/nvs_port_zephyr.c`(替代 `src/nvs_port.c`)。 --- ## 5. 快速启动(主机,内存后端) 无需任何硬件,即可在 PC 上编译并运行完整示例: ### 方式一:直接用编译器(推荐,最透明) ```bash cd NVS1 cc -Iinclude -Isrc examples/nvs_ram_example.c \ src/nvs_core.c src/nvs_crc.c src/nvs_port.c \ ports/ram/nvs_hal_ram.c -o nvs_example ./nvs_example ``` 预期输出包含挂载、写读、更新、空闲空间统计、删除、全盘擦除等步骤的结果。 ### 方式二:CMake ```bash cd NVS1 cmake -B build -DNVS_BUILD_EXAMPLE=ON cmake --build build ./build/nvs_ram_example ``` --- ## 6. 使用示例 下面最小示例展示应用侧如何挂载并读写一个条目(完整版本见 `NVS1/examples/nvs_ram_example.c`)。 ```c #include #include #include "nvs.h" #include "nvs_hal_ram.h" #define SECTOR_SIZE 512 #define SECTOR_COUNT 3 static uint8_t flash_buf[SECTOR_SIZE * SECTOR_COUNT]; static struct nvs_ram_flash ram; static struct nvs_hal ram_hal; static struct nvs_fs fs; int main(void) { /* 1. 装配 HAL(唯一与平台相关的部分)。 */ nvs_ram_hal_init(&ram_hal, &ram, flash_buf, sizeof(flash_buf), SECTOR_SIZE); /* 2. 配置并挂载文件系统。 */ fs.hal = &ram_hal; fs.base_offset = 0; fs.sector_size = SECTOR_SIZE; fs.sector_count = SECTOR_COUNT; if (nvs_mount(&fs) != 0) { printf("mount failed\n"); return 1; } /* 3. 写入 / 读取。 */ nvs_write(&fs, 1, "hello nvs", strlen("hello nvs") + 1); char rbuf[32]; nvs_read(&fs, 1, rbuf, sizeof(rbuf)); printf("read: %s\n", rbuf); /* 4. 更新(旧副本随后由垃圾回收回收)。 */ nvs_write(&fs, 1, "updated", strlen("updated") + 1); /* 5. 删除条目。 */ nvs_delete(&fs, 1); return 0; } ``` ### 顶层 API 一览(`nvs.h`) | 函数 | 说明 | |------|------| | `nvs_mount(fs)` | 挂载文件系统,挂载前由应用填写 `hal` / `base_offset` / `sector_size` / `sector_count` | | `nvs_write(fs, id, data, len)` | 写入条目;`len==0` 等同删除;写入与已存内容相同则跳过(无 flash 写) | | `nvs_read(fs, id, data, len)` | 读取条目最新值 | | `nvs_read_hist(fs, id, data, len, cnt)` | 读取历史值(`cnt=0` 最新,`cnt=1` 上一次 …) | | `nvs_delete(fs, id)` | 删除条目 | | `nvs_clear(fs)` | 擦除整个 NVS 区域(之后需重新挂载) | | `nvs_calc_free_space(fs)` | 计算剩余空闲字节数 | | `nvs_sector_max_data_size(fs)` | 当前活跃扇区剩余连续空闲字节 | | `nvs_sector_use_next(fs)` | 强制关闭当前扇区并触发 GC(慎用,会额外擦除) | --- ## 7. 核心功能说明 - **磨损均衡**:以“扇区环”方式循环写入,均衡各扇区擦写次数,延长 Flash 寿命。 - **垃圾回收(GC)**:活跃扇区写满后压缩有效数据到下一扇区并擦除旧扇区,回收空间。 - **分配表项(ATE)**:环形 ATE + CRC8 保证元数据完整性;无效 / 损坏 ATE 在挂载时被跳过。 - **数据完整性校验**:开启 `NVS_DATA_CRC` 后,每个数据条目追加 CRC-32,读取时校验; CRC 实现为标准 CRC-32(多项式 `0xEDB88320`、初始 `0xFFFFFFFF`、最终异或 `0xFFFFFFFF`), 与 Zephyr 原版逐位一致。 - **查找缓存**:开启 `NVS_LOOKUP_CACHE` 后,用哈希缓存加速 `id → ATE` 定位,减少扫描。 - **全坏块恢复**:开启 `NVS_INIT_BAD_MEMORY_REGION` 后,挂载时若所有扇区均关闭(损坏), 自动整片擦除而非失败。 ### 移植到新 MCU / RTOS 1. **实现 HAL(必做)**:参照 `ports/ram/nvs_hal_ram.c`,把 `init / read / write / erase / get_params` 映射到目标 Flash 驱动,填充 `struct nvs_hal_ops`,将 `hal->ops` 指向它、 `hal->priv` 指向私有状态。 2. **适配平台钩子(按需)**:默认 `nvs_port.c` 为无锁 + stderr 日志,裸机 / 单线程可直接用; 多任务环境提供 `nvs_port_lock_init / nvs_port_lock / nvs_port_unlock` 的强定义 (如 `ports/zephyr/nvs_port_zephyr.c` 用 `k_mutex`),并可重写 `nvs_port_log` 接入自有日志。 3. **应用侧**:`#include "nvs.h"`,填好 `struct nvs_fs` 后调用 `nvs_mount()`。 > 关键点:核心逻辑(`src/nvs_core.c`)与顶层 API(`nvs.h`)在新平台上**完全复用,零修改**。 --- ## 8. 配置参数详情 所有特性以普通宏开关,既可在 `NVS1/include/nvs_config.h` 中修改,也可在命令行用 `-D` 覆盖(例如 `-DNVS_LOOKUP_CACHE=0`)。部分参数与 Zephyr 原版 `CONFIG_NVS_*` 对应。 | 宏 | 默认 | 含义 | |----|------|------| | `NVS_LOOKUP_CACHE` | `1` | 启用 `id → ATE` 查找缓存(小 RAM MCU 可关闭) | | `NVS_LOOKUP_CACHE_SIZE` | `16` | 查找缓存条目数 | | `NVS_DATA_CRC` | `1` | 数据写入 CRC-32 校验(对应 `CONFIG_NVS_DATA_CRC`) | | `NVS_INIT_BAD_MEMORY_REGION` | `0` | 全坏块时挂载即整片擦除(对应 `CONFIG_NVS_INIT_BAD_MEMORY_REGION`) | | `NVS_LOG_LEVEL` | `2` | 日志级别:`0` 关闭 / `1` 错误 / `2` 警告 / `3` 信息 / `4` 调试 | | `NVS_SSIZE_T` | 未定义 | 工具链缺 `` 时,指定 `ssize_t` 的基础整数类型 | > **移植契约注意**:HAL 的 `struct nvs_flash_params` 必须正确设置 > `erase_value`(真实 Flash 擦除后应为 `0xFF`,否则擦除回读校验会失败)、 > `erase_block_size`(通常等于扇区 / 页大小)与 `write_block_size`(写对齐粒度,须为 2 的幂)。 --- ## 9. 测试命令 项目以**主机内存后端示例**作为自测(验证核心逻辑与读写往返、迁移兼容性)。 ```bash # 1) 编译并运行 RAM 示例(即自测) cd NVS1 cc -Iinclude -Isrc examples/nvs_ram_example.c \ src/nvs_core.c src/nvs_crc.c src/nvs_port.c \ ports/ram/nvs_hal_ram.c -o nvs_example ./nvs_example # 预期:mount/write/read/update/free-space/delete/clear 各步骤均正常输出,无断言失败。 ``` ```bash # 2) 或用 CMake 构建示例后运行 cmake -B build -DNVS_BUILD_EXAMPLE=ON && cmake --build build && ./build/nvs_ram_example ``` 校验 / CRC 一致性对照:可将 `NVS1` 与原版 `NVS0` 的 CRC 实现对照,或接入已知向量测试 (例如字符串 `"123456789"` 的 CRC-32 应为 `0xCBF43926`)。 --- ## 10. 与原 Zephyr NVS 的差异 - 移除对 `flash_*` / `k_mutex_*` / `LOG_*` / `sys/crc` / Kconfig 的直接依赖。 - Flash 访问统一收敛到 `struct nvs_hal_ops`;日志与锁收敛到弱符号 `nvs_port_*`。 - 算法逻辑(ATE、GC、磨损均衡、CRC、查找缓存)完整保留,**校验行为与原版一致**。 --- ## 11. 开源协议 本项目以 **Apache License 2.0** 发布。各源文件头部均带有 `SPDX-License-Identifier: Apache-2.0` 标识。 ``` Copyright (c) 2026 zephyr-nvs contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` Kephyr 原版 NVS 源自 Zephyr Project(`NVS0/`),同样以 Apache-2.0 许可发布。 --- ## 12. 相关资源 - `NVS1/README.md` —— NVS1 框架的详细设计、分层与移植说明。 - `NVS0/` —— 原版 Zephyr NVS 代码(行为对照基准)。 - `NVS1/examples/nvs_ram_example.c` —— 端到端 API 使用示例。