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

11 KiB
Raw Blame History

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_desktopdongle 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/3dongle 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 41/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 语义完全匹配。