Compare commits

..

1 Commits

Author SHA1 Message Date
88ee4da089 docs: 添加Blinky键盘2.4G端详细设计文档
- 定义了键盘外设固件内实现2.4G端的设计方案
- 描述了基于专用local identity的dongle peer设计方案
- 详细说明了身份规划和模块职责分工
- 包含了行为模型、状态事件设计和UI设计
- 提供了分阶段实施建议和风险评估
2026-05-06 18:36:39 +08:00

View File

@@ -0,0 +1,476 @@
# Blinky 键盘 2.4G 端详细设计稿
## 1. 背景
当前 `C:\projects\blinky` 已经完成了外设侧多槽 BLE 基础能力:
- `Slot 1~3` 对应普通 BLE 主机
- `identity 4` 预留为 `Dongle Slot`
- `mode_policy_module` 已经区分:
- `MODE_SWITCH_BLE -> BLE_PROFILE_POLICY_GENERAL`
- `MODE_SWITCH_24G -> BLE_PROFILE_POLICY_DONGLE`
但目前 `identity 4` 还只是“预留位”,没有真正落成完整的 dongle peer 行为。
本设计稿的目标,是定义如何在**键盘外设固件内**实现“2.4G 端”,参考 `nrf_desktop` 的外围设备侧 dongle peer 设计。
这里的“2.4G 端”在第一阶段的实现语义不是 ESB 或私有无线协议,而是:
- 键盘继续作为 BLE Peripheral
- 通过专用 local identity 与自家 dongle 建立专用连接
- 在产品层把该模式呈现为“2.4G”
这和 `nrf_desktop``dongle peer` 设计方向一致。
## 2. 设计目标
本方案的目标如下:
- 在当前键盘固件内实现专用 `dongle peer`
- `MODE_SWITCH_24G` 时固定使用专用 `identity 4`
- `MODE_SWITCH_BLE` 时继续使用普通 BLE 槽位 `identity 1/2/3`
- `dongle peer` 与普通 BLE 槽位完全隔离
- `dongle peer` 有独立 bond 和独立状态显示
- Swift Pair 对普通 BLE 开启,对 `dongle peer` 默认关闭
- 后续为自家 dongle 识别准备一个最小 `dev_descr` 风格自定义 GATT 服务
本设计稿不包含“dongle central 固件”的实现,只定义键盘外设侧。
## 3. 参考基线
本设计主要参考本地 `nrf_desktop` 的外围设备侧设计:
- `c:\ncs\v3.2.3\nrf\applications\nrf_desktop\doc\ble_bond.rst`
- `c:\ncs\v3.2.3\nrf\applications\nrf_desktop\doc\dev_descr.rst`
- `c:\ncs\v3.2.3\nrf\applications\nrf_desktop\doc\qos.rst`
- `c:\ncs\v3.2.3\nrf\applications\nrf_desktop\src\modules\dev_descr.c`
- `c:\ncs\v3.2.3\nrf\applications\nrf_desktop\src\modules\qos.c`
参考结论:
- `dongle peer` 的核心不是新的无线协议,而是**专用 Bluetooth local identity**
- 外设与 dongle 的专用配对要和普通 BLE peer 隔离
- `dev_descr` 是未来 dongle 识别外设的关键入口
- `QoS` 是增强项,不是第一阶段前置条件
## 4. 当前工程现状
当前工程已经具备实现 `dongle peer` 的关键基础:
- `ble_bond_multi_module` 已支持固定 identity 多槽
- `identity 1/2/3` 已用于普通 BLE 槽位
- `identity 4` 已预留为 `Dongle Slot`
- `mode_policy_module` 已输出 `BLE_PROFILE_POLICY_GENERAL / DONGLE`
- Swift Pair 已默认开启,并且在 `identity 4` 上默认关闭
相关文件:
- `C:\projects\blinky\src\ble_bond_multi_module.c`
- `C:\projects\blinky\src\mode_policy_module.c`
- `C:\projects\blinky\inc\events\transport_policy_event.h`
- `C:\projects\blinky\src\swift_pair_module.c`
当前缺失点:
- `MODE_SWITCH_24G` 没有真正强制切到 `identity 4`
- `dongle peer` 没有独立 UI 状态
- 没有 `dev_descr` 风格自定义服务
- 没有独立的 dongle 管理接口
## 5. 总体设计
## 5.1 核心设计结论
采用 `nrf_desktop` 风格的“专用 dongle peer”设计
- 保持当前键盘为 BLE Peripheral
- 使用 `identity 4` 作为专用 dongle identity
-`MODE_SWITCH_24G` 作为选择 `dongle peer` 的产品模式
- 普通 BLE 槽位 `1/2/3``dongle peer` 独立管理
也就是说:
- `2.4G` 是产品语义
- 第一阶段实现仍然是 BLE Peripheral + 专用 identity
## 5.2 identity 规划
identity 规划继续固定如下:
| Identity | 角色 | 用途 |
| --- | --- | --- |
| `0` | 默认 identity | 不使用 |
| `1` | BLE Slot 1 | 普通 BLE |
| `2` | BLE Slot 2 | 普通 BLE |
| `3` | BLE Slot 3 | 普通 BLE |
| `4` | Dongle Slot | 专用 2.4G / dongle peer |
设计原则:
- `identity 4` 不参与普通槽位轮换
- `identity 4` 不参与普通 BLE 设置页
- `identity 4` 有独立 bond 和独立状态
## 6. 模块职责分工
## 6.1 `mode_policy_module`
职责保持不变:
- 根据拨杆位置输出 transport policy
当前定义:
- `MODE_SWITCH_BLE -> BLE_PROFILE_POLICY_GENERAL`
- `MODE_SWITCH_24G -> BLE_PROFILE_POLICY_DONGLE`
它不直接管理 bond只输出“当前应该走哪种 BLE profile”。
## 6.2 `ble_bond_multi_module`
这是本方案第一阶段的主修改模块。
需要扩展职责:
- 支持根据 `BLE_PROFILE_POLICY_DONGLE` 固定选择 `identity 4`
- 普通 BLE 与 `dongle peer` 分开管理
- 提供 `dongle peer` 独立状态输出
- 提供 `dongle peer` 独立擦除操作
仍然保留已有职责:
- 普通 BLE 三槽切换
- 普通 BLE 三槽擦除
- slot meta 持久化
## 6.3 `swift_pair_module`
职责保持:
- 普通 BLE 槽位启用 Swift Pair
- `dongle peer` 默认关闭 Swift Pair payload
这和 `nrf_desktop` 的思路一致。
## 6.4 新增 `dev_descr_module`
建议新增一个最小版 `dev_descr` 风格服务。
目标:
- 给未来的 dongle 提供外设识别信息
- 不依赖设备名做唯一识别
第一阶段最小字段:
- `caps`
- `hwid`
后续可扩展:
- `role`
- `product type`
- `firmware revision`
## 6.5 `qos_module`
第一阶段不做。
理由:
- `nrf_desktop` 已明确说明自家 dongle 不依赖外围设备 QoS
- 当前先做 `dongle peer` identity 和识别就足够
## 7. 行为模型
## 7.1 普通 BLE 模式
条件:
- `MODE_SWITCH_BLE`
- `BLE_PROFILE_POLICY_GENERAL`
行为:
- 当前 active slot 只能为 `1/2/3`
- UI 显示普通 BLE 三槽
- 允许普通 BLE 切槽和擦除
- Swift Pair 默认开启
## 7.2 2.4G / Dongle 模式
条件:
- `MODE_SWITCH_24G`
- `BLE_PROFILE_POLICY_DONGLE`
行为:
- 当前 active identity 固定为 `4`
- 当前 bond 只属于 `identity 4`
- 不允许普通 BLE 三槽逻辑影响 `identity 4`
- Swift Pair 默认关闭
- UI 应显示:
- `Dongle Searching`
- `Dongle Paired`
- `Dongle Connected`
- `Dongle Empty`
## 7.3 模式切换语义
### BLE -> 24G
1. `mode_policy_module` 发布 `BLE_PROFILE_POLICY_DONGLE`
2. `ble_bond_multi_module` 切 active identity 到 `4`
3. 提交 `PEER_OPERATION_SELECTED`
4. CAF `ble_adv` 切到 `identity 4`
5. 当前连接断开
6. 使用 `identity 4` 广播
7. dongle 重连
### 24G -> BLE
1. `mode_policy_module` 发布 `BLE_PROFILE_POLICY_GENERAL`
2. `ble_bond_multi_module` 恢复普通 BLE 当前槽位 `1/2/3`
3. 提交 `PEER_OPERATION_SELECTED`
4. CAF `ble_adv` 切回对应 identity
5. 当前连接断开
6. 使用普通 BLE 槽位广播
## 8. 状态与事件设计
## 8.1 当前已有事件
可继续复用:
- `transport_policy_event`
- `ble_peer_event`
- `ble_peer_operation_event`
- `ble_bond_multi_event`
## 8.2 建议扩展 `ble_bond_multi_event`
建议增加字段或语义:
- `active_profile`
- `GENERAL`
- `DONGLE`
- `dongle_slot_meta`
- `occupied`
- `last_peer_addr`
- `display_name`
- `current_identity`
如果不想改现有事件结构,也可以新增一个独立事件:
- `ble_dongle_state_event`
推荐字段:
- `state`
- `EMPTY`
- `SEARCHING`
- `PAIRED`
- `CONNECTED`
- `identity_id`
- `display_name`
## 8.3 UI 状态来源
主界面与设置页可以通过以下信息判断:
- 当前 `mode`
- 当前 `active_identity_id`
- `identity 4` 是否有 bond
- 当前是否有连接且该连接属于 `identity 4`
## 9. `dev_descr` 设计
## 9.1 目标
最小化模仿 `nrf_desktop dev_descr`
- 为 dongle 提供一个稳定可读的识别服务
- 避免仅靠设备名判断
## 9.2 服务内容
建议服务包含两个 characteristic
### Characteristic 1: `caps`
建议字节布局:
- bit0: `supports_llpm`
- bit1: `supports_dongle_peer`
- bit2: `is_keyboard`
第一阶段只要能读出:
- 这个设备支持 dongle peer
- 这是 keyboard 类型
### Characteristic 2: `hwid`
固定长度硬件 ID
- 用于以后让 dongle 唯一识别这把键盘
- 也可用于配置通道映射
## 9.3 权限建议
建议与 `nrf_desktop` 保持一致:
- `BT_GATT_PERM_READ_ENCRYPT`
原因:
- 避免未加密链路上暴露识别信息
## 9.4 依赖
需要:
- `CONFIG_HWINFO`
- 固件内已有或新增 `hwid_get()` 辅助逻辑
## 10. Settings 设计
继续沿用现有 namespace
- `ble_multi/current_slot`
- `ble_multi/meta/1`
- `ble_multi/meta/2`
- `ble_multi/meta/3`
- `ble_multi/meta/4`
其中 `meta/4` 现在正式用于 dongle peer。
建议 `meta/4` 字段仍保持:
- `occupied`
- `last_peer_addr`
- `display_name`
显示策略:
- 有真实名字则显示名字
- 否则显示 MAC 地址
- 无 bond 显示 `Empty`
## 11. UI 设计
## 11.1 主界面
当前主界面可新增或扩展显示:
- 当前模式 `USB / BLE / 24G`
- 如果 `24G` 模式:
- 右上角额外状态位显示:
- searching
- connected
现有 BLE LINK 状态位可以复用,但语义建议细化:
- BLE 模式下:表示普通 BLE 当前槽状态
- 24G 模式下:表示 dongle peer 状态
## 11.2 设置页
建议新增二级入口:
- `Bluetooth`
- Slot 1
- Slot 2
- Slot 3
- Erase Current
- `Dongle`
- Status
- Erase Dongle Bond
第一阶段如果不想扩菜单,至少要做到:
- 主界面显示 dongle peer 状态
- 设置页不把 `identity 4` 混入 Slot 1~3
## 12. 分阶段实施建议
## 阶段 1Dongle Slot 真正接线
内容:
- `ble_bond_multi_module` 支持 `BLE_PROFILE_POLICY_DONGLE`
- `MODE_SWITCH_24G` 时固定切到 `identity 4`
- `identity 4` 独立 bond 和独立状态
- Swift Pair 在 `identity 4` 默认关闭
交付标准:
- 24G 模式和 BLE 模式切换时 identity 正确切换
- `identity 4``1/2/3` 完全隔离
## 阶段 2UI / 状态管理
内容:
- 增加 dongle 状态显示
- 增加独立擦除 dongle bond 入口
- 不把 dongle 混入普通 BLE 三槽 UI
交付标准:
- 用户可以明确区分:
- 普通 BLE 槽位
- 2.4G / dongle peer
## 阶段 3最小 `dev_descr`
内容:
- 实现最小自定义 GATT service
- 提供 `caps + hwid`
交付标准:
- 未来 dongle 可稳定识别这把键盘
## 阶段 4后续增强非当前范围
可选项:
- QoS
- 更强的 dongle 配对约束
- 生产预绑定
- 更明确的 dongle selector/恢复流程
## 13. 风险与边界
## 13.1 “2.4G” 实际仍然是 BLE
第一阶段产品语义是 2.4G,链路实现仍是 BLE。
这没有问题,但必须在代码和文档中明确,避免后续和真正私有 2.4G 链路混淆。
## 13.2 `dev_descr` 与未来 dongle 要对齐
如果未来 dongle 端也参考 `nrf_desktop central`,那这里的 UUID 和字段应该尽量稳定,不要后面再频繁改。
## 13.3 `identity 4` 与普通 UI 必须隔离
一旦 `identity 4` 被误混入普通三槽,就会造成用户理解混乱:
- 不知道哪个是普通蓝牙
- 哪个是 2.4G
这是 UI 设计上最需要避免的问题。
## 14. 结论
本方案建议把当前键盘的“2.4G 端”实现为:
- `BLE Peripheral + 专用 Dongle identity`
- `MODE_SWITCH_24G` 时固定走 `identity 4`
- 与普通 BLE 三槽完全隔离
- 第一阶段先打通 identity / bond / UI 状态
- 第二阶段补最小 `dev_descr`
- `QoS` 暂缓
这条路径与 `nrf_desktop` 外设侧的 dongle peer 设计一致,也与当前工程已有的 `transport_policy_event` 语义完全匹配。