Compare commits
4 Commits
5b4353d94f
...
b5433f0403
| Author | SHA1 | Date | |
|---|---|---|---|
| b5433f0403 | |||
| 881b36274c | |||
| e369567998 | |||
| c0a6e45911 |
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.20.0)
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
|
||||||
if(EXISTS "E:/extra/modules/ip5305")
|
if(EXISTS "E:/extra/modules/ip5306")
|
||||||
list(APPEND ZEPHYR_EXTRA_MODULES "E:/extra/modules/ip5305")
|
list(APPEND ZEPHYR_EXTRA_MODULES "E:/extra/modules/ip5306")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
|||||||
314
docs/bluetooth_sig_ble_profiles_summary.md
Normal file
314
docs/bluetooth_sig_ble_profiles_summary.md
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
# Bluetooth SIG 规格页中的 BLE Profile 汇总
|
||||||
|
|
||||||
|
更新时间:2026-04-01(Asia/Hong_Kong)
|
||||||
|
|
||||||
|
## 1. 说明与筛选口径
|
||||||
|
|
||||||
|
本文基于 Bluetooth SIG 官方规格索引页 `https://www.bluetooth.com/specifications/specs/` 当前处于 `Adopted` 状态的条目进行筛选,只保留运行在 Bluetooth Low Energy 体系上的 Profile,包括:
|
||||||
|
|
||||||
|
- 基于 GATT 的传统 BLE Profile
|
||||||
|
- 基于 LE Audio 的音频类 Profile
|
||||||
|
- 基于 Bluetooth Mesh / NLC 的 Profile
|
||||||
|
|
||||||
|
本文中的“详细说明”不是官方规范原文摘录,也不是对规范条款的逐句转述,而是我基于 BLE/GATT、LE Audio、Mesh/NLC 的通用工程记忆做的高层总结。用于快速建立全局认知和做架构预判是合适的;如果要做互操作或拿来做 BQB/QDID 级别实现,仍应回到对应规范逐条核对。
|
||||||
|
|
||||||
|
本次共纳入 **59** 个 Profile。
|
||||||
|
|
||||||
|
## 2. 总表
|
||||||
|
|
||||||
|
| Profile | 最新版本 | 类别 | 官方条目 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| Alert Notification Profile | 1.0 | 核心/GATT | https://www.bluetooth.com/specifications/specs/alert-notification-profile-1-0/ |
|
||||||
|
| Ambient Light Sensor NLC Profile | 1.0.1 | Mesh/NLC | https://www.bluetooth.com/specifications/specs/ambient-light-sensor-nlc-profile-1-0-1/ |
|
||||||
|
| Asset Tracking Profile | 1.0 | 商业/工业/定位 | https://www.bluetooth.com/specifications/specs/asset-tracking-profile-1-0/ |
|
||||||
|
| Authorization Control Profile | 1.0 | 商业/工业/定位 | https://www.bluetooth.com/specifications/specs/authorization-control-profile-1-0/ |
|
||||||
|
| Automation IO Profile | 1.0 | 核心/GATT | https://www.bluetooth.com/specifications/specs/automation-io-profile-1-0/ |
|
||||||
|
| Basic Audio Profile | 1.0.2 | LE Audio | https://www.bluetooth.com/specifications/specs/basic-audio-profile-1-0-2/ |
|
||||||
|
| Basic Lightness Controller NLC Profile | 1.0.1 | Mesh/NLC | https://www.bluetooth.com/specifications/specs/basic-lightness-controller-nlc-profile-1-0-1/ |
|
||||||
|
| Basic Scene Selector NLC Profile | 1.0.1 | Mesh/NLC | https://www.bluetooth.com/specifications/specs/basic-scene-selector-nlc-profile-1-0-1/ |
|
||||||
|
| Binary Sensor Profile | 1.0 | 商业/工业/定位 | https://www.bluetooth.com/specifications/specs/binary-sensor-profile-1-0/ |
|
||||||
|
| Blood Pressure Profile | 1.1.1 | 健康/医疗 | https://www.bluetooth.com/specifications/specs/blood-pressure-profile-1-1-1/ |
|
||||||
|
| Calendar Tasks and Notes Profile | 1.0.1 | 核心/GATT | https://www.bluetooth.com/specifications/specs/calendar-tasks-and-notes-profile-1-0-1/ |
|
||||||
|
| Call Control Profile | 1.0 | LE Audio | https://www.bluetooth.com/specifications/specs/call-control-profile-1-0/ |
|
||||||
|
| Common Audio Profile | 1.0.1 | LE Audio | https://www.bluetooth.com/specifications/specs/common-audio-profile-1-0-1/ |
|
||||||
|
| Continuous Glucose Monitoring Profile | 1.0.2 | 健康/医疗 | https://www.bluetooth.com/specifications/specs/continuous-glucose-monitoring-profile-1-0-2/ |
|
||||||
|
| Cookware Profile | 1.0 | 商业/工业/定位 | https://www.bluetooth.com/specifications/specs/cookware-profile-1-0/ |
|
||||||
|
| Coordinated Set Identification Profile | 1.1 | LE Audio | https://www.bluetooth.com/specifications/specs/coordinated-set-identification-profile-1-1/ |
|
||||||
|
| Cycling Power Profile | 1.1.1 | 运动/定位 | https://www.bluetooth.com/specifications/specs/cycling-power-profile-1-1-1/ |
|
||||||
|
| Cycling Speed and Cadence Profile | 1.0.1 | 运动/定位 | https://www.bluetooth.com/specifications/specs/cycling-speed-and-cadence-profile/ |
|
||||||
|
| Device Time Profile | 1.0 | 核心/GATT | https://www.bluetooth.com/specifications/specs/device-time-profile-1-0/ |
|
||||||
|
| Dimming Control NLC Profile | 1.0.1 | Mesh/NLC | https://www.bluetooth.com/specifications/specs/dimming-control-nlc-profile-1-0-1/ |
|
||||||
|
| Electronic Shelf Label Profile | 1.0.1 | 商业/工业/定位 | https://www.bluetooth.com/specifications/specs/electronic-shelf-label-profile-1-0-1/ |
|
||||||
|
| Emergency Profile | 1.0 | 商业/工业/定位 | https://www.bluetooth.com/specifications/specs/emergency-profile-1-0/ |
|
||||||
|
| Energy Monitor NLC Profile | 1.0.1 | Mesh/NLC | https://www.bluetooth.com/specifications/specs/energy-monitor-nlc-profile1-0-1/ |
|
||||||
|
| Environmental Sensing Profile | 1.0.1 | 核心/GATT | https://www.bluetooth.com/specifications/specs/environmental-sensing-profile-1-0-1/ |
|
||||||
|
| Find Me Profile | 1.0 | 核心/GATT | https://www.bluetooth.com/specifications/specs/find-me-profile-1-0/ |
|
||||||
|
| Fitness Machine Profile | 1.0.1 | 运动/定位 | https://www.bluetooth.com/specifications/specs/fitness-machine-profile-1-0-1/ |
|
||||||
|
| Gaming Audio Profile | 1.0.1 | LE Audio | https://www.bluetooth.com/specifications/specs/gaming-audio-profile-4/ |
|
||||||
|
| Generic Health Sensor Profile | 1.0 | 健康/医疗 | https://www.bluetooth.com/specifications/specs/generic-health-sensor-profile/ |
|
||||||
|
| Global Navigation Satellite System Profile | 1.0 | 运动/定位 | https://www.bluetooth.com/specifications/specs/global-navigation-satellite-system-profile-1-0/ |
|
||||||
|
| Glucose Profile | 1.0.1 | 健康/医疗 | https://www.bluetooth.com/specifications/specs/glucose-profile-1-0-1/ |
|
||||||
|
| Health Thermometer Profile | 1.0 | 健康/医疗 | https://www.bluetooth.com/specifications/specs/health-thermometer-profile-1-0/ |
|
||||||
|
| Hearing Access Profile | 1.0.1 | LE Audio | https://www.bluetooth.com/specifications/specs/hearing-access-profile-1-0-1/ |
|
||||||
|
| Heart Rate Profile | 1.0 | 健康/医疗 | https://www.bluetooth.com/specifications/specs/heart-rate-profile-1-0/ |
|
||||||
|
| HID Over GATT Profile | 1.1 | 核心/GATT | https://www.bluetooth.com/specifications/specs/hid-over-gatt-profile/ |
|
||||||
|
| HVAC Integration NLC Profile | 1.0 | Mesh/NLC | https://www.bluetooth.com/specifications/specs/hvac-integration-nlc-profile/ |
|
||||||
|
| Industrial Measurement Device Profile | 1.0 | 商业/工业/定位 | https://www.bluetooth.com/specifications/specs/industrial-measurement-device-profile-1-0/ |
|
||||||
|
| Insulin Delivery Profile | 1.0.2 | 健康/医疗 | https://www.bluetooth.com/specifications/specs/insulin-delivery-profile-1-0-2/ |
|
||||||
|
| Internet Protocol Support Profile | 1.0 | 核心/GATT | https://www.bluetooth.com/specifications/specs/internet-protocol-support-profile-1-0/ |
|
||||||
|
| Location and Navigation Profile | 1.0.1 | 运动/定位 | https://www.bluetooth.com/specifications/specs/location-and-navigation-profile-1-0-1/ |
|
||||||
|
| Media Control Profile | 1.0 | LE Audio | https://www.bluetooth.com/specifications/specs/media-control-profile/ |
|
||||||
|
| Mesh Configuration Database Profile | 1.0.1 | Mesh/NLC | https://www.bluetooth.com/specifications/specs/mesh-configuration-database-profile-1-0-1/ |
|
||||||
|
| Mesh Profile | 1.0.1 | Mesh/NLC | https://www.bluetooth.com/specifications/specs/mesh-profile-1-0-1/ |
|
||||||
|
| Microphone Control Profile | 1.0 | LE Audio | https://www.bluetooth.com/specifications/specs/microphone-control-profile-1-0/ |
|
||||||
|
| Object Transfer Profile | 1.0 | 核心/GATT | https://www.bluetooth.com/specifications/specs/object-transfer-profile-1-0/ |
|
||||||
|
| Occupancy Sensor NLC Profile | 1.0.1 | Mesh/NLC | https://www.bluetooth.com/specifications/specs/occupancy-sensor-nlc-profile-1-0-1/ |
|
||||||
|
| Phone Alert Status Profile | 1.0 | 核心/GATT | https://www.bluetooth.com/specifications/specs/phone-alert-status-profile-1-0/ |
|
||||||
|
| Physical Activity Monitor Profile | 1.0 | 健康/医疗 | https://www.bluetooth.com/specifications/specs/physical-activity-monitor-profile-1-0/ |
|
||||||
|
| Proximity Profile | 1.0.1 | 核心/GATT | https://www.bluetooth.com/specifications/specs/proximity-profile-1-0-1/ |
|
||||||
|
| Public Broadcast Profile | 1.0.2 | LE Audio | https://www.bluetooth.com/specifications/specs/public-broadcast-profile-1-0-2/ |
|
||||||
|
| Pulse Oximeter Profile | 1.0.1 | 健康/医疗 | https://www.bluetooth.com/specifications/specs/pulse-oximeter-profile-1-0-1/ |
|
||||||
|
| Ranging Profile | 1.0 | 商业/工业/定位 | https://www.bluetooth.com/specifications/specs/ranging-profile-1-0/ |
|
||||||
|
| Reconnection Configuration Profile | 1.0.1 | LE Audio | https://www.bluetooth.com/specifications/specs/reconnection-configuration-profile-1-0-1/ |
|
||||||
|
| Running Speed and Cadence Profile | 1.0.1 | 运动/定位 | https://www.bluetooth.com/specifications/specs/running-speed-and-cadence-profile-1-0-1/ |
|
||||||
|
| Scan Parameters Profile | 1.0 | 核心/GATT | https://www.bluetooth.com/specifications/specs/scan-parameters-profile-1-0/ |
|
||||||
|
| Telephony and Media Audio Profile | 1.0.1 | LE Audio | https://www.bluetooth.com/specifications/specs/telephony-and-media-audio-profile-1-0-1/ |
|
||||||
|
| Time Profile | 1.0 | 核心/GATT | https://www.bluetooth.com/specifications/specs/time-profile-1-0/ |
|
||||||
|
| Voice Assistant Profile | 1.0 | LE Audio | https://www.bluetooth.com/specifications/specs/voice-assistant-profile-1-0/ |
|
||||||
|
| Volume Control Profile | 1.0 | LE Audio | https://www.bluetooth.com/specifications/specs/volume-control-profile-1-0/ |
|
||||||
|
| Weight Scale Profile | 1.0.1 | 健康/医疗 | https://www.bluetooth.com/specifications/specs/weight-scale-profile-1-0-1/ |
|
||||||
|
|
||||||
|
## 3. 逐项详细说明
|
||||||
|
|
||||||
|
### 3.1 核心 / GATT 类
|
||||||
|
|
||||||
|
#### Alert Notification Profile
|
||||||
|
这是一个把“手机或主设备上的提醒事件”标准化转给外设的 Profile,常见目标是手表、腕带、桌面提醒器之类的低功耗接收端。它关注的是类别化通知、已读状态、未读计数、立即提醒这类轻量信息,而不是完整消息正文同步。工程上它适合做“提醒镜像”,不适合做完整 IM 客户端。
|
||||||
|
|
||||||
|
#### Automation IO Profile
|
||||||
|
这个 Profile 面向简单工业控制和楼宇场景,核心思想是把离散输入、离散输出、模拟量等基础 I/O 点位做成统一抽象。它适合开关量、继电器、按钮、状态量等低复杂度控制接口,不强调复杂控制逻辑本身。工程上常被当作 BLE 版“轻量远程 I/O 面板”。
|
||||||
|
|
||||||
|
#### Calendar Tasks and Notes Profile
|
||||||
|
它的定位是让外设以标准方式访问日历、待办和笔记这类个人信息对象。和“通知”类 Profile 相比,它更偏对象化数据同步,强调项目集合、元数据、内容条目和访问流程。适用场景通常是可穿戴设备、车载设备或桌面配件做轻量 PIM 同步。
|
||||||
|
|
||||||
|
#### Device Time Profile
|
||||||
|
这个 Profile 的重点是设备侧时间基准管理,适合让一个时间主设备给多个从设备做校时。它通常关心设备当前时间、时区、DST 或更新时间来源等信息。工程上它比通用的 Time Profile 更偏“设备维护”视角。
|
||||||
|
|
||||||
|
#### Environmental Sensing Profile
|
||||||
|
这是 BLE 里很常见的环境类 Profile,覆盖温度、湿度、气压、露点、风速、空气质量等大量环境传感字段。它的价值在于给环境监测节点定义统一组织方式,减少私有 GATT 设计。做传感器平台时,它通常是优先考虑的标准基线。
|
||||||
|
|
||||||
|
#### Find Me Profile
|
||||||
|
这是最早一批 BLE Profile 之一,场景非常直接:主设备触发外设发声、闪灯或震动,从而“找回”钥匙扣、标签或其他小设备。它的交互非常简单,通常没有复杂数据通道。工程上它偏“单向触发”,不是精确定位方案。
|
||||||
|
|
||||||
|
#### HID Over GATT Profile
|
||||||
|
HOGP 是 BLE 键盘、鼠标、遥控器、触控设备最核心的标准 Profile 之一。它把传统 HID 语义映射到 GATT,让低功耗输入设备能和主机系统直接互通,并支持报告模式、协议模式、Boot 兼容路径等。对键盘项目来说,它通常就是“标准输入外设”的第一选择。
|
||||||
|
|
||||||
|
#### Internet Protocol Support Profile
|
||||||
|
这个 Profile 的意义在于让 BLE 不只是传属性值,还能承载 IPv6/6LoWPAN 之类的上层网络协议。它面向的是更偏物联网基础设施的场景,而不是简单外设控制。工程上只有在你明确需要把设备纳入 IP 网络模型时才值得采用。
|
||||||
|
|
||||||
|
#### Object Transfer Profile
|
||||||
|
OTP 面向“对象”而不是“单个特征值”,适合在 BLE 上搬运图片、固件片段、记录文件、联系人卡片等具备元数据和可寻址性的内容。它通常依赖对象目录、对象元信息、读写偏移、创建删除等对象管理能力。和自定义长特征值相比,它更规范,但实现复杂度也更高。
|
||||||
|
|
||||||
|
#### Phone Alert Status Profile
|
||||||
|
PASP 主要用于把手机侧“来电铃声、振动、静音、提醒状态”这类手机告警状态同步给外设。它和 Alert Notification Profile 关系很近,但更强调电话和提醒设备状态而不是通知明细本身。典型设备是手环、腕表和桌面提醒器。
|
||||||
|
|
||||||
|
#### Proximity Profile
|
||||||
|
Proximity Profile 更关注链路“靠近/远离”带来的行为,比如距离太远时报警、靠近后自动静音或恢复。它通常依赖发射功率与链路损耗这类简单近远估计,不等同于现代高精度测距。工程上可以把它理解为 Find Me 的“距离关联版”。
|
||||||
|
|
||||||
|
#### Scan Parameters Profile
|
||||||
|
这个 Profile 主要用来让扫描方和被扫描方就扫描参数做一定程度的协同,目标是兼顾发现时延和功耗。它是很早期 BLE 生态为手机与外设配合而定义的补充机制。现代系统里它未必总是显性出现,但在兼容旧实现时仍值得知道。
|
||||||
|
|
||||||
|
#### Time Profile
|
||||||
|
Time Profile 是 BLE 时间同步体系的通用基线,关注当前时间、精度、参考时间来源以及时间更新。它适合需要基本时钟同步但又不想自定义时间服务的设备。和 Device Time Profile 相比,它更像“通用时间语义”的上层封装。
|
||||||
|
|
||||||
|
### 3.2 健康 / 医疗类
|
||||||
|
|
||||||
|
#### Blood Pressure Profile
|
||||||
|
这个 Profile 面向电子血压计,核心数据通常是收缩压、舒张压、平均动脉压、测量时间戳和脉搏等。它的价值在于让手机健康应用、家庭医疗网关和血压计之间具备一致的数据模型。工程上应特别注意单位、时序和一条记录的完整性。
|
||||||
|
|
||||||
|
#### Continuous Glucose Monitoring Profile
|
||||||
|
CGM Profile 面向连续血糖监测设备,强调连续采样、趋势、会话状态和告警管理。它比传统 Glucose Profile 更适合长时间持续数据流和设备状态追踪。医疗属性很强,实现时通常还要同时考虑记录缓存、断线补传和告警可靠性。
|
||||||
|
|
||||||
|
#### Generic Health Sensor Profile
|
||||||
|
从命名和生态位置看,它是为了给大量新型健康传感器提供一个更泛化的标准外壳,避免每类新传感器都重新造一套 Profile。它适合指标多样但又不值得为单一指标单独立 Profile 的健康设备。工程上可把它看作医疗/健康类的“可扩展通用框架”。
|
||||||
|
|
||||||
|
#### Glucose Profile
|
||||||
|
Glucose Profile 更偏间歇式测量设备,例如指尖采血血糖仪。它通常围绕测量记录、上下文信息、时间戳和历史数据访问来组织。和 CGM 相比,它不强调连续流,而更强调离散测量记录管理。
|
||||||
|
|
||||||
|
#### Health Thermometer Profile
|
||||||
|
这个 Profile 用于体温计或温度类健康设备,重点是体温测量值、测量部位、时间戳等。它在家庭健康设备中很常见,互操作也比较成熟。工程实现通常不复杂,但要处理好单位、一次性测量与持续测量模式的区分。
|
||||||
|
|
||||||
|
#### Heart Rate Profile
|
||||||
|
这是最常见的 BLE 健康/运动 Profile 之一,面向心率带、手环、运动设备。它核心传的是实时心率值,并可包含能量消耗或 RR-Interval 等附加信息。因为支持广、实现轻,很多平台把它当成 BLE 互操作示范案例。
|
||||||
|
|
||||||
|
#### Insulin Delivery Profile
|
||||||
|
这个 Profile 面向胰岛素泵或给药相关设备,重点是输注状态、历史记录、治疗参数和控制安全性。它比一般传感器 Profile 更强调状态机和风险控制语义。工程上要把“数据展示”和“可导致治疗动作的控制”严格分层。
|
||||||
|
|
||||||
|
#### Physical Activity Monitor Profile
|
||||||
|
它覆盖日常活动跟踪场景,如步数、活动时长、活动等级、消耗估算等。相比 Heart Rate 这类单一生理信号,它更偏行为统计与日常健康监测。适合手环、健康贴片、轻量可穿戴。
|
||||||
|
|
||||||
|
#### Pulse Oximeter Profile
|
||||||
|
这个 Profile 主要用于脉搏血氧设备,核心指标是 SpO2、脉率以及相关上下文。它在家用健康、睡眠监测和康复设备中很常见。工程上要区分瞬时显示值和可归档记录值,避免 UI 和记录逻辑混淆。
|
||||||
|
|
||||||
|
#### Weight Scale Profile
|
||||||
|
Weight Scale Profile 面向体重秤和身体成分相关设备,基础数据是体重,也可带 BMI、身高、时间戳等信息。它的价值在于手机健康应用能直接理解标准数据而不需要厂商私有解析。对消费级产品来说,这个 Profile 的生态成熟度很高。
|
||||||
|
|
||||||
|
### 3.3 运动 / 定位类
|
||||||
|
|
||||||
|
#### Cycling Power Profile
|
||||||
|
面向功率计、自行车台、训练设备,核心是功率值以及踏频、扭矩、左右平衡、曲线段等扩展信息。它属于运动传感里实现要求较高的一类,因为用户往往关心高刷新率和训练准确性。做骑行训练生态时,这个 Profile 很关键。
|
||||||
|
|
||||||
|
#### Cycling Speed and Cadence Profile
|
||||||
|
这个 Profile 用于车轮速度和踏频传感器,数据模型比功率计更轻。它非常适合电池供电的低功耗传感器做长续航设计。常见场景是码表、运动表、骑行 App 与车轮/踏频传感器互联。
|
||||||
|
|
||||||
|
#### Fitness Machine Profile
|
||||||
|
FTMP 面向跑步机、动感单车、划船机、椭圆机等健身器材,既包含器材上报,也允许控制类交互。它的意义是把“训练设备”从单纯传感器提升到可配置、可联动的训练终端。工程上需要特别留意控制权限和状态一致性。
|
||||||
|
|
||||||
|
#### Global Navigation Satellite System Profile
|
||||||
|
这个 Profile 面向 GNSS 接收设备,把位置、速度、卫星状态或导航相关信息以标准方式暴露给对端。它适合外置卫星定位模块、运动设备或定位记录器。工程上常见用途是把 GNSS 功能从主机中解耦到独立 BLE 外设。
|
||||||
|
|
||||||
|
#### Location and Navigation Profile
|
||||||
|
这个 Profile 是通用位置/导航数据封装,通常涵盖位置、速度、航向、海拔和导航点信息。它比单纯 GNSS 更高层,能容纳更多导航语义。适用于户外设备、船舶设备、骑行/跑步导航附件。
|
||||||
|
|
||||||
|
#### Running Speed and Cadence Profile
|
||||||
|
RSC Profile 面向跑步脚环、鞋夹或可穿戴传感器,关注跑速、步频、步长、跑/走状态等。它和骑行速度/踏频 Profile 类似,属于低功耗、低带宽但很实用的运动类标准。对跑步生态兼容性来说,它是基础件。
|
||||||
|
|
||||||
|
### 3.4 LE Audio 类
|
||||||
|
|
||||||
|
#### Basic Audio Profile
|
||||||
|
BAP 是 LE Audio 体系里的基础音频传输 Profile,围绕单播/广播音频流、流配置和基本音频能力组织。可以把它理解为 LE Audio 的“音频承载基石”。很多更上层的音频 Profile 都会依赖它提供的流控制和能力表达。
|
||||||
|
|
||||||
|
#### Call Control Profile
|
||||||
|
CCP 用来表达通话相关控制语义,比如接听、挂断、保持、来电状态变化等。它的目的不是定义音频编解码,而是把“通话控制面”标准化。对耳机、免提设备、车载设备来说,它是电话业务的关键拼图。
|
||||||
|
|
||||||
|
#### Common Audio Profile
|
||||||
|
CAP 更像 LE Audio 各类设备协同行为的公共约束层,定义一组通用角色和组合方式,避免不同音频 Profile 各自形成孤岛。它通常与 CSIP、BAP 等配合使用。工程上可把它看成 LE Audio 设备行为一致性的“总装配规则”。
|
||||||
|
|
||||||
|
#### Coordinated Set Identification Profile
|
||||||
|
CSIP 用来把多个独立设备组织成一个协调集合,典型例子就是左右耳耳机、双扬声器或多设备音频系统。它解决的问题是“多个物理设备如何在逻辑上被识别为一组”。没有它,多设备配对、切换和同步体验会明显变差。
|
||||||
|
|
||||||
|
#### Gaming Audio Profile
|
||||||
|
从命名和 LE Audio 位置看,它面向游戏场景的低时延、双向音频和设备控制协同。它通常比通用媒体播放更强调时延预算、语音聊天和交互响应。工程上适合游戏耳机、掌机配件、无线麦克风方案。
|
||||||
|
|
||||||
|
#### Hearing Access Profile
|
||||||
|
HAP 面向助听器、听辅设备及其控制终端,重点是接入、控制、状态读取以及个性化听力功能配合。它是 LE Audio 在医疗辅助听力方向的重要接口层。实现时要特别关注可靠性、低时延和多设备协同。
|
||||||
|
|
||||||
|
#### Media Control Profile
|
||||||
|
MCP 把媒体播放控制抽象成标准接口,例如播放、暂停、下一曲、上一曲、快进、元数据查看等。它解决的是控制面统一,不直接替代音频流承载本身。对耳机、遥控器、车载控制面板都很有价值。
|
||||||
|
|
||||||
|
#### Microphone Control Profile
|
||||||
|
这个 Profile 聚焦麦克风相关控制,最典型的是静音/取消静音以及麦克风状态同步。它常用于耳机、会议设备、采集配件和语音终端。虽然看起来简单,但在多端协同和 UI 同步上很有必要。
|
||||||
|
|
||||||
|
#### Public Broadcast Profile
|
||||||
|
PBP 是 Auracast/Public Broadcast 体系中的关键 Profile,解决的是公开广播音频如何被发现、识别和接入。它偏广播音频的“可发现性与可消费性”约束,而不只是裸流传输。适合商场、机场、影院、公共导览等大范围音频分发场景。
|
||||||
|
|
||||||
|
#### Reconnection Configuration Profile
|
||||||
|
从命名和音频生态位置看,这个 Profile 用来描述设备断开后如何重连、优先重连谁、何时自动恢复等重连策略。它的目的通常是改善多主机、多耳塞、多场景切换时的用户体验。工程上它属于“体验型 Profile”,对 TWS 这类设备尤其重要。
|
||||||
|
|
||||||
|
#### Telephony and Media Audio Profile
|
||||||
|
TMAP 是 LE Audio 设备在电话与媒体两大主场景中的角色组合规范。它更多定义“设备是什么、在这个场景里应该怎么协同”,而不是单一控制命令。可以把它理解为 LE Audio 终端类型与用例映射。
|
||||||
|
|
||||||
|
#### Voice Assistant Profile
|
||||||
|
从生态定位看,VAP 面向语音助手接入场景,让耳机或外设能标准化启动助手会话、处理语音交互路径和相关状态。它通常和麦克风控制、音频流控制、设备角色协同使用。适用场景是耳机呼出助手、可穿戴语音入口、车载语音终端。
|
||||||
|
|
||||||
|
#### Volume Control Profile
|
||||||
|
VCP 负责音量控制与状态同步,包括绝对音量、音量步进、静音状态等。它的价值是让多类 LE Audio 终端对音量行为有一致表达。工程上如果你不希望每个设备都做私有音量协议,它是很自然的选择。
|
||||||
|
|
||||||
|
### 3.5 商业 / 工业 / 定位类
|
||||||
|
|
||||||
|
#### Asset Tracking Profile
|
||||||
|
这个 Profile 面向资产标签与定位基础设施,典型场景是仓储、零售、医院、物流等环境中的物品追踪。它通常会和广播、周期广播、方向查找或其他定位能力协作,而不是只靠一个静态 GATT 表。工程上它强调“标签、定位器、后台系统”三者的协同。
|
||||||
|
|
||||||
|
#### Authorization Control Profile
|
||||||
|
从命名看,它用于标准化“授权对象”和“访问控制状态”的 BLE 交互,适合门锁、闸机、设备启停授权、数字钥匙等场景。它的重点更像权限校验和授权流程,而不是通用传感。实现时安全边界、凭证生命周期和离线行为都应优先设计。
|
||||||
|
|
||||||
|
#### Binary Sensor Profile
|
||||||
|
这是一个很实用但语义非常克制的 Profile,用来表达开/关、在/不在、触发/未触发、占用/未占用这类二值状态。它适合门磁、按钮、限位、干接点、简单安防触发器等设备。它的优势是简单、低功耗、互操作成本低。
|
||||||
|
|
||||||
|
#### Cookware Profile
|
||||||
|
从命名和家电生态位置看,它面向智能锅具、烹饪容器或配套温控设备。核心信息大概率围绕锅具温度、烹饪阶段、加热状态、定时和食材完成度提示。它适合做厨房配件的标准化接口,但实际产品里常仍会叠加厂商私有逻辑。
|
||||||
|
|
||||||
|
#### Electronic Shelf Label Profile
|
||||||
|
ESL Profile 是零售领域非常明确的商业场景标准,用于价签设备和控制基础设施之间的低功耗、批量、可靠更新。它强调群组调度、同步刷新、超低功耗待机和门店级大规模部署能力。对商超场景来说,这是 BLE 向“基础设施协议”扩展的代表作。
|
||||||
|
|
||||||
|
#### Emergency Profile
|
||||||
|
从名称判断,它服务于紧急告警、求助、事件上报和联动响应这类场景,例如老人监护、工业告警、紧急按钮设备。它通常不只是传一个布尔值,更强调事件等级、状态和响应流程。工程实现时要把“告警一定要送达”的可靠性目标单独考虑。
|
||||||
|
|
||||||
|
#### Industrial Measurement Device Profile
|
||||||
|
这个 Profile 面向工业测量设备,例如压力表、流量计、过程测量节点、便携仪表等。它的目标是让工业现场数据采集具备统一结构,而不是每家仪表都自定义私有 GATT。对工业场景来说,它比消费电子 Profile 更强调量测语义和系统集成。
|
||||||
|
|
||||||
|
#### Ranging Profile
|
||||||
|
Ranging Profile 是 BLE 进入高精度距离测量后的关键 Profile,核心目的就是把测距流程、角色和结果表达标准化。它通常适用于数字钥匙、物体接近判断、室内精细定位和安全接入场景。和早期 Proximity Profile 相比,它更接近“精确距离感知”而不是粗略远近估计。
|
||||||
|
|
||||||
|
### 3.6 Mesh / NLC 类
|
||||||
|
|
||||||
|
#### Mesh Configuration Database Profile
|
||||||
|
这个 Profile 更偏管理面,关注 Mesh 网络的配置数据库如何表达、交换和持久化。它不是普通终端用户直接感知的功能,而是配置工具、网关、后台系统之间保持网络一致性的基础。工程上它有助于把 Mesh 网络从“临时配网”提升为“可运维系统”。
|
||||||
|
|
||||||
|
#### Mesh Profile
|
||||||
|
Mesh Profile 是 Bluetooth Mesh 的核心,定义了节点、消息中继、发布订阅、低功耗节点、Friend、代理等网络行为。虽然它不是传统意义上的单设备 GATT Profile,但它的承载底座仍是 Bluetooth LE 广播和相关承载机制,所以应纳入 BLE 体系讨论。对照明、楼宇和大规模传感网络来说,它是总根。
|
||||||
|
|
||||||
|
#### Ambient Light Sensor NLC Profile
|
||||||
|
这个 NLC Profile 面向网络化照明控制里的环境光传感器节点。它把环境照度读数纳入 NLC 语义,使照明系统能做日光补偿、节能调光和场景联动。适合办公室、商业照明和智能楼宇。
|
||||||
|
|
||||||
|
#### Basic Lightness Controller NLC Profile
|
||||||
|
它对应最基础的亮度控制器角色,强调“以标准化方式控制灯光亮度”。和底层 Mesh Model 相比,NLC Profile 给的是更高层、面向成品设备的约束组合。工程上它降低了不同厂商控制面板和灯具的对接成本。
|
||||||
|
|
||||||
|
#### Basic Scene Selector NLC Profile
|
||||||
|
这个 Profile 用来标准化场景选择器,例如面板上的“会议模式、演示模式、离开模式”按钮。它适合把复杂灯光/楼宇状态打包成少量场景入口。对用户交互而言,它比直接调模型参数友好得多。
|
||||||
|
|
||||||
|
#### Dimming Control NLC Profile
|
||||||
|
这个 Profile 更强调连续调光过程和控制行为,比单纯的“设定亮度值”更贴近真实调光器交互。它适合旋钮面板、滑条、墙控设备等。工程上通常和灯光控制器、亮度控制逻辑配合使用。
|
||||||
|
|
||||||
|
#### Energy Monitor NLC Profile
|
||||||
|
它把能耗监测设备纳入 NLC 语义,可用于照明回路或楼宇设备的电能数据采集。场景包括能耗可视化、节能优化和维护分析。它的价值在于让照明系统不只“能控”,还能“可度量”。
|
||||||
|
|
||||||
|
#### HVAC Integration NLC Profile
|
||||||
|
这个 Profile 体现了 NLC 从照明向楼宇环境系统扩展的趋势,用于暖通空调相关设备和照明/楼宇控制系统互联。它适合温控器、风机盘管接口、环境联动面板等设备。工程上它更强调跨子系统协同,而不只是灯控本身。
|
||||||
|
|
||||||
|
#### Occupancy Sensor NLC Profile
|
||||||
|
这个 Profile 面向人体存在/占用检测节点,是楼宇自动化里非常核心的传感输入。它常用于自动开灯、延时关灯、空调节能、会议室占用判断。和 Binary Sensor 相比,它位于 NLC 生态内部,强调与照明/楼宇场景联动。
|
||||||
|
|
||||||
|
## 4. 未纳入的网页条目
|
||||||
|
|
||||||
|
Bluetooth SIG 规格页里还存在不少名称中带有 `Profile` 的条目,但它们不属于 BLE 体系,或者主要是 BR/EDR / Classic Bluetooth 方向,因此本次没有纳入,例如:
|
||||||
|
|
||||||
|
- 3D Synchronization Profile
|
||||||
|
- A/V Remote Control Profile
|
||||||
|
- Advanced Audio Distribution Profile
|
||||||
|
- Basic Imaging Profile
|
||||||
|
- Basic Printing Profile
|
||||||
|
- BR/EDR Connection Handover Profile
|
||||||
|
- Device Identification Profile
|
||||||
|
- Dial-Up Networking Profile
|
||||||
|
- File Transfer Profile
|
||||||
|
- Generic A/V Distribution Profile
|
||||||
|
- Generic Object Exchange Profile
|
||||||
|
- Generic PIM Profile
|
||||||
|
- Hands-Free Profile
|
||||||
|
- Hardcopy Cable Replacement Profile
|
||||||
|
- Headset Profile
|
||||||
|
- Health Device Profile
|
||||||
|
- Human Interface Device Profile
|
||||||
|
- Message Access Profile
|
||||||
|
- Multi Profile Specification
|
||||||
|
- Object Push Profile
|
||||||
|
- Personal Area Networking Profile
|
||||||
|
- Phone Book Access Profile
|
||||||
|
- Serial Port Profile
|
||||||
|
- SIM Access Profile
|
||||||
|
- Synchronization Profile
|
||||||
|
- Video Distribution Profile
|
||||||
|
|
||||||
|
说明:其中个别条目可能在现代产品里和 LE 设备共存,但其规范本体并不是“基于 BLE 的 Profile”,所以这里按“协议归属”而不是“产品是否可能双模”来排除。
|
||||||
|
|
||||||
|
## 5. 对 `new_kbd` 项目的直接参考价值
|
||||||
|
|
||||||
|
如果你的项目是键盘/输入设备,最直接相关的是:
|
||||||
|
|
||||||
|
- `HID Over GATT Profile`:BLE 键盘主标准
|
||||||
|
- `Battery Service`、`Device Information Service`、`Bonding/Security` 等虽然不在本文 Profile 汇总内,但会和 HOGP 一起构成实际产品骨架
|
||||||
|
- 如果后续要做查找键盘、靠近告警,可参考 `Find Me Profile` / `Proximity Profile`
|
||||||
|
- 如果要做文件、配置对象同步,可看 `Object Transfer Profile` 的对象化思路,但一般键盘产品没必要直接上完整 OTP
|
||||||
|
|
||||||
|
如果要继续,我可以在下一步再补一份“**和 BLE 键盘最相关的 Profile / Service / Characteristic 清单**”,直接映射到你当前 `new_kbd` 工程的实现关注点。
|
||||||
926
docs/ncs_v3_2_3_gatt_services_summary.md
Normal file
926
docs/ncs_v3_2_3_gatt_services_summary.md
Normal file
@@ -0,0 +1,926 @@
|
|||||||
|
# NCS v3.2.3 集成的 GATT Service 汇总
|
||||||
|
|
||||||
|
更新时间:2026-04-01(Asia/Hong_Kong)
|
||||||
|
|
||||||
|
## 1. 统计口径
|
||||||
|
|
||||||
|
本文面向 `C:\ncs\v3.2.3` 代码树中**应用可直接集成**的 GATT Service。
|
||||||
|
|
||||||
|
筛选规则:
|
||||||
|
|
||||||
|
- 以 `zephyr/include/zephyr/bluetooth/services/` 与 `nrf/include/bluetooth/services/` 中公开头文件为主
|
||||||
|
- 以 `zephyr/subsys/bluetooth/services/` 与 `nrf/subsys/bluetooth/services/` 中实际注册 GATT 服务的实现为准
|
||||||
|
- 优先整理**服务端**能力,也就是“本机作为 Peripheral/Server 暴露 GATT Service”时的用法
|
||||||
|
- `*_client`、`hogp`、`gattp` 这类主要用于 Central 侧发现/访问远端服务的客户端辅助库,不作为本文主表主体
|
||||||
|
|
||||||
|
按这个口径,当前 SDK 中可直接拿来做本地 GATT Service 的模块主要分为两类:
|
||||||
|
|
||||||
|
- Zephyr 自带标准服务
|
||||||
|
- NCS / Nordic 扩展服务
|
||||||
|
|
||||||
|
## 2. 先看结论
|
||||||
|
|
||||||
|
### 2.1 Zephyr 自带标准服务
|
||||||
|
|
||||||
|
| Service | Kconfig | 头文件 | 典型用途 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| Alert Notification Service | `CONFIG_BT_ANS` | `<zephyr/bluetooth/services/ans.h>` | 对手表/手环输出通知类别与未读数 |
|
||||||
|
| Battery Service | `CONFIG_BT_BAS` | `<zephyr/bluetooth/services/bas.h>` | 暴露电量、电池状态 |
|
||||||
|
| Current Time Service | `CONFIG_BT_CTS` | `<zephyr/bluetooth/services/cts.h>` | 给客户端提供当前时间/校时 |
|
||||||
|
| Device Information Service | `CONFIG_BT_DIS` | `<zephyr/bluetooth/services/dis.h>` | 暴露厂商、型号、版本、PnP ID 等静态信息 |
|
||||||
|
| Heart Rate Service | `CONFIG_BT_HRS` | `<zephyr/bluetooth/services/hrs.h>` | 心率设备 |
|
||||||
|
| Immediate Alert Service | `CONFIG_BT_IAS` | `<zephyr/bluetooth/services/ias.h>` | 查找设备、远程触发蜂鸣/闪灯 |
|
||||||
|
| Nordic UART Service(Zephyr 版) | `CONFIG_BT_ZEPHYR_NUS` | `<zephyr/bluetooth/services/nus.h>` | 简单双向串口透传 |
|
||||||
|
| Object Transfer Service | `CONFIG_BT_OTS` | `<zephyr/bluetooth/services/ots.h>` | 面向对象的数据传输 |
|
||||||
|
| Tx Power Service | `CONFIG_BT_TPS` | 无独立公共 API 头 | 暴露当前发射功率 |
|
||||||
|
|
||||||
|
### 2.2 NCS / Nordic 扩展服务
|
||||||
|
|
||||||
|
| Service | Kconfig | 头文件 | 典型用途 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| Bond Management Service | `CONFIG_BT_BMS` | `<bluetooth/services/bms.h>` | 让对端触发删 bond |
|
||||||
|
| Continuous Glucose Monitoring Service | `CONFIG_BT_CGMS` | `<bluetooth/services/cgms.h>` | 连续血糖监测 |
|
||||||
|
| Direction and Distance Finding Service | `CONFIG_BT_DDFS` | `<bluetooth/services/ddfs.h>` | 方位/距离测量结果输出 |
|
||||||
|
| Fast Pair Provider Service | `CONFIG_BT_FAST_PAIR` + `CONFIG_BT_FAST_PAIR_GATT_SERVICE` | `<bluetooth/services/fast_pair/fast_pair.h>` | Google Fast Pair |
|
||||||
|
| Human Interface Device Service | `CONFIG_BT_HIDS` | `<bluetooth/services/hids.h>` | BLE 键盘、鼠标、输入设备 |
|
||||||
|
| Latency Service | `CONFIG_BT_LATENCY` | `<bluetooth/services/latency.h>` | 延迟测试/回环 |
|
||||||
|
| LED Button Service | `CONFIG_BT_LBS` | `<bluetooth/services/lbs.h>` | 示例级 LED/Button 交互 |
|
||||||
|
| Memfault Diagnostic Service | `CONFIG_BT_MDS` | `<bluetooth/services/mds.h>` | Memfault 诊断数据导出 |
|
||||||
|
| Nordic Status Message Service | `CONFIG_BT_NSMS` | `<bluetooth/services/nsms.h>` | 暴露一段可读状态文本 |
|
||||||
|
| Nordic UART Service(Nordic 旧版) | `CONFIG_BT_NUS` | `<bluetooth/services/nus.h>` | NCS 样例常用串口透传 |
|
||||||
|
| Ranging Service | `CONFIG_BT_RAS` + `CONFIG_BT_RAS_RRSP` | `<bluetooth/services/ras.h>` | Channel Sounding / Ranging 服务端 |
|
||||||
|
| Running Speed and Cadence Service | `CONFIG_BT_RSCS` | `<bluetooth/services/rscs.h>` | 跑步速度步频 |
|
||||||
|
| Throughput Service | `CONFIG_BT_THROUGHPUT` | `<bluetooth/services/throughput.h>` | 吞吐测试 |
|
||||||
|
| Wi-Fi Provisioning Service | `CONFIG_BT_WIFI_PROV` | `<bluetooth/services/wifi_provisioning.h>` | 通过 BLE 给设备配 Wi-Fi |
|
||||||
|
|
||||||
|
## 3. 使用方式总规律
|
||||||
|
|
||||||
|
大多数服务都遵循类似流程:
|
||||||
|
|
||||||
|
1. 在 `prj.conf` 里打开对应 `CONFIG_BT_*`
|
||||||
|
2. 包含头文件
|
||||||
|
3. 若服务需要运行时初始化,则在 `bt_enable()` 前后调用对应 `init/register`
|
||||||
|
4. 连接建立后,通过通知/读写回调/API 更新服务数据
|
||||||
|
5. 在广告里决定是否放服务 UUID,但这不是注册服务的必要条件
|
||||||
|
|
||||||
|
有三类例外要先记住:
|
||||||
|
|
||||||
|
- **纯 Kconfig 静态服务**:例如 `DIS`、`TPS`,启用配置后就自动挂到 GATT DB,上层几乎没有运行时 API
|
||||||
|
- **宏定义式实例服务**:例如 `NSMS`、`Zephyr NUS` 多实例、`HIDS`,需要先用宏定义实例,再初始化或更新
|
||||||
|
- **复杂协议服务**:例如 `OTS`、`RAS`、`Fast Pair`,除了开 Kconfig,还要按它自己的状态机/回调/缓冲机制接入
|
||||||
|
|
||||||
|
## 4. 逐项说明
|
||||||
|
|
||||||
|
## 4.1 Zephyr 标准服务
|
||||||
|
|
||||||
|
### 4.1.1 Alert Notification Service, `ANS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `zephyr/subsys/bluetooth/services/ans.c`
|
||||||
|
- `zephyr/include/zephyr/bluetooth/services/ans.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_ANS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 先在 Kconfig 里决定支持哪些提醒类别,例如 `CONFIG_BT_ANS_NALRT_CAT_EMAIL=y`
|
||||||
|
- 运行时如果还想动态设置支持位图,可以调用 `bt_ans_set_new_alert_support_category()` 和 `bt_ans_set_unread_support_category()`
|
||||||
|
- 有新提醒时调用 `bt_ans_notify_new_alert(conn, category, num_new, text)`
|
||||||
|
- 未读数变化时调用 `bt_ans_set_unread_count(conn, category, unread)`
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 手环、手表、桌面提醒器
|
||||||
|
- 你只想同步“有提醒/未读数/提醒类别”,而不是完整消息正文
|
||||||
|
|
||||||
|
注意点:
|
||||||
|
|
||||||
|
- 头文件明确写了 `bt_ans_notify_new_alert()` / `bt_ans_set_unread_count()` 会拿互斥锁,**不要从 BT RX 线程或 System Workqueue 里直接调用**
|
||||||
|
- 这个服务偏“提醒镜像”,不适合做完整消息中心
|
||||||
|
|
||||||
|
### 4.1.2 Battery Service, `BAS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `zephyr/subsys/bluetooth/services/bas/`
|
||||||
|
- `zephyr/include/zephyr/bluetooth/services/bas.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_BAS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
如果要扩展电池状态:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT_BAS_BLS=y
|
||||||
|
CONFIG_BT_BAS_BCS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 最基本只需要周期性调用 `bt_bas_set_battery_level(level)`,把 0..100 的电量同步给客户端
|
||||||
|
- 读取当前缓存值可用 `bt_bas_get_battery_level()`
|
||||||
|
- 如果启用了扩展状态特征,可继续设置:
|
||||||
|
- `bt_bas_bls_set_battery_present()`
|
||||||
|
- `bt_bas_bls_set_battery_charge_state()`
|
||||||
|
- `bt_bas_bls_set_battery_charge_level()`
|
||||||
|
- `bt_bas_bls_set_service_required()`
|
||||||
|
- `bt_bas_bls_set_battery_fault()`
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 键盘、鼠标、耳机、手表、遥控器等所有电池供电外设
|
||||||
|
|
||||||
|
对你当前项目的价值:
|
||||||
|
|
||||||
|
- 这是 `new_kbd` 最应该启用的标准服务之一
|
||||||
|
- 你已经有 `ble_battery_module.c`,它天然适合映射到 BAS
|
||||||
|
|
||||||
|
### 4.1.3 Current Time Service, `CTS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `zephyr/subsys/bluetooth/services/cts.c`
|
||||||
|
- `zephyr/include/zephyr/bluetooth/services/cts.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_CTS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
可选工具 API:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT_CTS_HELPER_API=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 定义 `struct bt_cts_cb`
|
||||||
|
- 至少实现 `fill_current_cts_time()`,因为服务在被读或发通知时要靠它拿当前时间
|
||||||
|
- 如果允许对端写时间,再实现 `cts_time_write()`
|
||||||
|
- 如果关心客户端是否订阅时间更新,实现 `notification_changed()`
|
||||||
|
- 初始化时调用 `bt_cts_init(&cb)`
|
||||||
|
- 时间变化后调用 `bt_cts_send_notification(reason)`
|
||||||
|
|
||||||
|
最小使用思路:
|
||||||
|
|
||||||
|
1. 系统自己维护 RTC / Unix 时间
|
||||||
|
2. CTS 被读时把当前时间填进 `struct bt_cts_time_format`
|
||||||
|
3. 如果时间是由手机写入的,就在 `cts_time_write()` 里反写到系统时钟
|
||||||
|
|
||||||
|
### 4.1.4 Device Information Service, `DIS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `zephyr/subsys/bluetooth/services/dis.c`
|
||||||
|
- `zephyr/subsys/bluetooth/services/Kconfig.dis`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_DIS=y
|
||||||
|
CONFIG_BT_DIS_MANUF_NAME=y
|
||||||
|
CONFIG_BT_DIS_MANUF_NAME_STR="Your Company"
|
||||||
|
CONFIG_BT_DIS_MODEL_NUMBER=y
|
||||||
|
CONFIG_BT_DIS_MODEL_NUMBER_STR="KBD-01"
|
||||||
|
CONFIG_BT_DIS_PNP=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- `DIS` 基本是**纯配置型服务**
|
||||||
|
- 你在 `prj.conf` 里打开需要的特征值并填字符串/ID,服务会静态注册
|
||||||
|
- 常用字段包括:
|
||||||
|
- 厂商名
|
||||||
|
- 型号
|
||||||
|
- 序列号
|
||||||
|
- FW/HW/SW 版本
|
||||||
|
- PnP ID
|
||||||
|
- 医疗设备 UDI
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 几乎所有 BLE 外设都建议启用
|
||||||
|
|
||||||
|
对键盘项目的建议:
|
||||||
|
|
||||||
|
- 至少填 `Manufacturer Name`、`Model Number`、`FW Revision`
|
||||||
|
- 如果你将来打算做 HID 认证/系统识别,`PnP ID` 也建议补齐
|
||||||
|
|
||||||
|
### 4.1.5 Heart Rate Service, `HRS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `zephyr/subsys/bluetooth/services/hrs.c`
|
||||||
|
- `zephyr/include/zephyr/bluetooth/services/hrs.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_HRS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 若要处理控制点请求,定义 `struct bt_hrs_cb` 并注册 `bt_hrs_cb_register(&cb)`
|
||||||
|
- 上报新心率时调用 `bt_hrs_notify(heartrate)`
|
||||||
|
- 如果支持 Energy Expended 重置,则在 `ctrl_point_write()` 里处理 `BT_HRS_CONTROL_POINT_RESET_ENERGY_EXPANDED_REQ`
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 心率带、健康设备、运动设备
|
||||||
|
|
||||||
|
### 4.1.6 Immediate Alert Service, `IAS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `zephyr/subsys/bluetooth/services/ias/ias.c`
|
||||||
|
- `zephyr/include/zephyr/bluetooth/services/ias.h`
|
||||||
|
- 参考样例:`zephyr/samples/bluetooth/peripheral/src/main.c`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_IAS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 用 `BT_IAS_CB_DEFINE(name)` 定义回调对象
|
||||||
|
- 在回调里实现:
|
||||||
|
- `no_alert()`
|
||||||
|
- `mild_alert()`
|
||||||
|
- `high_alert()`
|
||||||
|
- 远端写 Alert Level 时,服务会自动回调你
|
||||||
|
- 如果本机已经在报警,且你想主动停掉当前告警,可调用 `bt_ias_local_alert_stop()`
|
||||||
|
|
||||||
|
典型逻辑:
|
||||||
|
|
||||||
|
- `mild_alert()` 里短鸣、低频闪烁
|
||||||
|
- `high_alert()` 里持续蜂鸣或高亮闪烁
|
||||||
|
- `no_alert()` 里停蜂鸣、灭灯
|
||||||
|
|
||||||
|
### 4.1.7 Nordic UART Service, `Zephyr 版 NUS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `zephyr/subsys/bluetooth/services/nus/`
|
||||||
|
- `zephyr/include/zephyr/bluetooth/services/nus.h`
|
||||||
|
- 参考样例:`zephyr/samples/bluetooth/peripheral_nus`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_ZEPHYR_NUS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
可选:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT_ZEPHYR_NUS_DEFAULT_INSTANCE=y
|
||||||
|
CONFIG_BT_ZEPHYR_NUS_AUTO_START_BLUETOOTH=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 最简单:使用默认实例
|
||||||
|
- 定义 `struct bt_nus_cb`
|
||||||
|
- 注册 `bt_nus_cb_register(&cb, ctx)`
|
||||||
|
- 对端写 RX 特征值时,你的 `received()` 回调会收到数据
|
||||||
|
- 要发数据给对端时,调用 `bt_nus_send(conn, data, len)`
|
||||||
|
|
||||||
|
高级用法:
|
||||||
|
|
||||||
|
- 这个版本支持多实例
|
||||||
|
- 你可以先用 `BT_NUS_INST_DEFINE(name)` 定义多个 NUS 端点
|
||||||
|
- 然后对每个实例调用 `bt_nus_inst_cb_register()` / `bt_nus_inst_send()`
|
||||||
|
|
||||||
|
建议:
|
||||||
|
|
||||||
|
- 新代码如果想做“可扩展串口通道”,Zephyr 版 NUS 比 Nordic 旧版更现代
|
||||||
|
|
||||||
|
### 4.1.8 Object Transfer Service, `OTS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `zephyr/subsys/bluetooth/services/ots/`
|
||||||
|
- `zephyr/include/zephyr/bluetooth/services/ots.h`
|
||||||
|
- 参考样例:`zephyr/samples/bluetooth/peripheral_ots`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_OTS=y
|
||||||
|
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
|
||||||
|
CONFIG_BT_GATT_DYNAMIC_DB=y
|
||||||
|
CONFIG_BT_SMP=y
|
||||||
|
```
|
||||||
|
|
||||||
|
按需求补充:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT_OTS_DIR_LIST_OBJ=y
|
||||||
|
CONFIG_BT_OTS_OACP_WRITE_SUPPORT=y
|
||||||
|
CONFIG_BT_OTS_OACP_PATCH_SUPPORT=y
|
||||||
|
CONFIG_BT_OTS_OACP_CREATE_SUPPORT=y
|
||||||
|
CONFIG_BT_OTS_OACP_DELETE_SUPPORT=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
1. 先拿一个实例:`bt_ots_free_instance_get()`
|
||||||
|
2. 填 `struct bt_ots_init_param`,配置支持的 OACP/OLCP Feature 与回调
|
||||||
|
3. 调用 `bt_ots_init(ots, &ots_init)`
|
||||||
|
4. 准备对象元数据与对象数据,再用 `bt_ots_obj_add(ots, ¶m)` 加入对象池
|
||||||
|
5. 客户端随后可通过 OTS 读/写/选择对象
|
||||||
|
|
||||||
|
什么时候值得用:
|
||||||
|
|
||||||
|
- 需要在 BLE 上传输“对象”,例如文件、图片、日志、记录块、配置块
|
||||||
|
- 需要比单个 characteristic 更规范的元数据和对象管理
|
||||||
|
|
||||||
|
什么时候不值得用:
|
||||||
|
|
||||||
|
- 只是传几字节配置或简单串口透传时,`NUS` 或自定义服务更轻
|
||||||
|
|
||||||
|
### 4.1.9 Tx Power Service, `TPS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `zephyr/subsys/bluetooth/services/tps.c`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_TPS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 这是典型的**无应用层 API**服务
|
||||||
|
- 打开 `CONFIG_BT_TPS` 后,服务会静态注册
|
||||||
|
- 客户端读取 `TX Power Level` 特征值时,底层会通过 `bt_conn_le_get_tx_power_level()` 取当前发射功率并返回
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 定位、调试、需要标准化暴露 TX Power 的设备
|
||||||
|
|
||||||
|
## 4.2 NCS / Nordic 扩展服务
|
||||||
|
|
||||||
|
### 4.2.1 Bond Management Service, `BMS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/bms.c`
|
||||||
|
- `nrf/include/bluetooth/services/bms.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_BMS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 定义 `struct bt_bms_init_params`
|
||||||
|
- 在里面配置支持哪些删 bond 操作,以及是否需要授权码
|
||||||
|
- 如果某些删除操作要授权,实现 `struct bt_bms_cb.authorize`
|
||||||
|
- 调用 `bt_bms_init(&init_params)`
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 设备端希望让手机或维护工具发起“删除本机 bond”
|
||||||
|
- 做售后恢复、重新配对、共享设备切换用户
|
||||||
|
|
||||||
|
对你当前项目的价值:
|
||||||
|
|
||||||
|
- 你的键盘已经在做 bond 管理,这个服务值得评估
|
||||||
|
- 但很多键盘不会直接对外开放 BMS,而是自己做按键清配对逻辑
|
||||||
|
|
||||||
|
### 4.2.2 Continuous Glucose Monitoring Service, `CGMS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/cgms/`
|
||||||
|
- `nrf/include/bluetooth/services/cgms.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_CGMS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 填 `struct bt_cgms_init_param`
|
||||||
|
- 传感器类型
|
||||||
|
- 采样位置
|
||||||
|
- session 运行时长
|
||||||
|
- 初始通信间隔
|
||||||
|
- 回调
|
||||||
|
- 调用 `bt_cgms_init(&init)`
|
||||||
|
- 每有一条新血糖测量值,就调用 `bt_cgms_measurement_add(measurement)`
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 连续血糖监测设备
|
||||||
|
|
||||||
|
### 4.2.3 Direction and Distance Finding Service, `DDFS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/ddfs.c`
|
||||||
|
- `nrf/include/bluetooth/services/ddfs.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_DDFS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 填 `struct bt_ddfs_init_params`
|
||||||
|
- 初始 features
|
||||||
|
- `struct bt_ddfs_cb` 回调
|
||||||
|
- 调用 `bt_ddfs_init(&init)`
|
||||||
|
- 应用拿到测距/方位结果后,用以下 API 通知客户端:
|
||||||
|
- `bt_ddfs_distance_measurement_notify()`
|
||||||
|
- `bt_ddfs_azimuth_measurement_notify()`
|
||||||
|
- `bt_ddfs_elevation_measurement_notify()`
|
||||||
|
|
||||||
|
回调的意义:
|
||||||
|
|
||||||
|
- `dm_ranging_mode_set()`:对端改测距模式时通知应用
|
||||||
|
- `dm_config_read()`:对端读取配置时由应用填充配置
|
||||||
|
- `*_notification_config_changed()`:通知开关变化
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 方向查找、距离估计、定位试验平台
|
||||||
|
|
||||||
|
### 4.2.4 Fast Pair Provider Service, `FPS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/fast_pair/fp_gatt_service.c`
|
||||||
|
- `nrf/include/bluetooth/services/fast_pair/fast_pair.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_FAST_PAIR=y
|
||||||
|
CONFIG_BT_FAST_PAIR_GATT_SERVICE=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 这不是通用 GATT 服务,而是 Google Fast Pair 生态专用服务
|
||||||
|
- 正常接入方式不是自己操作 characteristic,而是走高层 API
|
||||||
|
- 典型流程:
|
||||||
|
1. `bt_enable()`
|
||||||
|
2. `settings_load()`
|
||||||
|
3. 注册必要回调
|
||||||
|
4. 调用 `bt_fast_pair_enable()`
|
||||||
|
- 运行时常用 API:
|
||||||
|
- `bt_fast_pair_set_pairing_mode()`
|
||||||
|
- `bt_fast_pair_battery_set()`
|
||||||
|
- `bt_fast_pair_info_cb_register()`
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 要做经过 Fast Pair 生态认证的耳机、输入设备、Tag 类设备
|
||||||
|
|
||||||
|
不适合场景:
|
||||||
|
|
||||||
|
- 普通 BLE 外设
|
||||||
|
- 只想做自定义配对体验
|
||||||
|
|
||||||
|
### 4.2.5 Human Interface Device Service, `HIDS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/hids.c`
|
||||||
|
- `nrf/include/bluetooth/services/hids.h`
|
||||||
|
- 参考样例:
|
||||||
|
- `nrf/samples/bluetooth/peripheral_hids_keyboard`
|
||||||
|
- `nrf/samples/bluetooth/peripheral_hids_mouse`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_HIDS=y
|
||||||
|
CONFIG_BT_HIDS_MAX_CLIENT_COUNT=2
|
||||||
|
CONFIG_BT_HIDS_DEFAULT_PERM_RW_ENCRYPT=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
1. 用 `BT_HIDS_DEF(hids_obj, ...)` 定义一个 HID 服务实例
|
||||||
|
2. 准备 `struct bt_hids_init_param`
|
||||||
|
- HID 信息
|
||||||
|
- 输入/输出/特征报告组
|
||||||
|
- Report Map
|
||||||
|
- 协议模式回调
|
||||||
|
- Control Point 回调
|
||||||
|
- Boot Keyboard/Mouse 回调
|
||||||
|
- `is_kb` / `is_mouse`
|
||||||
|
3. 调用 `bt_hids_init(&hids_obj, &init_param)`
|
||||||
|
4. 连接回调里调用:
|
||||||
|
- `bt_hids_connected(&hids_obj, conn)`
|
||||||
|
- `bt_hids_disconnected(&hids_obj, conn)`
|
||||||
|
5. 发报告时调用:
|
||||||
|
- 通用输入报告:`bt_hids_inp_rep_send()`
|
||||||
|
- Boot Keyboard:`bt_hids_boot_kb_inp_rep_send()`
|
||||||
|
- Boot Mouse:`bt_hids_boot_mouse_inp_rep_send()`
|
||||||
|
|
||||||
|
对键盘项目的意义:
|
||||||
|
|
||||||
|
- 如果你走标准 HID over GATT 键盘路线,这是最关键的服务实现
|
||||||
|
- 比起自定义 NUS,HIDS 才是操作系统原生识别键盘的正路
|
||||||
|
|
||||||
|
### 4.2.6 Latency Service
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/latency.c`
|
||||||
|
- `nrf/include/bluetooth/services/latency.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_LATENCY=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 定义一个 `struct bt_latency latency`
|
||||||
|
- 可选定义 `struct bt_latency_cb`
|
||||||
|
- 调用 `bt_latency_init(&latency, &cb)`
|
||||||
|
- 对端对 Latency Characteristic 发写请求时,会回调 `latency_request()`
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 链路时延测量
|
||||||
|
- 实验室验证,不是典型产品服务
|
||||||
|
|
||||||
|
### 4.2.7 LED Button Service, `LBS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/lbs.c`
|
||||||
|
- `nrf/include/bluetooth/services/lbs.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_LBS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 定义 `struct bt_lbs_cb`
|
||||||
|
- `led_cb`:远端写 LED 特征值时回调
|
||||||
|
- `button_cb`:远端读 Button 特征值时回调
|
||||||
|
- 初始化:`bt_lbs_init(&callbacks)`
|
||||||
|
- 按键状态变化时调用 `bt_lbs_send_button_state(button_state)`
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 教学、验证链路、最小双向 GATT 交互 demo
|
||||||
|
|
||||||
|
不建议:
|
||||||
|
|
||||||
|
- 直接当成量产产品协议
|
||||||
|
|
||||||
|
### 4.2.8 Memfault Diagnostic Service, `MDS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/mds.c`
|
||||||
|
- `nrf/include/bluetooth/services/mds.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_MDS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 这个服务主要为 Memfault 诊断导出服务
|
||||||
|
- 启用后服务静态注册
|
||||||
|
- 如果想控制谁能访问诊断数据,在 `bt_enable()` 前调用 `bt_mds_cb_register(&cb)`
|
||||||
|
- 关键回调是 `access_enable(conn)`,用来决定连接方是否有权限访问 MDS 数据
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 你已经集成 Memfault,并希望通过 BLE 导出诊断信息
|
||||||
|
|
||||||
|
### 4.2.9 Nordic Status Message Service, `NSMS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/nsms.c`
|
||||||
|
- `nrf/include/bluetooth/services/nsms.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_NSMS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 这个服务不是 `init()` 风格,而是**宏定义实例**
|
||||||
|
- 用 `BT_NSMS_DEF(nsms_obj, "Status", BT_NSMS_SECURITY_LEVEL_ENCRYPT, "idle", 64)` 定义一个服务实例
|
||||||
|
- 之后运行时调用 `bt_nsms_set_status(&nsms_obj, "connected")` 更新状态文本
|
||||||
|
|
||||||
|
特点:
|
||||||
|
|
||||||
|
- 适合快速暴露一段人类可读状态字符串
|
||||||
|
- 支持安全级别配置
|
||||||
|
- 支持多实例
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 开发调试状态
|
||||||
|
- 设备工作模式简报
|
||||||
|
|
||||||
|
### 4.2.10 Nordic UART Service, `Nordic 旧版 NUS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/nus.c`
|
||||||
|
- `nrf/include/bluetooth/services/nus.h`
|
||||||
|
- 参考样例:`nrf/samples/bluetooth/peripheral_uart`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_NUS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
可选:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT_NUS_AUTHEN=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 定义 `struct bt_nus_cb`
|
||||||
|
- 调用 `bt_nus_init(&callbacks)`
|
||||||
|
- 在 `received()` 回调里处理远端写进来的数据
|
||||||
|
- 调用 `bt_nus_send(conn, data, len)` 给远端发通知
|
||||||
|
- `bt_nus_get_mtu(conn)` 可拿到当前可用有效负载大小
|
||||||
|
|
||||||
|
和 Zephyr 版 NUS 的区别:
|
||||||
|
|
||||||
|
- Nordic 旧版更接近历史 NCS 示例代码
|
||||||
|
- API 更简单,通常单实例
|
||||||
|
- 如果项目已经基于 `peripheral_uart` 一类示例写的,通常继续沿用这个版本更省事
|
||||||
|
|
||||||
|
注意:
|
||||||
|
|
||||||
|
- **不要同时把 Zephyr NUS 和 Nordic 旧版 NUS 当成同一个业务通道一起开**,它们 UUID 相同,容易造成概念和实现混乱
|
||||||
|
|
||||||
|
### 4.2.11 Ranging Service, `RAS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/ras/rrsp/ras_rrsp.c`
|
||||||
|
- `nrf/include/bluetooth/services/ras.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
如果本机要作为**服务端/响应端**暴露 Ranging Service:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_RAS=y
|
||||||
|
CONFIG_BT_RAS_RRSP=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 服务端 RRSP 角色启用后会注册标准 Ranging Service
|
||||||
|
- 每个连接通常要先调用 `bt_ras_rrsp_alloc(conn)` 关联上下文
|
||||||
|
- 通过 `bt_ras_rd_buffer_cb_register()` 监听 ranging data buffer 生命周期
|
||||||
|
- 当有新的测距数据可提供时,使用数据缓冲 API:
|
||||||
|
- `bt_ras_rd_buffer_ready_check()`
|
||||||
|
- `bt_ras_rd_buffer_claim()`
|
||||||
|
- `bt_ras_rd_buffer_release()`
|
||||||
|
- `bt_ras_rd_buffer_bytes_pull()`
|
||||||
|
- 连接释放时调用 `bt_ras_rrsp_free(conn)`
|
||||||
|
|
||||||
|
补充说明:
|
||||||
|
|
||||||
|
- 同一个头文件里还提供 `RREQ` API,那是**客户端/请求端**使用的,不是本地服务端注册逻辑
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- BLE Channel Sounding / Ranging 实验与产品验证
|
||||||
|
|
||||||
|
### 4.2.12 Running Speed and Cadence Service, `RSCS`
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/rscs.c`
|
||||||
|
- `nrf/include/bluetooth/services/rscs.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_RSCS=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 填 `struct bt_rscs_init_params`
|
||||||
|
- `features`
|
||||||
|
- 支持的位置列表
|
||||||
|
- 当前位置
|
||||||
|
- 事件处理函数
|
||||||
|
- 控制点回调
|
||||||
|
- 调用 `bt_rscs_init(&init)`
|
||||||
|
- 生成新测量值时调用 `bt_rscs_measurement_send(conn, &measurement)`
|
||||||
|
|
||||||
|
控制点回调负责:
|
||||||
|
|
||||||
|
- `set_cumulative()`
|
||||||
|
- `calibration()`
|
||||||
|
- `update_loc()`
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 跑步传感器、脚环、步频速度设备
|
||||||
|
|
||||||
|
### 4.2.13 Throughput Service
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/throughput.c`
|
||||||
|
- `nrf/include/bluetooth/services/throughput.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_THROUGHPUT=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 定义 `struct bt_throughput throughput`
|
||||||
|
- 定义 `struct bt_throughput_cb`
|
||||||
|
- 调用 `bt_throughput_init(&throughput, &cb)`
|
||||||
|
|
||||||
|
如果本机作为服务端:
|
||||||
|
|
||||||
|
- 服务会被注册为一个测试用 Throughput Service
|
||||||
|
- 对端读/写该特征值时,你会在回调里拿到吞吐统计信息
|
||||||
|
|
||||||
|
如果本机作为客户端测试远端吞吐:
|
||||||
|
|
||||||
|
- 用 `bt_gatt_dm` 发现远端 Throughput Service
|
||||||
|
- 调用 `bt_throughput_handles_assign(dm, &throughput)`
|
||||||
|
- 然后用 `bt_throughput_read()` / `bt_throughput_write()` 发测试流量
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 链路性能压测
|
||||||
|
- MTU / DLE / PHY 参数实验
|
||||||
|
|
||||||
|
### 4.2.14 Wi-Fi Provisioning Service
|
||||||
|
|
||||||
|
源码位置:
|
||||||
|
|
||||||
|
- `nrf/subsys/bluetooth/services/wifi_prov/wifi_prov_ble.c`
|
||||||
|
- `nrf/include/bluetooth/services/wifi_provisioning.h`
|
||||||
|
- 配套核心库:`nrf/include/net/wifi_prov_core/wifi_prov_core.h`
|
||||||
|
|
||||||
|
启用方法:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
||||||
|
CONFIG_BT_WIFI_PROV=y
|
||||||
|
```
|
||||||
|
|
||||||
|
怎么用:
|
||||||
|
|
||||||
|
- 这个 BLE GATT 服务本身是 Wi-Fi Provisioning Core 的传输承载层
|
||||||
|
- 你真正要初始化的是 `wifi_prov_core`
|
||||||
|
- 典型流程:
|
||||||
|
1. 调用 `wifi_prov_init()`
|
||||||
|
2. 广告里带上 Provisioning Service UUID
|
||||||
|
3. 手机/配置工具向 Control Point 写 provisioning 请求
|
||||||
|
4. 核心库通过 `wifi_prov_send_rsp()` / `wifi_prov_send_result()` 把结果经 BLE 返回
|
||||||
|
|
||||||
|
适合场景:
|
||||||
|
|
||||||
|
- 设备本身有 Wi-Fi,但没有屏幕/键盘,需要靠手机配网
|
||||||
|
|
||||||
|
## 5. 哪些是客户端辅助库,不是本地服务端
|
||||||
|
|
||||||
|
下面这些模块也在 `services` 目录里,但它们主要是**Central 侧访问远端服务**用的,不是“本机注册一个 GATT Service”:
|
||||||
|
|
||||||
|
- `ams_client`
|
||||||
|
- `ancs_client`
|
||||||
|
- `bas_client`
|
||||||
|
- `cts_client`
|
||||||
|
- `dfu_smp`
|
||||||
|
- `gattp`
|
||||||
|
- `hogp`
|
||||||
|
- `hrs_client`
|
||||||
|
- `ias` 的 client API 部分
|
||||||
|
- `latency_client`
|
||||||
|
- `nus_client`
|
||||||
|
- `ots` 的 client API 部分
|
||||||
|
- `ras` 的 `RREQ` API 部分
|
||||||
|
|
||||||
|
如果你需要,我可以下一步单独再整理一份“**这些 client 库分别怎么发现远端服务、怎么订阅、怎么读写**”。
|
||||||
|
|
||||||
|
## 6. 对 `new_kbd` 项目的直接建议
|
||||||
|
|
||||||
|
如果目标是 BLE 键盘,优先级基本如下:
|
||||||
|
|
||||||
|
### 第一优先级
|
||||||
|
|
||||||
|
- `HIDS`:标准键盘主服务
|
||||||
|
- `BAS`:电量上报
|
||||||
|
- `DIS`:厂商/型号/版本
|
||||||
|
|
||||||
|
### 第二优先级
|
||||||
|
|
||||||
|
- `BMS`:如果你想让主机侧触发清配对
|
||||||
|
- `IAS` / `Proximity` 类思路:如果要做“找键盘”
|
||||||
|
- `TPS`:若你想暴露标准发射功率
|
||||||
|
|
||||||
|
### 通常不建议直接用于键盘主链路
|
||||||
|
|
||||||
|
- `NUS`:适合调试、配置通道,不适合作为系统键盘输入主协议
|
||||||
|
- `OTS`:太重
|
||||||
|
- `LBS`:示例用途
|
||||||
|
- `Throughput` / `Latency`:测试用途
|
||||||
|
|
||||||
|
## 7. 参考代码路径
|
||||||
|
|
||||||
|
你后面如果要继续落到工程实现,最值得先看的参考代码是:
|
||||||
|
|
||||||
|
- `C:\ncs\v3.2.3\nrf\samples\bluetooth\peripheral_hids_keyboard`
|
||||||
|
- `C:\ncs\v3.2.3\nrf\samples\bluetooth\peripheral_uart`
|
||||||
|
- `C:\ncs\v3.2.3\zephyr\samples\bluetooth\peripheral_nus`
|
||||||
|
- `C:\ncs\v3.2.3\zephyr\samples\bluetooth\peripheral_ots`
|
||||||
|
|
||||||
|
如果你要,我下一步可以继续给你补一份“**把这些 Service 映射到 `new_kbd` 当前代码结构的落地建议**”,直接对应你现在的 `ble_bond_module.c`、`ble_battery_module.c` 和后续 HIDS 模块拆分方式。
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
|
|
||||||
## 未纳入本索引的项目项
|
## 未纳入本索引的项目项
|
||||||
|
|
||||||
- `zephyr/drivers/power/ip5305.h`、`CONFIG_IP5305`:当前项目使用的是自定义驱动/自定义绑定,Zephyr 官方 latest 站点未核到对应官方页面,因此未纳入
|
- `zephyr/drivers/power/ip5306.h`、`CONFIG_IP5306`:当前项目使用的是自定义驱动/自定义绑定,Zephyr 官方 latest 站点未核到对应官方页面,因此未纳入
|
||||||
- `pm_static.yml` 对应的 Partition Manager 规划:属于 Nordic NCS 范畴,不属于 Zephyr 官方 docs 站点范围;Nordic 官方索引见 [nordic_ncs_官方知识索引.md](./nordic_ncs_官方知识索引.md)
|
- `pm_static.yml` 对应的 Partition Manager 规划:属于 Nordic NCS 范畴,不属于 Zephyr 官方 docs 站点范围;Nordic 官方索引见 [nordic_ncs_官方知识索引.md](./nordic_ncs_官方知识索引.md)
|
||||||
- `CAF`、`App Event Manager`、`settings_loader`、`ble_state`、`ble_common_event`、`power_manager`、`buttons_def.h` 等:属于 Nordic NCS/CAF 文档范围,不属于本 Zephyr 官方索引;Nordic 官方索引见 [nordic_ncs_官方知识索引.md](./nordic_ncs_官方知识索引.md)
|
- `CAF`、`App Event Manager`、`settings_loader`、`ble_state`、`ble_common_event`、`power_manager`、`buttons_def.h` 等:属于 Nordic NCS/CAF 文档范围,不属于本 Zephyr 官方索引;Nordic 官方索引见 [nordic_ncs_官方知识索引.md](./nordic_ncs_官方知识索引.md)
|
||||||
- 项目私有协议与实现,如时间同步私有 GATT 服务、主机 HID 命令协议、显示主题持久化逻辑等:只索引其依赖的 Zephyr 通用能力,不索引项目私有设计本身
|
- 项目私有协议与实现,如时间同步私有 GATT 服务、主机 HID 命令协议、显示主题持久化逻辑等:只索引其依赖的 Zephyr 通用能力,不索引项目私有设计本身
|
||||||
|
|||||||
5
prj.conf
5
prj.conf
@@ -62,6 +62,9 @@ CONFIG_BT_HIDS_FEATURE_REP_MAX=0
|
|||||||
CONFIG_BT_BAS=y
|
CONFIG_BT_BAS=y
|
||||||
CONFIG_BT_DIS=y
|
CONFIG_BT_DIS=y
|
||||||
CONFIG_BT_DIS_PNP=y
|
CONFIG_BT_DIS_PNP=y
|
||||||
|
CONFIG_BT_DIS_PNP_VID_SRC=2
|
||||||
|
CONFIG_BT_DIS_PNP_VID=0x1209
|
||||||
|
CONFIG_BT_DIS_PNP_PID=0x0001
|
||||||
|
|
||||||
CONFIG_USB_DEVICE_STACK_NEXT=y
|
CONFIG_USB_DEVICE_STACK_NEXT=y
|
||||||
CONFIG_USBD_HID_SUPPORT=y
|
CONFIG_USBD_HID_SUPPORT=y
|
||||||
@@ -89,7 +92,7 @@ CONFIG_CAF_BUTTONS_DEBOUNCE_INTERVAL=10
|
|||||||
|
|
||||||
CONFIG_ADC=y
|
CONFIG_ADC=y
|
||||||
CONFIG_I2C=y
|
CONFIG_I2C=y
|
||||||
CONFIG_IP5305=y
|
CONFIG_IP5306=y
|
||||||
CONFIG_SENSOR=y
|
CONFIG_SENSOR=y
|
||||||
CONFIG_DISPLAY=y
|
CONFIG_DISPLAY=y
|
||||||
CONFIG_MIPI_DBI=y
|
CONFIG_MIPI_DBI=y
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
#include <zephyr/drivers/power/ip5305.h>
|
#include <zephyr/drivers/power/ip5306.h>
|
||||||
#include <zephyr/drivers/sensor.h>
|
#include <zephyr/drivers/sensor.h>
|
||||||
#include <zephyr/pm/device.h>
|
#include <zephyr/pm/device.h>
|
||||||
#include <zephyr/sys/atomic.h>
|
#include <zephyr/sys/atomic.h>
|
||||||
@@ -32,7 +32,7 @@ LOG_MODULE_REGISTER(MODULE);
|
|||||||
#define BATTERY_EMPTY_MV 3300
|
#define BATTERY_EMPTY_MV 3300
|
||||||
#define BATTERY_FULL_MV 4100
|
#define BATTERY_FULL_MV 4100
|
||||||
|
|
||||||
static const struct device *const ip5305_dev = DEVICE_DT_GET(DT_NODELABEL(ip5305));
|
static const struct device *const ip5306_dev = DEVICE_DT_GET(DT_NODELABEL(ip5306));
|
||||||
static const struct device *const battery_sensor_dev = DEVICE_DT_GET(BATTERY_SENSE_NODE);
|
static const struct device *const battery_sensor_dev = DEVICE_DT_GET(BATTERY_SENSE_NODE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -164,19 +164,19 @@ static int board_power_monitor_read_voltage_mv(int32_t *voltage_mv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 从 IP5305 读取一次充电态与满电态。 */
|
/* 从 IP5306 读取一次充电态与满电态。 */
|
||||||
static int board_power_monitor_read_charge_state(bool *charging, bool *full)
|
static int board_power_monitor_read_charge_state(bool *charging, bool *full)
|
||||||
{
|
{
|
||||||
int err = ip5305_is_charging(ip5305_dev, charging);
|
int err = ip5306_is_charging(ip5306_dev, charging);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_WRN("ip5305_is_charging failed (err=%d)", err);
|
LOG_WRN("ip5306_is_charging failed (err=%d)", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ip5305_is_charge_full(ip5305_dev, full);
|
err = ip5306_is_charge_full(ip5306_dev, full);
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_WRN("ip5305_is_charge_full failed (err=%d)", err);
|
LOG_WRN("ip5306_is_charge_full failed (err=%d)", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,8 +305,8 @@ out_reschedule:
|
|||||||
/* 初始化 board power monitor consumer,并拉起首轮采样。 */
|
/* 初始化 board power monitor consumer,并拉起首轮采样。 */
|
||||||
static int battery_module_init(void)
|
static int battery_module_init(void)
|
||||||
{
|
{
|
||||||
if (!device_is_ready(ip5305_dev)) {
|
if (!device_is_ready(ip5306_dev)) {
|
||||||
LOG_ERR("IP5305 device not ready");
|
LOG_ERR("IP5306 device not ready");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,11 @@
|
|||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
#include <zephyr/drivers/sensor.h>
|
#include <zephyr/drivers/sensor.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/pm/device.h>
|
||||||
|
#include <zephyr/sys/atomic.h>
|
||||||
|
|
||||||
#include <app_event_manager.h>
|
#include <app_event_manager.h>
|
||||||
|
#include <caf/events/power_event.h>
|
||||||
|
|
||||||
#define MODULE qdec
|
#define MODULE qdec
|
||||||
#include <caf/events/module_state_event.h>
|
#include <caf/events/module_state_event.h>
|
||||||
@@ -24,6 +27,7 @@ struct qdec_ctx {
|
|||||||
const struct device *dev;
|
const struct device *dev;
|
||||||
struct sensor_trigger trigger;
|
struct sensor_trigger trigger;
|
||||||
struct k_work_delayable emit_work;
|
struct k_work_delayable emit_work;
|
||||||
|
atomic_t active;
|
||||||
int32_t acc_deg;
|
int32_t acc_deg;
|
||||||
bool emit_scheduled;
|
bool emit_scheduled;
|
||||||
};
|
};
|
||||||
@@ -36,8 +40,31 @@ static struct qdec_ctx qdec = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void qdec_reset_state(void)
|
||||||
|
{
|
||||||
|
qdec.acc_deg = 0;
|
||||||
|
qdec.emit_scheduled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qdec_device_set_enabled(bool enable)
|
||||||
|
{
|
||||||
|
int err = pm_device_action_run(qdec.dev,
|
||||||
|
enable ? PM_DEVICE_ACTION_RESUME :
|
||||||
|
PM_DEVICE_ACTION_SUSPEND);
|
||||||
|
|
||||||
|
if ((err == 0) || (err == -EALREADY)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static void schedule_emit_work(void)
|
static void schedule_emit_work(void)
|
||||||
{
|
{
|
||||||
|
if (!atomic_get(&qdec.active)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (qdec.emit_scheduled) {
|
if (qdec.emit_scheduled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -52,6 +79,11 @@ static void qdec_emit_work_handler(struct k_work *work)
|
|||||||
|
|
||||||
ARG_UNUSED(work);
|
ARG_UNUSED(work);
|
||||||
|
|
||||||
|
if (!atomic_get(&qdec.active)) {
|
||||||
|
qdec.emit_scheduled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
qdec.emit_scheduled = false;
|
qdec.emit_scheduled = false;
|
||||||
|
|
||||||
if ((qdec.acc_deg < QDEC_DEG_PER_STEP_EVENT) &&
|
if ((qdec.acc_deg < QDEC_DEG_PER_STEP_EVENT) &&
|
||||||
@@ -83,6 +115,10 @@ static void qdec_data_handler(const struct device *dev,
|
|||||||
|
|
||||||
ARG_UNUSED(trigger);
|
ARG_UNUSED(trigger);
|
||||||
|
|
||||||
|
if (!atomic_get(&qdec.active)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
err = sensor_sample_fetch_chan(dev, SENSOR_CHAN_ROTATION);
|
err = sensor_sample_fetch_chan(dev, SENSOR_CHAN_ROTATION);
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_ERR("QDEC sample fetch failed: %d", err);
|
LOG_ERR("QDEC sample fetch failed: %d", err);
|
||||||
@@ -113,8 +149,8 @@ static int qdec_init(void)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdec.acc_deg = 0;
|
qdec_reset_state();
|
||||||
qdec.emit_scheduled = false;
|
atomic_set(&qdec.active, false);
|
||||||
k_work_init_delayable(&qdec.emit_work, qdec_emit_work_handler);
|
k_work_init_delayable(&qdec.emit_work, qdec_emit_work_handler);
|
||||||
|
|
||||||
err = sensor_trigger_set(qdec.dev, &qdec.trigger, qdec_data_handler);
|
err = sensor_trigger_set(qdec.dev, &qdec.trigger, qdec_data_handler);
|
||||||
@@ -129,6 +165,46 @@ static int qdec_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qdec_module_suspend(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!atomic_get(&qdec.active)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic_set(&qdec.active, false);
|
||||||
|
(void)k_work_cancel_delayable(&qdec.emit_work);
|
||||||
|
qdec_reset_state();
|
||||||
|
|
||||||
|
err = qdec_device_set_enabled(false);
|
||||||
|
if (err) {
|
||||||
|
LOG_WRN("QDEC suspend failed: %d", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_set_state(MODULE_STATE_STANDBY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qdec_module_resume(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (atomic_get(&qdec.active)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = qdec_device_set_enabled(true);
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("QDEC resume failed: %d", err);
|
||||||
|
module_set_state(MODULE_STATE_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdec_reset_state();
|
||||||
|
atomic_set(&qdec.active, true);
|
||||||
|
module_set_state(MODULE_STATE_READY);
|
||||||
|
}
|
||||||
|
|
||||||
static bool app_event_handler(const struct app_event_header *aeh)
|
static bool app_event_handler(const struct app_event_header *aeh)
|
||||||
{
|
{
|
||||||
if (is_module_state_event(aeh)) {
|
if (is_module_state_event(aeh)) {
|
||||||
@@ -140,16 +216,28 @@ static bool app_event_handler(const struct app_event_header *aeh)
|
|||||||
if (err) {
|
if (err) {
|
||||||
module_set_state(MODULE_STATE_ERROR);
|
module_set_state(MODULE_STATE_ERROR);
|
||||||
} else {
|
} else {
|
||||||
module_set_state(MODULE_STATE_READY);
|
qdec_module_resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_power_down_event(aeh)) {
|
||||||
|
qdec_module_suspend();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_wake_up_event(aeh)) {
|
||||||
|
qdec_module_resume();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
__ASSERT_NO_MSG(false);
|
__ASSERT_NO_MSG(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
||||||
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
||||||
|
APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);
|
||||||
|
|||||||
Reference in New Issue
Block a user