Skip to content

CH592F DataFlash 使用说明

MeowKeyboard CH592F 固件在 DataFlash 中的存储布局说明。

DataFlash 概览

  • 基地址0x70000(CH592 物理地址)
  • 总容量:32KB (0x0000 ~ 0x7FFF)
  • 擦除粒度256B / 4KB(按区域策略使用)
  • 写入推荐:256 字节对齐

整体布局

地址范围大小用途
0x0000 ~ 0x0BFF3KB配置槽轮转区(3 槽 × 1KB,配置小擦写)
0x0C00 ~ 0x0FFF1KBruntime 热数据区(4 页 × 256B,层号高频持久化)
0x1000 ~ 0x4FFF16KB宏数据区(8 槽 × 2KB)
0x5000 ~ 0x7DFF11.5KB预留
0x7E00 ~ 0x7EFF256BBLE SNV(蓝牙配对信息)
0x7F00 ~ 0x7FFF256B预留

当前策略:宏大擦写(4KB 块)配置小擦写(256B 页)层号独立热数据页环


配置区 (0x0000 ~ 0x0FFF)

配置区采用冷热分离:

  • 0x0000 ~ 0x0BFF:配置槽轮转区(3 槽 × 1KB)
  • 0x0C00 ~ 0x0FFF:runtime 热数据区(4 页 × 256B)

配置槽内偏移保持不变(以下偏移为槽位内偏移)。

runtime 热数据页(0x0C00 ~ 0x0FFF,当前实现)

runtime 区用于高频持久化状态(当前已用于 current_layer)。区域总计 1KB,由 4 × 256B 页组成,按页轮转。

单页结构 kbd_runtime_page_t(256B)

