跳转至

CH582M DataFlash 地址偏移实践

场景:自定义配置区与 BLE SNV 共存时的地址规划
实践日期:2026-07-17
来源:CodeBuddy 操作记录 + DeepSeek 分析验证
关联文章:CH582M Flash 存储与 SNV 详解


背景

CH582M Flash 存储与 SNV 详解 中已知:DataFlash 只有 32 KB,尾部默认被 BLE SNV 占用。当需要在 DataFlash 中同时存放用户自定义配置BLE 配对绑定信息时,就需要调整 SNV 的起始位置,把配置区"插"进去。

本文记录一次实际的地址规划操作,以及其中踩到的坑。


原始规划(CodeBuddy 操作)

目标:在 DataFlash 中开辟一段配置存储区,同时把 SNV 从默认位置下移,避免冲突。

原始方案

区域 DataFlash 偏移 大小 用途
用户配置区 0x7000 0x100 (256 B) 自定义配置参数
BLE SNV 区 0x7700 配对绑定信息(从 0x07E00 下移)

CodeBuddy 记录

使用 DataFlash【偏移 0x7000(物理 0x77000)~ 0x70FF】区域存储配置,BLE SNV 现位于偏移 0x7700,2026-07-17 由 0x07E00 下移扩容。


问题发现:地址规划有空洞

把方案交给 DeepSeek 分析后,发现原始规划存在空间浪费

DataFlash 布局(原始方案):
0x7000 ├─ 用户配置区 ──┤ 256 B (0x7000 ~ 0x70FF)
0x7100 ├─ 空闲 ────────┤ ???  (0x7100 ~ 0x76FF = 1536 B 未使用!)
0x7700 ├─ BLE SNV ─────┤ 从这儿开始

问题:配置区结束于 0x70FF,SNV 却从 0x7700 开始,中间空出了 0x7700 - 0x7100 = 0x6001536 B)的未使用区域。这在 32 KB 的 DataFlash 里是非常浪费的。


修正方案:紧凑布局

正确做法:SNV 应该紧跟用户配置区之后,中间不留空隙。

区域 DataFlash 偏移 大小 说明
用户配置区 0x7000 0x100 (256 B) 自定义配置参数
BLE SNV 区 0x7100 0x100 × N 紧跟配置区,N 为绑定设备数
DataFlash 布局(修正方案):
0x7000 ├─ 用户配置区 ──┤ 256 B (0x7000 ~ 0x70FF)
0x7100 ├─ BLE SNV #1 ──┤ 256 B (0x7100 ~ 0x71FF)
0x7200 ├─ BLE SNV #2 ──┤ 256 B (0x7200 ~ 0x72FF)
...    ├─ ...          ──┤ 按 256 B 块对齐

💡 每个绑定设备占用 256 B(实际有效数据约 224 B,协议栈按块对齐)。如果 BLE_SNV_NUM = 6,SNV 区总大小就是 6 × 256 = 1536 B = 0x600


核心知识点:相对地址 vs 物理地址

这是 CH58x DataFlash 操作中最容易混淆的地方。

概念 数值 说明
DataFlash 物理基地址 0x00070000 芯片手册中的绝对地址
用户配置区物理地址 0x00077000 0x70000 + 0x7000
DataFlash 接口使用的偏移 0x7000 EEPROM_READ/WRITE/ERASE 的参数
SNV 物理地址(默认) 0x00077E00 对应偏移 0x7E00
SNV 物理地址(修正后) 0x00077100 对应偏移 0x7100

关键区别

  • EEPROM_READ(offset, buffer, len) 里的 offset相对 DataFlash 起始的偏移
  • BLE_SNV_ADDR 宏在 CONFIG.h 里,不同版本可能是物理地址偏移地址,要看注释!

坑:0x07700 和 0x7700 有什么区别?

答案:没有区别,完全等价。

写法 数值 说明
0x07700 30464 (十进制) 前导 0 只是为了对齐位数,方便阅读
0x7700 30464 (十进制) 标准 16 进制写法
0x00007700 30464 (十进制) 32 位对齐写法

在 C 语言中,0x077000x7700 会被编译器解析为完全相同的整数。前导 0 只是书写风格,不改变数值。所以当你看到 0x07E000x7E00 时,它们也是同一个数(32000)。

但要注意: - 0x07E00偏移地址(相对于 DataFlash 基址 0x70000) - 0x77E00物理地址0x70000 + 0x7E00) - 这两个不是同一个数!


配置修改步骤(备忘)

假设要在 CONFIG.h 中实现上述修正方案:

// 1. 定义用户配置区(相对地址)
#define USER_CONFIG_ADDR    0x7000    // DataFlash 偏移
#define USER_CONFIG_SIZE    0x100     // 256 字节

// 2. 修改 SNV 起始地址(紧跟配置区之后)
#define BLE_SNV_ADDR        0x7100    // 原来是 0x7E00,下移到 0x7100
#define BLE_SNV_BLOCK       0x100     // 每个设备 256 B
#define BLE_SNV_NUM         6         // 支持 6 个绑定设备
// 总占用:0x7100 ~ 0x76FF (6 × 256 = 1536 B)

⚠️ 修改后务必验证: 1. USER_CONFIG_ADDR + USER_CONFIG_SIZE <= BLE_SNV_ADDR(不重叠) 2. BLE_SNV_ADDR + BLE_SNV_NUM * BLE_SNV_BLOCK <= 0x8000(不超出 DataFlash 边界) 3. 不与其他系统区域(如 MESH 的 12 KB、OTA 标志的 4 B)冲突


检查清单

  • 理解相对地址(偏移)和物理地址的区别
  • 确认 0x077000x7700 是同一个数(无前导零歧义)
  • 配置区与 SNV 区紧密排列,不留空隙
  • 所有地址不超出 DataFlash 32 KB(偏移 0x8000)边界
  • 核对 MESH、OTA 等其他系统占用的区域,避免冲突
  • 实际编译下载后,用 ISP 工具读取 DataFlash 验证数据位置
  • 测试 BLE 配对、解绑、重新配对,确认 SNV 数据正确保存

参考链接