# 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 #define MODULE main #include 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 输入设备项目里最常见的基础设施。