字节偏移字段类型说明
0-30x00magicuint32_t0x52554E54 (\"RUNT\")
4-50x04versionuint16_t0x0001
6-70x06flagsuint16_t预留,当前写 0
8-110x08sequint32_t页轮转序号(递增)
120x0Ccurrent_layeruint8_t当前层(高频保存)
13-2510x0D ~ 0xFBreserveduint8_t[239]预留
252-2550xFC ~ 0xFFcrc32uint32_t整页校验(末尾字段除外)

加载时扫描 4 页,校验 magic/version/crc32 后选择 seq 最大的有效页。

runtime 页(规划 v2,建议)

为后续模式恢复与蓝牙槽位扩展预留字段,建议在 version=0x0002 时使用以下布局(当前未启用):

字节偏移字段类型说明
0-30x00magicuint32_t\"RUNT\"
4-50x04versionuint16_t0x0002(规划)
6-70x06flagsuint16_truntime 标志位
8-110x08sequint32_t页轮转序号
120x0Ccurrent_layeruint8_t当前层
130x0Dactive_modeuint8_t当前模式(USB/BLE/2.4G,可选持久化)
140x0Eprofile_slot_reserveduint8_t预留(未来 BLE 多槽位)
150x0Fruntime_flagsuint8_t预留运行态标志
16-2510x10 ~ 0xFBreserveduint8_t[236]预留
252-2550xFC ~ 0xFFcrc32uint32_t整页校验

块内偏移布局

偏移大小内容
0x00032B配置头 kbd_config_header_t
0x020 ~ 0x0FF224B填充/保留
0x10064B系统配置 kbd_system_config_t
0x140 ~ 0x1FF192B填充/保留
0x200164B按键映射 kbd_keymap_t
0x2A4 ~ 0x2FF92B填充/保留
0x30032BFN 键配置 kbd_fnkey_config_t
0x320 ~ 0x33F32B填充/保留
0x34032BRGB 配置 kbd_rgb_config_t
0x360 ~ 0xFFF3232B填充/保留

配置头 kbd_config_header_t (32 字节, 偏移 0x000 / 槽位内)

字节偏移字段类型说明
0-30x00magicuint32_t魔数 0x4D454F57 ("MEOW")
4-50x04versionuint16_t配置版本 0x0102
6-70x06flagsuint16_t标志位
8-110x08crc32uint32_t各配置块 CRC32 异或校验
12-150x0Csave_countuint32_t保存计数
16-310x10reserveduint8_t[16]保留

系统配置 kbd_system_config_t (64 字节, 偏移 0x100)

字节偏移字段类型说明
00x100default_modeuint8_t默认模式 (0=USB, 1=BLE, 2=2.4G预留)
10x101auto_sleep_minuint8_t自动休眠时间(分钟,0=禁用)
20x102debounce_msuint8_t按键消抖时间(毫秒)
30x103log_enableduint8_tHID 日志开关 (v1.2+)
4-630x104reserveduint8_t[60]保留

按键映射 kbd_keymap_t (164 字节, 偏移 0x200)

字节偏移字段类型说明
00x200num_layersuint8_t层数 (1-5)
10x201current_layeruint8_t当前激活层(基础值,启动后可被 runtime 热数据覆盖)
20x202default_layeruint8_t默认层
30x203reserveduint8_t保留
4-1630x204layers[5]kbd_layer_t[5]5 层 × 32 字节

单层 kbd_layer_t (32 字节)

每层 8 个按键 × 4 字节 (kbd_action_t)

字节字段说明
0type动作类型
1modifier修饰键/操作类型
2param1键码/参数1
3param2参数2

FN 键配置 kbd_fnkey_config_t (32 字节, 偏移 0x300)

4 个 FN 键 × 8 字节 (kbd_fnkey_entry_t)

字节偏移字段说明
00x300fn[0].click_actionFN1 短按动作
10x301fn[0].click_paramFN1 短按参数
20x302fn[0].long_actionFN1 长按动作
30x303fn[0].long_paramFN1 长按参数
4-50x304fn[0].long_press_ms长按阈值 (little-endian)
6-70x306fn[0].reserved保留
8-150x308fn[1]FN2 配置
16-230x310fn[2]FN3 配置
24-310x318fn[3]FN4 配置

RGB 配置 kbd_rgb_config_t (32 字节, 偏移 0x340)

字节偏移字段类型说明
00x340enableduint8_tRGB 总开关
10x341modeuint8_t灯效模式 (0=关,1=静态,2=呼吸,3=闪烁,4=彩虹,5=状态指示)
20x342brightnessuint8_tRGB/按键灯亮度 (0-255)
30x343speeduint8_t动画速度 (0-255)
40x344color_ruint8_t静态颜色 R
50x345color_guint8_t静态颜色 G
60x346color_buint8_t静态颜色 B
70x347indicator_enableduint8_t状态指示开关
80x348indicator_brightnessuint8_t指示灯亮度 (0-255)
9-310x349reserveduint8_t[23]保留

宏数据区 (0x1000 ~ 0x4FFF)

宏区前移,与 BLE SNV (0x7E00~0x7EFF) 完全分离,避免冲突。

槽位地址范围大小说明
00x1000 ~ 0x17FF2KB宏槽位 0
10x1800 ~ 0x1FFF2KB宏槽位 1
20x2000 ~ 0x27FF2KB宏槽位 2
30x2800 ~ 0x2FFF2KB宏槽位 3
40x3000 ~ 0x37FF2KB宏槽位 4
50x3800 ~ 0x3FFF2KB宏槽位 5
60x4000 ~ 0x47FF2KB宏槽位 6
70x4800 ~ 0x4FFF2KB宏槽位 7

宏槽位布局 (每槽 2KB)

偏移大小内容
01valid (0xAA=有效)
11id (0-7)
2-32action_count
4-52data_size
6-72reserved
8-2316name (UTF-8)
24~-宏动作数据

BLE SNV 区 (0x7E00 ~ 0x7EFF)

蓝牙协议栈用于存储配对/绑定信息的非易失存储,由 WCH BLE 库管理。

参数默认值说明
BLE_SNV_ADDR0x77000 - FLASH_ROM_MAX_SIZE实际约为 0x7E00(Data Flash 末段)
BLE_SNV_BLOCK256块大小
BLE_SNV_NUM1块数量

读写通过 Lib_Read_Flash / Lib_Write_Flash 回调,内部使用 EEPROM_READ / EEPROM_WRITE。CH592A 需按 4KB 块擦除,会读-改-写整块。


保存流程

  1. 通过 HID 命令修改 RAM 中的配置(如 RGB_SET)
  2. 发送 CFG_SAVE (0x10) 触发保存
  3. 固件将配置写入下一个 1KB 配置槽(按 256B 页差异擦写)
  4. 同步写入 runtime 热数据页(保存当前层)

高频层切换(不走 CFG_SAVE)

  • current_layer 变化时,仅写 0x0C00~0x0FFF 的 runtime 热数据页(256B
  • 不重写整份配置

注意事项

配置区整体

小配置小擦写

配置区使用 3×1KB 槽位轮转 + 256B 页差异写。每次 CFG_SAVE 不再整块擦写 4KB,只更新发生变化的配置页。

魔数与版本校验

加载时扫描配置槽,校验 magic、主版本号与 crc32,选择 save_count 最大的有效槽位。无有效槽位时回退默认配置。

CRC 校验

crc32 由系统、键映射、FN、RGB 四块的 CRC32 异或得出,写入时计算,加载时会校验

热数据页环

current_layer 单独存放在 runtime 热数据页环(4×256B),高频切层只写热数据页,减少配置区磨损。

按键映射

层数与键盘类型

num_layers 须与键盘类型一致:基础款 4、五键款 5、旋钮款 5。current_layerdefault_layer 必须小于 num_layers,否则可能出现越界访问。

按键槽位

每层固定 8 个按键槽位 (KBD_MAX_KEYS),实际有效按键数由 deviceInfo.actualKeyCount 决定。超出部分的槽位可保留为 NONE。

FN 键配置

实际使用

基础款与五键款仅使用 fn[0]fn[1]fn[2]fn[3] 为保留字段。long_press_ms 为 16 位小端序。

RGB 配置

双亮度独立保存

brightness (0x342) 与 indicator_brightness (0x348) 为两个独立参数,需通过 RGB_SET 传入 9 字节(含 data[8])并执行 CFG_SAVE 才能完整保存。网页端请点击「保存 RGB」。

旧配置迁移

加载时若 indicator_brightness == 0,会自动设为默认值 51(20% 亮度),用于兼容未包含该字段的旧固件配置。

宏数据区

擦除粒度

宏槽位按 4KB 块边界对齐,写入/删除单个宏时会擦除整块。槽位 0~1 共用块 0x1000~0x1FFF,槽位 2~3 共用 0x2000~0x2FFF,以此类推。修改一个槽位可能影响同块内另一槽位。

宏写入流程

宏写入必须严格按顺序:MACRO_SET seq=0(BeginWrite)→ MACRO_SET seq=1~N(WriteChunk,可分多包)→ MACRO_SET seq=0 且完成(EndWrite 标记有效)。中途失败或未调用 EndWrite 时,该槽位将保持无效。

宏大小限制

单宏动作数据最大 KBD_MACRO_MAX_SIZE - 24 = 2024 字节,动作数量最多 KBD_MACRO_MAX_ACTIONS = 1000data_size 不含 24 字节头部。

有效标记

槽位首字节 valid == 0xAA 表示该宏有效。删除宏时将整槽填 0xFF,valid 变为非 0xAA。

保存与恢复

网页端分按钮保存

  • 保存配置:仅保存按键映射 (KEYMAP_SET + CFG_SAVE)
  • 保存 FN:仅保存 FN 键 (FNKEY_SET + CFG_SAVE)
  • 保存 RGB:仅保存 RGB (RGB_SET + CFG_SAVE)

修改 FN 或 RGB 后需点击对应按钮,否则重启后不会生效。

恢复出厂

CFG_RESET 会调用 KBD_Config_Reset:加载默认配置、清除全部 8 个宏槽位、再执行 CFG_SAVE。所有自定义配置将丢失。

DataFlash 与 BLE SNV

BLE 占用 DataFlash

蓝牙协议栈的 SNV(Simple Non-Volatile)用于存储配对/绑定信息,使用 DataFlash 末段 0x7E00~0x7EFF(256 字节),由 ble_config.h 配置。

升级与迁移

  • 新布局将 0x0C00~0x0FFF 作为 runtime 热数据区,不再作为第 4 个配置槽使用。
  • 启动时会优先扫描新配置槽;若无有效配置,会尝试读取旧版 0x0C00 配置并自动迁移。
  • 迁移成功后,后续保存将只使用新布局(3 槽配置区 + 1KB runtime 热数据区)。

推荐优化方案(规划)

以下为下一版可选方案,当前固件尚未完全实现。

核心思路

  • 小配置使用 256B 页环(分区日志页)
  • 宏数据保持 4KB 块擦写
  • 每个分区独立 seq + crc + commit,按分区恢复

推荐布局(示例)

地址范围大小用途
0x0000 ~ 0x03FF1KBbase 页环(系统/FN/RGB)
0x0400 ~ 0x07FF1KBkeymap 页环
0x0800 ~ 0x0BFF1KBmeta 页环(迁移/统计/版本)
0x0C00 ~ 0x0FFF1KBruntime 热数据页环(层号/模式)
0x1000 ~ 0x4FFF16KB宏区(4KB 块擦写)

页记录头(建议)

  • magic
  • version
  • typeBASE/KEYMAP/RUNTIME/META
  • state(空/写入中/有效)
  • seq
  • payload_len
  • crc32

写入流程(建议)

  1. 擦除目标 256B
  2. 写入 header(state=写入中) 和 payload
  3. 校验 crc32
  4. state 写为有效(只做 1 -> 0 位变化)

优点

  • current_layer 高频更新只写 runtime
  • 改 RGB 不会写 keymap
  • 改键位不影响 base/runtime
  • 单分区损坏不影响其他分区恢复