Files
blinky/docs/caf_stock_modules_guide.md
skiinder 2c421b23b6 feat(mini_keyboard): 添加CAF按钮模块支持并完善项目配置
- 添加external目录到.gitignore排除列表
- 在CMakeLists.txt中添加inc目录包含路径
- 更新DTS文件启用gpio0状态
- 创建CAF按钮定义头文件buttons_def.h,配置4x6矩阵键盘引脚
- 在prj.conf中启用CAF按钮模块及相关配置
- 添加详细的CAF官方模块清单文档caf_stock_modules_guide.md
- 添加nRF Desktop架构说明文档nrf_desktop_architecture.md,为后续
  键盘功能开发提供架构参考
2026-04-07 14:26:59 +08:00

783 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CAF 官方现成模块清单与使用方法
本文基于本地 `NCS v3.2.3` 的官方源码与文档整理,范围以以下目录为准:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf`
- `C:\ncs\v3.2.3\nrf\subsys\caf\modules`
目标是回答两个问题:
1. CAF 官方现成提供了哪些模块可以直接用。
2. 这些模块最小要怎么启用、怎么接入。
## 1. CAF 是什么
CAF, Common Application Framework是 Nordic 基于 `app_event_manager` 封装的一组现成模块和事件。
它的基本模式是:
- 你启用某个 CAF 模块
- 模块监听 CAF 事件或应用自定义事件
- 模块自己和别的模块通过事件解耦通信
因此 CAF 更像一套“事件驱动应用积木”,而不是单个库函数。
## 2. 使用 CAF 的最小前提
在使用任何 CAF 模块前,建议先完成这 3 件事。
### 2.1 打开 CAF
`prj.conf` 中至少启用:
```conf
CONFIG_CAF=y
```
### 2.2 启用并初始化 Application Event Manager
你的应用需要正常使用 `app_event_manager`
### 2.3 在 `main()` 中发出第一条 `module_state_event`
CAF 模块在收到 `main` 模块的 `MODULE_STATE_READY` 后才会继续初始化。
典型写法:
```c
#include <app_event_manager.h>
#define MODULE main
#include <caf/events/module_state_event.h>
int main(void)
{
if (app_event_manager_init()) {
return 0;
}
module_set_state(MODULE_STATE_READY);
return 0;
}
```
可以参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\caf_overview.rst`
- `C:\ncs\v3.2.3\nrf\applications\nrf_desktop\src\main.c`
## 3. CAF 官方现成模块列表
`C:\ncs\v3.2.3\nrf\subsys\caf\modules\Kconfig`NCS 3.2.3 中 CAF 官方模块包括:
1. `CAF_BLE_ADV`
2. `CAF_BLE_BOND`
3. `CAF_BLE_SMP`
4. `CAF_BLE_STATE`
5. `CAF_BLE_STATE_PM`
6. `CAF_BUTTONS`
7. `CAF_BUTTONS_PM_KEEP_ALIVE`
8. `CAF_CLICK_DETECTOR`
9. `CAF_FACTORY_RESET_REQUEST`
10. `CAF_LEDS`
11. `CAF_NET_STATE`
12. `CAF_POWER_MANAGER`
13. `CAF_SENSOR_DATA_AGGREGATOR`
14. `CAF_SENSOR_MANAGER`
15. `CAF_SETTINGS_LOADER`
16. `CAF_SHELL`
## 4. 模块总览表
| 模块 | 主要作用 | 典型输入 | 典型输出 | 最小启用点 |
| --- | --- | --- | --- | --- |
| `CAF_BUTTONS` | 扫描按键/矩阵键盘 GPIO | GPIO 变化 | `button_event` | `CONFIG_CAF_BUTTONS=y` |
| `CAF_BUTTONS_PM_KEEP_ALIVE` | 按键活动保持系统唤醒 | `button_event` | `keep_alive_event` | `CONFIG_CAF_BUTTONS_PM_KEEP_ALIVE=y` |
| `CAF_CLICK_DETECTOR` | 将按键动作识别为短按/长按/双击 | `button_event` | `click_event` | `CONFIG_CAF_CLICK_DETECTOR=y` |
| `CAF_LEDS` | 根据 LED effect 控制 LED | `led_event` | LED 状态变化 | `CONFIG_CAF_LEDS=y` |
| `CAF_POWER_MANAGER` | 管理挂起/唤醒/关机 | keep-alive、restriction、error | `power_down_event``wake_up_event``power_off_event` | `CONFIG_CAF_POWER_MANAGER=y` |
| `CAF_BLE_STATE` | 打开 BLE、管理连接回调 | 蓝牙栈回调 | `ble_peer_event``ble_peer_conn_params_event` | `CONFIG_CAF_BLE_STATE=y` |
| `CAF_BLE_STATE_PM` | BLE 连接存在时限制省电级别 | `ble_peer_event` | power restriction | `CONFIG_CAF_BLE_STATE_PM=y` |
| `CAF_BLE_ADV` | Peripheral 侧广播控制 | BLE 状态、advertising provider 数据 | 广播行为、`force_power_down_event` | `CONFIG_CAF_BLE_ADV=y` |
| `CAF_BLE_BOND` | 默认 BLE bond 管理 | `click_event`、settings | bond erase 行为 | `CONFIG_CAF_BLE_BOND=y` |
| `CAF_BLE_SMP` | BLE 上 MCUmgr DFU | MCUmgr 传输 | `ble_smp_transfer_event` | `CONFIG_CAF_BLE_SMP=y` |
| `CAF_SETTINGS_LOADER` | 在合适时机调用 `settings_load()` | `module_state_event` | settings 已装载 | `CONFIG_CAF_SETTINGS_LOADER=y` |
| `CAF_NET_STATE` | 上报网络连接状态 | LTE / OpenThread backend | `net_state_event` | `CONFIG_CAF_NET_STATE=y` |
| `CAF_SENSOR_MANAGER` | 周期采样传感器 | sensor driver | `sensor_event``sensor_state_event` | `CONFIG_CAF_SENSOR_MANAGER=y` |
| `CAF_SENSOR_DATA_AGGREGATOR` | 聚合 sensor_event 数据块 | `sensor_event` | `sensor_data_aggregator_event` | `CONFIG_CAF_SENSOR_DATA_AGGREGATOR=y` |
| `CAF_FACTORY_RESET_REQUEST` | 上电窗口内按键触发恢复出厂请求 | `button_event` | `factory_reset_event` | `CONFIG_CAF_FACTORY_RESET_REQUEST=y` |
| `CAF_SHELL` | 通过 shell 手动发 CAF 事件 | shell 命令 | `button_event` 等 | `CONFIG_CAF_SHELL=y` |
## 5. 各模块使用方法
下面按“用途、最小接入方法、何时使用”来总结。
### 5.1 `CAF_BUTTONS`
**用途**
- 读取独立按键或矩阵键盘
- 统一生成 `button_event`
**最小接入**
1.`prj.conf` 打开:
```conf
CONFIG_CAF_BUTTONS=y
CONFIG_GPIO=y
```
2. 新建按钮定义头文件,例如 `buttons_def.h`,定义:
- `row[]`
- `col[]`
3.`CONFIG_CAF_BUTTONS_DEF_PATH` 指向这个配置文件。
例如:
```conf
CONFIG_CAF_BUTTONS_DEF_PATH="buttons_def.h"
```
**何时使用**
- 你要做按键输入,基本都会先用它
- 对键盘项目最常用
**补充**
- 支持矩阵键盘和直接 GPIO 按键
- 支持去抖、扫描周期、按键极性配置
- 可选支持 PM 事件和唤醒
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\buttons.rst`
### 5.2 `CAF_BUTTONS_PM_KEEP_ALIVE`
**用途**
- 按键按下时自动发 `keep_alive_event`
- 常配合 `CAF_POWER_MANAGER`
**最小接入**
```conf
CONFIG_CAF_BUTTONS=y
CONFIG_CAF_POWER_MANAGER=y
CONFIG_CAF_BUTTONS_PM_KEEP_ALIVE=y
```
**何时使用**
- 设备需要超时休眠
- 但用户按键活动应重置休眠计时
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\buttons_pm_keep_alive.rst`
### 5.3 `CAF_CLICK_DETECTOR`
**用途**
-`button_event` 识别短按、长按、双击
- 生成 `click_event`
**最小接入**
1. 打开:
```conf
CONFIG_CAF_CLICK_DETECTOR=y
```
2. 新建 click 配置头文件,定义 `click_detector_config[]`
至少要给出:
- `key_id`
- `consume_button_event`
3.`CONFIG_CAF_CLICK_DETECTOR_DEF_PATH` 指向该文件。
**何时使用**
- 一个键要复用多个动作
- 如长按进入配对、双击切层、长按恢复出厂
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\click_detector.rst`
### 5.4 `CAF_LEDS`
**用途**
- 接收 `led_event`
- 用 PWM 或 GPIO 驱动 LED
- 支持 LED effect
**最小接入**
PWM 方案示例:
```conf
CONFIG_CAF_LEDS=y
CONFIG_CAF_LEDS_PWM=y
CONFIG_LED=y
CONFIG_LED_PWM=y
CONFIG_PWM=y
```
GPIO 方案示例:
```conf
CONFIG_CAF_LEDS=y
CONFIG_CAF_LEDS_GPIO=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_GPIO=y
```
同时还需要:
- 在 DTS 或 overlay 中定义 LED 节点
- 在应用里由别的模块发 `led_event`
**何时使用**
- 做状态灯、层指示、配对指示、电量指示
**补充**
- 想做平滑呼吸灯,优先用 PWM
- GPIO 版只适合开关式 LED
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\leds.rst`
- `C:\ncs\v3.2.3\nrf\samples\caf`
### 5.5 `CAF_POWER_MANAGER`
**用途**
- 管理系统从 idle 到 suspended/off 的切换
- 对外广播 `power_down_event``wake_up_event``power_off_event`
**最小接入**
```conf
CONFIG_CAF_POWER_MANAGER=y
```
常用附加项:
```conf
CONFIG_CAF_POWER_MANAGER_TIMEOUT=120
CONFIG_CAF_POWER_MANAGER_ERROR_TIMEOUT=30
```
**何时使用**
- 电池设备
- 需要空闲休眠/关机
- 多模块都需要统一响应省电状态
**补充**
- 常和 `CAF_BUTTONS_PM_KEEP_ALIVE` 配合
- 其他模块可用 `power_manager_restrict_event` 限制最大省电级别
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\power_manager.rst`
### 5.6 `CAF_BLE_STATE`
**用途**
- 启动 BLE
- 处理连接和参数回调
- 向应用广播 BLE 连接状态事件
**最小接入**
```conf
CONFIG_BT=y
CONFIG_BT_SMP=y
CONFIG_CAF_BLE_STATE=y
```
常见附加项:
```conf
CONFIG_CAF_BLE_STATE_SECURITY_REQ=y
CONFIG_CAF_BLE_USE_LLPM=y
```
**何时使用**
- 只要 CAF 体系下要做 BLE几乎都先启用它
- 它本身不负责广播或扫描
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_state.rst`
### 5.7 `CAF_BLE_STATE_PM`
**用途**
- 当 BLE 连接存在时,阻止系统进入过深省电级别
**最小接入**
```conf
CONFIG_CAF_BLE_STATE=y
CONFIG_CAF_POWER_MANAGER=y
CONFIG_CAF_BLE_STATE_PM=y
```
**何时使用**
- BLE 外设连接后不能立即休眠
- 要让 BLE 连接期间系统维持可通信
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_state_pm.rst`
### 5.8 `CAF_BLE_ADV`
**用途**
- 作为 BLE Peripheral 控制广播
**最小接入**
1. 启用 `CAF_BLE_STATE`
2. 启用:
```conf
CONFIG_CAF_BLE_ADV=y
```
3. 配置 advertising data provider 和 scan response provider
**何时使用**
- 你的设备要作为 BLE Peripheral 被手机/PC/主机发现
**补充**
- 支持快慢广播
- 支持 directed advertising
- 支持 suspend/resume
- 支持 grace period
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_adv.rst`
### 5.9 `CAF_BLE_BOND`
**用途**
- 提供默认 BLE bond 管理
- 可通过特定点击动作执行 bond erase
**最小接入**
```conf
CONFIG_CAF_BLE_BOND=y
CONFIG_BT_BONDABLE=y
CONFIG_BT_SETTINGS=y
CONFIG_CAF_SETTINGS_LOADER=y
CONFIG_CAF_BLE_COMMON_EVENTS=y
```
如果要支持按键清除 bond还要配置
```conf
CONFIG_CAF_BLE_BOND_PEER_ERASE_CLICK=y
CONFIG_CAF_BLE_BOND_PEER_ERASE_CLICK_KEY_ID=0x0000
```
并选择触发类型之一:
- `CONFIG_CAF_BLE_BOND_PEER_ERASE_CLICK_SHORT`
- `CONFIG_CAF_BLE_BOND_PEER_ERASE_CLICK_LONG`
- `CONFIG_CAF_BLE_BOND_PEER_ERASE_CLICK_DOUBLE`
**何时使用**
- 简单 BLE 应用需要默认配对/绑定位管理
**补充**
- 只适合简单应用
- 更复杂的多 identity / 多 peer 管理,通常要自己实现
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_bond.rst`
### 5.10 `CAF_BLE_SMP`
**用途**
- 通过 BLE 做 MCUmgr DFU
**最小接入**
```conf
CONFIG_CAF_BLE_STATE=y
CONFIG_CAF_BLE_SMP=y
CONFIG_MCUMGR_GRP_IMG=y
CONFIG_MCUMGR_MGMT_NOTIFICATION_HOOKS=y
CONFIG_MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK=y
CONFIG_MCUMGR_TRANSPORT_BT=y
CONFIG_BOOTLOADER_MCUBOOT=y
```
**何时使用**
- 需要 BLE OTA/DFU
**补充**
- 依赖 MCUboot
- 构建后会在 build 目录生成 `dfu_application.zip`
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_smp.rst`
### 5.11 `CAF_SETTINGS_LOADER`
**用途**
- 在合适的初始化时机调用 `settings_load()`
**最小接入**
```conf
CONFIG_CAF_SETTINGS_LOADER=y
CONFIG_SETTINGS=y
```
还需要:
- 新建配置头文件
- 实现 `get_req_modules(struct module_flags *mf)`
这个函数用于告诉 settings loader
- 哪些模块 ready 以后再加载 settings
**何时使用**
- 你的应用用了 settings/NVS/BT settings
- 比如 BLE bond、用户配置、持久化参数
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\settings_loader.rst`
### 5.12 `CAF_NET_STATE`
**用途**
- 上报网络连接状态
- 提供 LTE / OpenThread backend
**最小接入**
```conf
CONFIG_CAF_NET_STATE=y
```
具体 backend 由链路层决定,例如:
- `CONFIG_CAF_NET_STATE_LTE`
- `CONFIG_CAF_NET_STATE_OT`
**何时使用**
- 不是键盘/鼠标常用模块
- 更适合蜂窝或 Thread 设备
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\net_state.rst`
### 5.13 `CAF_SENSOR_MANAGER`
**用途**
- 周期采样传感器
- 统一生成 `sensor_event``sensor_state_event`
**最小接入**
```conf
CONFIG_CAF_SENSOR_MANAGER=y
CONFIG_SENSOR=y
```
还需要:
1. 在 DTS/overlay 中启用传感器
2. 打开对应传感器驱动 Kconfig
3. 新建 `sm_sensor_config[]` 配置文件
4.`CONFIG_CAF_SENSOR_MANAGER_DEF_PATH` 指向该文件
配置项通常至少包括:
- `dev_name`
- `event_descr`
- `chans`
- `chan_cnt`
- `sampling_period_ms`
- `active_events_limit`
**何时使用**
- 有 IMU、加速度计、光传感器、环境传感器等
**补充**
- 有独立采样线程
- 支持 trigger
- 支持 PM
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\sensor_manager.rst`
- `C:\ncs\v3.2.3\nrf\samples\caf_sensor_manager`
### 5.14 `CAF_SENSOR_DATA_AGGREGATOR`
**用途**
- 将多个 `sensor_event` 聚合成更大的数据包
- 多核 SoC 下可降低核间唤醒频率
**最小接入**
```conf
CONFIG_CAF_SENSOR_DATA_AGGREGATOR=y
```
如果另一核心要接收聚合事件,还可启用:
```conf
CONFIG_CAF_SENSOR_DATA_AGGREGATOR_EVENTS=y
```
还需要:
- 在 DTS/overlay 里添加 `compatible = "caf,aggregator"` 的节点
关键属性:
- `sensor_descr`
- `buf_data_length`
- `sample_size`
- `buf_count`
**何时使用**
- 传感器数据量较大
- 需要批处理
- 或者多核 SoC 上做功耗优化
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\sensor_data_aggregator.rst`
### 5.15 `CAF_FACTORY_RESET_REQUEST`
**用途**
- 在上电初始化窗口中检测某个按键是否被按住
- 若满足条件,发出 `factory_reset_event`
**最小接入**
```conf
CONFIG_CAF_FACTORY_RESET_REQUEST=y
CONFIG_CAF_FACTORY_RESET_REQUEST_BUTTON=0x0000
CONFIG_CAF_FACTORY_RESET_REQUEST_DELAY=50
```
它依赖:
- `CAF_BUTTONS`
- `button_event`
**何时使用**
- 开机长按某键请求恢复出厂
- 需要给上层模块一个统一 factory-reset 事件入口
**补充**
- 这个模块在 `NCS v3.2.3` 源码中存在
- 但没有找到与其他模块同等级的独立官方 `.rst` 页面
- 当前说明主要依据:
- `C:\ncs\v3.2.3\nrf\subsys\caf\modules\Kconfig.factory_reset_request`
- `C:\ncs\v3.2.3\nrf\subsys\caf\modules\factory_reset_request.c`
### 5.16 `CAF_SHELL`
**用途**
- 通过 Zephyr Shell 手工触发 CAF 事件
- 便于调试
**最小接入**
```conf
CONFIG_CAF_SHELL=y
CONFIG_SHELL=y
CONFIG_CAF=y
```
常见命令:
```text
caf_events button_event [button_id] [pressed]
```
例如:
```text
caf_events button_event 1 y
caf_events button_event 1 n
```
**何时使用**
- 没有真实按键硬件时做联调
- 验证 button/click/LED/状态机逻辑
参考:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\caf_shell.rst`
## 6. 对键盘项目最常用的 CAF 组合
如果你的项目是 `C:\projects\blinky` 这种自定义键盘方向,最常见的组合通常是:
### 6.1 纯输入层
- `CAF_BUTTONS`
- `CAF_CLICK_DETECTOR`
适合:
- 扫描键盘按键
- 做短按/长按/双击功能键
### 6.2 带状态灯
- `CAF_BUTTONS`
- `CAF_CLICK_DETECTOR`
- `CAF_LEDS`
适合:
- Caps Lock 指示
- 蓝牙通道指示
- 层状态指示
### 6.3 电池设备
- `CAF_BUTTONS`
- `CAF_POWER_MANAGER`
- `CAF_BUTTONS_PM_KEEP_ALIVE`
- `CAF_LEDS`
适合:
- 一段时间无操作后休眠
- 按键恢复活跃状态
### 6.4 BLE 键盘
- `CAF_BLE_STATE`
- `CAF_BLE_ADV`
- `CAF_BLE_BOND`
- `CAF_SETTINGS_LOADER`
按需叠加:
- `CAF_BLE_STATE_PM`
- `CAF_BLE_SMP`
适合:
- 支持广播、连接、加密、绑定
- 支持设置装载
- 需要时支持 OTA
## 7. 推荐的接入顺序
如果你要在 `blinky` 里逐步引入 CAF建议顺序如下
1. 先接 `CAF_BUTTONS`
2. 再接 `CAF_LEDS`
3. 然后根据需要加 `CAF_CLICK_DETECTOR`
4. 如果是电池设备,再接 `CAF_POWER_MANAGER`
5. 如果要做 BLE再接 `CAF_BLE_STATE``CAF_BLE_ADV``CAF_BLE_BOND`
6. 如果要做 OTA再接 `CAF_BLE_SMP`
这样改动面最小,也最容易定位问题。
## 8. 官方参考路径
建议优先阅读这些本地官方文件:
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\caf_overview.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\buttons.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\click_detector.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\leds.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\power_manager.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_state.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_state_pm.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_adv.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_bond.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_smp.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\settings_loader.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\net_state.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\sensor_manager.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\sensor_data_aggregator.rst`
- `C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\caf_shell.rst`
同时可参考源码:
- `C:\ncs\v3.2.3\nrf\subsys\caf\modules`
- `C:\ncs\v3.2.3\nrf\samples\caf`
- `C:\ncs\v3.2.3\nrf\samples\caf_sensor_manager`
## 9. 一句话结论
如果只看键盘/鼠标类项目CAF 里最值得优先使用的官方模块通常是:
- `CAF_BUTTONS`
- `CAF_CLICK_DETECTOR`
- `CAF_LEDS`
- `CAF_POWER_MANAGER`
- `CAF_BLE_STATE`
- `CAF_BLE_ADV`
- `CAF_BLE_BOND`
- `CAF_SETTINGS_LOADER`
它们已经覆盖了一个 BLE/USB 输入设备项目里最常见的基础设施。