- 添加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,为后续 键盘功能开发提供架构参考
16 KiB
CAF 官方现成模块清单与使用方法
本文基于本地 NCS v3.2.3 的官方源码与文档整理,范围以以下目录为准:
C:\ncs\v3.2.3\nrf\doc\nrf\libraries\cafC:\ncs\v3.2.3\nrf\subsys\caf\modules
目标是回答两个问题:
- CAF 官方现成提供了哪些模块可以直接用。
- 这些模块最小要怎么启用、怎么接入。
1. CAF 是什么
CAF, Common Application Framework,是 Nordic 基于 app_event_manager 封装的一组现成模块和事件。
它的基本模式是:
- 你启用某个 CAF 模块
- 模块监听 CAF 事件或应用自定义事件
- 模块自己和别的模块通过事件解耦通信
因此 CAF 更像一套“事件驱动应用积木”,而不是单个库函数。
2. 使用 CAF 的最小前提
在使用任何 CAF 模块前,建议先完成这 3 件事。
2.1 打开 CAF
在 prj.conf 中至少启用:
CONFIG_CAF=y
2.2 启用并初始化 Application Event Manager
你的应用需要正常使用 app_event_manager。
2.3 在 main() 中发出第一条 module_state_event
CAF 模块在收到 main 模块的 MODULE_STATE_READY 后才会继续初始化。
典型写法:
#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.rstC:\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 官方模块包括:
CAF_BLE_ADVCAF_BLE_BONDCAF_BLE_SMPCAF_BLE_STATECAF_BLE_STATE_PMCAF_BUTTONSCAF_BUTTONS_PM_KEEP_ALIVECAF_CLICK_DETECTORCAF_FACTORY_RESET_REQUESTCAF_LEDSCAF_NET_STATECAF_POWER_MANAGERCAF_SENSOR_DATA_AGGREGATORCAF_SENSOR_MANAGERCAF_SETTINGS_LOADERCAF_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
最小接入
- 在
prj.conf打开:
CONFIG_CAF_BUTTONS=y
CONFIG_GPIO=y
- 新建按钮定义头文件,例如
buttons_def.h,定义:
row[]col[]
- 用
CONFIG_CAF_BUTTONS_DEF_PATH指向这个配置文件。
例如:
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
最小接入
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
最小接入
- 打开:
CONFIG_CAF_CLICK_DETECTOR=y
- 新建 click 配置头文件,定义
click_detector_config[]。
至少要给出:
key_idconsume_button_event
- 用
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 方案示例:
CONFIG_CAF_LEDS=y
CONFIG_CAF_LEDS_PWM=y
CONFIG_LED=y
CONFIG_LED_PWM=y
CONFIG_PWM=y
GPIO 方案示例:
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.rstC:\ncs\v3.2.3\nrf\samples\caf
5.5 CAF_POWER_MANAGER
用途
- 管理系统从 idle 到 suspended/off 的切换
- 对外广播
power_down_event、wake_up_event、power_off_event
最小接入
CONFIG_CAF_POWER_MANAGER=y
常用附加项:
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 连接状态事件
最小接入
CONFIG_BT=y
CONFIG_BT_SMP=y
CONFIG_CAF_BLE_STATE=y
常见附加项:
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 连接存在时,阻止系统进入过深省电级别
最小接入
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 控制广播
最小接入
- 启用
CAF_BLE_STATE - 启用:
CONFIG_CAF_BLE_ADV=y
- 配置 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
最小接入
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,还要配置:
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_SHORTCONFIG_CAF_BLE_BOND_PEER_ERASE_CLICK_LONGCONFIG_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
最小接入
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()
最小接入
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
最小接入
CONFIG_CAF_NET_STATE=y
具体 backend 由链路层决定,例如:
CONFIG_CAF_NET_STATE_LTECONFIG_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
最小接入
CONFIG_CAF_SENSOR_MANAGER=y
CONFIG_SENSOR=y
还需要:
- 在 DTS/overlay 中启用传感器
- 打开对应传感器驱动 Kconfig
- 新建
sm_sensor_config[]配置文件 - 用
CONFIG_CAF_SENSOR_MANAGER_DEF_PATH指向该文件
配置项通常至少包括:
dev_nameevent_descrchanschan_cntsampling_period_msactive_events_limit
何时使用
- 有 IMU、加速度计、光传感器、环境传感器等
补充
- 有独立采样线程
- 支持 trigger
- 支持 PM
参考:
C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\sensor_manager.rstC:\ncs\v3.2.3\nrf\samples\caf_sensor_manager
5.14 CAF_SENSOR_DATA_AGGREGATOR
用途
- 将多个
sensor_event聚合成更大的数据包 - 多核 SoC 下可降低核间唤醒频率
最小接入
CONFIG_CAF_SENSOR_DATA_AGGREGATOR=y
如果另一核心要接收聚合事件,还可启用:
CONFIG_CAF_SENSOR_DATA_AGGREGATOR_EVENTS=y
还需要:
- 在 DTS/overlay 里添加
compatible = "caf,aggregator"的节点
关键属性:
sensor_descrbuf_data_lengthsample_sizebuf_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
最小接入
CONFIG_CAF_FACTORY_RESET_REQUEST=y
CONFIG_CAF_FACTORY_RESET_REQUEST_BUTTON=0x0000
CONFIG_CAF_FACTORY_RESET_REQUEST_DELAY=50
它依赖:
CAF_BUTTONSbutton_event
何时使用
- 开机长按某键请求恢复出厂
- 需要给上层模块一个统一 factory-reset 事件入口
补充
- 这个模块在
NCS v3.2.3源码中存在 - 但没有找到与其他模块同等级的独立官方
.rst页面 - 当前说明主要依据:
C:\ncs\v3.2.3\nrf\subsys\caf\modules\Kconfig.factory_reset_requestC:\ncs\v3.2.3\nrf\subsys\caf\modules\factory_reset_request.c
5.16 CAF_SHELL
用途
- 通过 Zephyr Shell 手工触发 CAF 事件
- 便于调试
最小接入
CONFIG_CAF_SHELL=y
CONFIG_SHELL=y
CONFIG_CAF=y
常见命令:
caf_events button_event [button_id] [pressed]
例如:
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_BUTTONSCAF_CLICK_DETECTOR
适合:
- 扫描键盘按键
- 做短按/长按/双击功能键
6.2 带状态灯
CAF_BUTTONSCAF_CLICK_DETECTORCAF_LEDS
适合:
- Caps Lock 指示
- 蓝牙通道指示
- 层状态指示
6.3 电池设备
CAF_BUTTONSCAF_POWER_MANAGERCAF_BUTTONS_PM_KEEP_ALIVECAF_LEDS
适合:
- 一段时间无操作后休眠
- 按键恢复活跃状态
6.4 BLE 键盘
CAF_BLE_STATECAF_BLE_ADVCAF_BLE_BONDCAF_SETTINGS_LOADER
按需叠加:
CAF_BLE_STATE_PMCAF_BLE_SMP
适合:
- 支持广播、连接、加密、绑定
- 支持设置装载
- 需要时支持 OTA
7. 推荐的接入顺序
如果你要在 blinky 里逐步引入 CAF,建议顺序如下:
- 先接
CAF_BUTTONS - 再接
CAF_LEDS - 然后根据需要加
CAF_CLICK_DETECTOR - 如果是电池设备,再接
CAF_POWER_MANAGER - 如果要做 BLE,再接
CAF_BLE_STATE、CAF_BLE_ADV、CAF_BLE_BOND - 如果要做 OTA,再接
CAF_BLE_SMP
这样改动面最小,也最容易定位问题。
8. 官方参考路径
建议优先阅读这些本地官方文件:
C:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\caf_overview.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\buttons.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\click_detector.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\leds.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\power_manager.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_state.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_state_pm.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_adv.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_bond.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\ble_smp.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\settings_loader.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\net_state.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\sensor_manager.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\sensor_data_aggregator.rstC:\ncs\v3.2.3\nrf\doc\nrf\libraries\caf\caf_shell.rst
同时可参考源码:
C:\ncs\v3.2.3\nrf\subsys\caf\modulesC:\ncs\v3.2.3\nrf\samples\cafC:\ncs\v3.2.3\nrf\samples\caf_sensor_manager
9. 一句话结论
如果只看键盘/鼠标类项目,CAF 里最值得优先使用的官方模块通常是:
CAF_BUTTONSCAF_CLICK_DETECTORCAF_LEDSCAF_POWER_MANAGERCAF_BLE_STATECAF_BLE_ADVCAF_BLE_BONDCAF_SETTINGS_LOADER
它们已经覆盖了一个 BLE/USB 输入设备项目里最常见的基础设施。