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 = 0x600(1536 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 语言中,
0x07700和0x7700会被编译器解析为完全相同的整数。前导 0 只是书写风格,不改变数值。所以当你看到0x07E00和0x7E00时,它们也是同一个数(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)冲突
检查清单¶
- 理解相对地址(偏移)和物理地址的区别
- 确认
0x07700和0x7700是同一个数(无前导零歧义) - 配置区与 SNV 区紧密排列,不留空隙
- 所有地址不超出 DataFlash 32 KB(偏移
0x8000)边界 - 核对 MESH、OTA 等其他系统占用的区域,避免冲突
- 实际编译下载后,用 ISP 工具读取 DataFlash 验证数据位置
- 测试 BLE 配对、解绑、重新配对,确认 SNV 数据正确保存
参考链接¶
- CH582M Flash 存储与 SNV 详解 — 完整的 Flash 分区地图和 SNV 机制