【中科蓝讯】TWS 耳机提示音是怎样播放出来的

在 TWS 耳机里,开机、蓝牙连接、低电量和降噪模式切换,通常都会伴随一段提示音。 从表面看,提示音像是准备一个音频文件,需要时调用播放函数即可。实际上,一段提示音从代码触发到左右耳真正出声,中间还要经过资源查找、播放排队、双耳同步和音频恢复。 本文以中科蓝讯 BT891x 原厂 SDK 的实现为例,重点分析提示音播放的核心流程。不同 SDK 的接口名称可能不一样,但整体思路通常可以互相参考。 一、提示音播放的完整链路 一段提示音的完整流程,可以先简化成下面五步: %%{init: {"flowchart": {"htmlLabels": true, "wrappingWidth": 1000, "rankSpacing": 30}, "themeVariables": {"lineColor": "#71829a"}}}%% flowchart TB subgraph R0["① 准备播放请求"] direction LR R0N0["业务触发"] R0N1["找到对应的提示音资源"] R0N2["把播放请求加入队列"] R0N0 --> R0N1 --> R0N2 end class R0N0,R0N1,R0N2 blue; style R0 fill:#f1f6fd,stroke:#b8cfe8,color:#23456b subgraph R1["② 同步与播放"] direction LR R1N0["确定哪只耳机播放<br/>并完成双耳同步"] R1N1["解码播放<br/>结束后恢复原来的音频状态"] R1N0 --> R1N1 end class R1N0,R1N1 green; style R1 fill:#f0f8f3,stroke:#b9d7c4,color:#24563a R0 --> R1 classDef blue fill:#e8f2ff,stroke:#7ba4d8,color:#23456b,stroke-width:1.5px; classDef green fill:#e7f4ec,stroke:#78aa8b,color:#24563a,stroke-width:1.5px; classDef amber fill:#fff3df,stroke:#d5a25b,color:#72501e,stroke-width:1.5px; 比如手机连接耳机成功以后,蓝牙业务只需要提出“播放连接成功提示音”这个请求。至于提示音文件放在哪里、左右耳什么时候开始播放、当前音乐要不要降低音量,都会继续交给提示音模块处理。 ...

【中科蓝讯】TWS 按键问题单复盘

一、写在开始 我参与的是一款基于中科蓝讯 BT8910 的 TWS 耳机品牌项目,目前这个项目已经完成。 项目结束后,我想把开发过程中接触到的 Jira 问题单重新梳理一遍。其中既有我参与处理的内容,也有同事负责的模块。 现在查一个函数、一个配置项并不难,真正值得记录的是:面对一个问题现象时,应该先判断哪一层,为什么往这个方向查,以及怎么通过日志一步步缩小范围。 所以这次复盘不是给出一套标准答案,而是站在我目前对应用层的理解上,把问题现象、判断过程和排查思路整理下来,供遇到类似问题的同学参考。 整理过程中我还发现,很多反馈看起来不一样,根因却有重复。按根因归类后,下次遇到类似现象时,就可以先判断问题属于哪个环节,再沿对应链路往下查。 后续我会继续按模块整理项目中的问题单,包括按键、提示音、机盒通信、ANC、音量控制、功耗管理、出入盒、双耳同步、蓝牙问题和连接问题等内容。这一篇先从按键开始,归纳其中比较常见的 4 类问题。 阅读提示 全文约 2 300 字,预计 10 分钟读完。 本文包含 4 类按键问题:完全无响应、场景功能错误、误触,以及复杂手势互相干扰。重点不是讲基础原理,而是遇到类似反馈时,应该先查哪里、再往哪里查。 本文只讨论按键链路本身。如果按键已经触发正确功能,只是提示音没有播放或播放不对,就归到后续的提示音问题中。 二、所有手势都没有反应 客户反馈 其中一只耳机的触控按键完全无效,双击、三击、长按都没有反应。 排查思路 第一步:确认触控输入 先看这只耳机的触控按键是否有按下、松开的日志。 没有日志:先查这个触控按键的输入本身,例如触控是否启用、耳机是否在盒内、是否正处于禁键时间、触控阈值或通道是否正常。 有日志:说明这个触控按键已经有输入,继续往下查。 第二步:确认手势识别 再看目标手势有没有识别出来。 没有识别出来:重点查双击间隔、长按时间、松手后状态是否复位,以及组合手势是否把普通手势挡住了。 识别出来:说明手势已经产生,继续看功能。 第三步:确认功能消息 最后看手势有没有转换成正确的功能消息。 没有、为空或错误:查按键定义、场景切换和配置更新。 有正确消息:再确认功能处理是否执行;如果功能已经执行,后面只是没有提示音,就属于提示音问题,不再按按键问题处理。 判断与处理 “完全无效”不一定是触控硬件问题,也可能是手势已经产生、但后面没有正确链接到功能。处理时不要一开始就调灵敏度或改功能定义,先通过日志确认问题停在哪一层。 三、同一手势,功能却错了 客户反馈 听歌时双击正常,来电时双击却不能接听或挂断。 长按在听歌时能切换功能,到响铃或通话时却失效。 App 改完触控后,耳机执行的功能不对。 排查思路 第一步:固定一个场景复现 只测听歌、只测来电响铃,或只测通话,避免混在一起判断。 第二步:确认手势已经识别 如果手势都没出来,回到第一类问题排查。 第三步:核对当前场景的功能 手势正常后,直接看耳机最后想执行的是什么功能。 同样是“双击”:听歌时可能是切歌,来电时应该是接听或拒接,通话中又可能是其他操作。 来电时双击却去切歌:说明双击识别没有问题,只是耳机还在按“听歌时的规则”处理。 只有通话异常:重点检查进入通话后,双击和长按是否已经改成通话时该做的功能。 App 改完才异常:重点检查新设置是否把听歌、来电或通话时的功能改错了。 判断与处理 听歌、来电响铃、通话时都可以识别同一个“双击”或“长按”,但后续要执行的功能并不相同。 这类问题通常是耳机没有按当前使用状态执行对应功能。处理重点是把每种状态下的功能对应关系确认清楚。 四、不该响应时仍然响应 客户反馈 耳机放在盒内还能切歌;刚出盒或拿取耳机时,容易误触切换功能。 排查思路 第一步:确认误触发生的时机 ...

【中科蓝讯】TWS 耳机按键处理流程

上一篇已经把 SDK 的几个核心概念过了一遍,包括模式状态机、process/message/display 和消息分层。 这一篇就拿按键功能做一次具体分析,从一个按键事件出发,一直追到最终执行的位置。 以我接触到的 TWS 项目来看,按键是应用层里相对好理解、也比较容易上手的一部分:改单击功能、加长按、加多击,或者调整不同模式下的按键行为。这些需求在 SDK 里都对应到同一套机制,弄懂之后,定位修改位置会更快。 一、先跑一遍完整链路 一个按键从手指按下到功能执行,在 SDK 里走了这几步: %%{init: {"flowchart": {"htmlLabels": true, "wrappingWidth": 1000, "rankSpacing": 30}, "themeVariables": {"lineColor": "#71829a"}}}%% flowchart TB subgraph R0["① 输入与识别"] direction LR R0N0["手指按下<br/>用户触发按键"] R0N1["硬件扫描<br/>读取按键编号"] R0N2["消抖 / 识别<br/>判断短按、长按、多击"] R0N0 --> R0N1 --> R0N2 end class R0N0,R0N1,R0N2 blue; style R0 fill:#f1f6fd,stroke:#b8cfe8,color:#23456b subgraph R1["② 消息与业务"] direction LR R1N0["查按键表<br/>找到对应消息"] R1N1["消息入队<br/>放入消息队列"] R1N2["模式分发<br/>按当前模式处理"] R1N3["功能执行<br/>播放、切歌、接听等"] R1N0 --> R1N1 --> R1N2 --> R1N3 end class R1N0,R1N1,R1N2,R1N3 green; style R1 fill:#f0f8f3,stroke:#b9d7c4,color:#24563a R0 --> R1 classDef blue fill:#e8f2ff,stroke:#7ba4d8,color:#23456b,stroke-width:1.5px; classDef green fill:#e7f4ec,stroke:#78aa8b,color:#24563a,stroke-width:1.5px; classDef amber fill:#fff3df,stroke:#d5a25b,color:#72501e,stroke-width:1.5px; 前两步主要回答“这个按键物理上发生了什么”。从第 3 步开始,软件才把按键行为转换成功能。 ...

【中科蓝讯】聊聊我对这套SDK的理解

前两篇记录了环境搭建和 com/bank 内存的事。这篇主要想讲一下中科蓝汛的 SDK——不讲具体细节,也不列目录结构,每个项目的目录可能都不太一样,列了也没太大意义。主要是聊一下我对这套 SDK 几个核心概念的理解。以后不管拿到哪个版本、做什么功能,这几个概念应该都不会变。 一、SDK 就是一个"模式状态机" 这是做完项目之后最大的感受。一颗 TWS 耳机芯片,任何时候只处于一个"模式"——蓝牙模式、充电模式、IDLE 待机、关机。切模式就是改一个变量 func_cb.sta。 // func_run() —— 整个 SDK 的主循环就长这样 while (1) { func_enter(); switch (func_cb.sta) { case FUNC_BT: func_bt(); break; // 蓝牙 case FUNC_CHARGE: func_charge(); break; // 充电 case FUNC_IDLE: func_idle(); break; // 待机 case FUNC_PWROFF: func_pwroff(); break; // 关机 default: func_exit(); break; // 退出,切下一个 } } 虽然每个模式做的事情不一样,但内部结构都有共同点。拿蓝牙模式看: void func_bt(void) { func_bt_enter(); // 进来先初始化 while (func_cb.sta == FUNC_BT) { // 没切模式就一直在这转 func_bt_process(); // 轮询事件 func_bt_message(msg_dequeue()); // 处理消息 func_bt_display(); // 刷新显示 } func_bt_exit(); // 走之前收尾 } 就是 enter → while → process/message/display → exit。再看 idle 模式,几乎一模一样——func_idle_enter() → while(func_cb.sta == FUNC_IDLE) → process/message/display → 退出。充电和关机模式虽然内部细节不同,但也是 enter → 做事 → exit 这个三段式。 ...

【中科蓝讯】从两次偶发死机,理解 com 区和 bank 区

刚接触中科蓝讯 SDK 时,我经常看到函数前面有 AT(.com_text.xxx)。一开始我只知道照着原有代码写,却不明白它为什么在这里。后来看了资料和工程里的写法,我才认识到:SDK 把代码分区域存放,不同区域的运行方式不一样。 这篇只是我目前从应用侧整理的一点理解,重点放在看到 AT(...) 时怎么读。 一、com 区和 bank 区有什么区别 按照官方资料的说明,芯片上电后,一部分代码会从 Flash 搬到 RAM 里常驻下来,这部分就是 com 区;剩下的代码继续待在 Flash,用到时才被加载到 bank 运行区。 区域 简单理解 适合放什么 com 区 上电后会加载到 RAM,并在运行期间常驻 中断函数、实时性要求高的 bank 区 代码存在 Flash,运行时按需加载到 bank 运行区 大多数普通应用逻辑 com 区的空间有限,所以不要因为更快,就把普通功能都放进去。 二、真正要注意的是中断和它调用的函数 中断函数和它调到的关键函数,通常需要放在 com 区。因为中断来了要马上处理,不能等到需要时再去加载代码。 在工程里看定时和一些中断相关代码时,我能看到类似下面的写法: AT(.com_text.user) void user_timer_isr(void) { // 中断中的处理 } 实际用的时候,我是先看同模块已有代码的写法,不凭空猜。但照抄还不够——踩过两次坑才知道,光盯着函数本身的 AT,容易漏掉更深层的依赖。 第一次是在中断里调了一个普通函数,我给那个函数加了 AT(.com_text.xxx),以为这就完事了。结果还是偶发异常。排查后发现,这个函数内部又调了另一个普通函数,那个子函数没加 AT。中断触发时 CPU 跳到 com 区,执行到嵌套的子函数时,它的代码还在 bank 区没加载进来,一样挂。这件事的风险在于,被调函数可能还调了其他函数,嵌套几层之后很容易漏掉。所以给函数加 AT 时,得顺着调用链往下检查,确保整条执行路径上的函数都在 com 区。如果调用深度比较大,更稳妥的做法是通过消息转发把逻辑放到其他线程执行,避免在 com 区里越套越深。 ...

【中科蓝讯】SDK 环境搭建与烧录

以我最近实际接触的中科蓝讯 BT891x 项目为例,刚开始最先要做的就是把开发环境搭起来:准备资料和工具、打开工程、编译生成 app.dcf,再用 Downloader 完成后续烧录。 不同 SDK 版本和开发板的目录、工具版本可能不一样,最终以当前资料包和工程说明为准。 一、准备资料和工具 如果手上的 SDK 对应特定的 TWS 开发板,原理图和相关硬件资料也要一并保存好,后面核对硬件配置、下载和外设问题时都会用到。 刚开始做 BT891x 时,主要先准备下面四项资料和工具: 内容 先拿它做什么 BT891x 固件 SDK 后续的功能开发主要就在这里进行 CodeBlocks 开发环境 打开 .cbp 工程并发起编译 RV32 Toolchain 供 CodeBlocks 调用的 RISC-V 编译工具链 Downloader 读取 app.dcf,进行配置和烧录处理 如果当前使用的是串口下载方式,还要保留蓝讯提供的串口驱动。资料包里的驱动通常以 CP210x 驱动包的形式提供,用于让电脑识别 CP2102 或 XLink 模块对应的 COM 口。 CodeBlocks 和 RV32 Toolchain 都是双击安装程序后,按提示一路选择 Next、默认路径安装即可。CodeBlocks 用来打开 .cbp 工程并编译,RV32 Toolchain 是真正执行编译的工具。 如果使用串口下载,按当前下载器对应的驱动安装即可。下载器和设备接入电脑后,系统能够识别出 COM 口,Downloader 才能继续扫描设备。 Downloader 不需要安装,解压后直接运行 Downloader.exe 即可。 二、编译与烧录 环境装完后,我不会马上改功能,而是先在 CodeBlocks 中打开 SDK 里的 .cbp 工程并编译一次。 ...

一副 TWS 耳机,为什么既要用经典蓝牙,又要用 BLE

做 TWS 耳机时,经常会同时看到经典蓝牙和 BLE。 手机已经通过蓝牙连接耳机,可以播放音乐、接打电话,为什么配套 App 还要再连接一次 BLE?我刚开始接触时,也没有认真区分这两部分,只知道它们都叫蓝牙。 后来做 App 交互功能多了,我才慢慢理解:在目前常见的 TWS 产品里,它们处理的事情并不一样。经典蓝牙主要负责音乐、通话和媒体控制,BLE 更像一条给 App 使用的数据通道。 一、经典蓝牙主要负责耳机的基本功能 平时用耳机听歌、调节音量和接打电话,主要涉及经典蓝牙中的几个 Profile: Profile 在耳机中的主要作用 A2DP 传输音乐音频 AVRCP 播放、暂停、切歌和音量控制 HFP 来电、接听、挂断等通话控制 通话时的语音通常还会通过 SCO/eSCO 链路传输。 这些功能决定了一副耳机能不能正常听歌和通话。以我目前接触到的应用开发来说,平时主要处理 SDK 上报的 A2DP、AVRCP 和 HFP 事件,再根据当前状态执行对应的产品逻辑。 二、BLE 主要负责耳机与 App 交互 配套 App 需要做的事情和播放音乐不太一样。它传输的通常不是连续音频,而是一些控制命令和状态数据。 我做过的项目里,BLE 主要用于这些功能: 修改 EQ; 切换 ANC 模式; 读取耳机电量; OTA 升级; 查找耳机。 例如用户在 App 上切换 ANC,App 会通过 BLE 把命令发给耳机;耳机执行以后,还可能需要把最新状态返回给 App。读取电量也是类似的过程,只是数据方向和触发时机可能不同。 我接触过 GATT 的 Service、Characteristic、读写和通知,不过实际开发时,大部分数据收发还是通过 SDK 封装好的接口完成。刚开始看这些名词时,我觉得它们比较抽象。结合 TWS 耳机的功能,可以先这样理解: ...

做耳机开发,需要掌握哪些 C 语言知识

TWS 应用层的大部分工作,最后还是要落到 C 代码上。这篇整理开发中经常用到、也容易混淆的内容,方便需要时快速回顾。 一、数据类型与类型转换 嵌入式代码经常使用 uint8_t、uint16_t 和 uint32_t,因为它们的位宽是明确的。 int 占多少字节,由芯片架构和编译器决定。在常见的 32 位平台上,int 通常占 4 字节;在部分嵌入式平台上,也可能只占 2 字节。可以使用 sizeof 查看当前平台上的实际大小: printf("int size: %u\n", (unsigned int)sizeof(int)); sizeof 返回的是 size_t 类型。这里先把结果转换成 unsigned int,再使用 %u 输出,适合常见的嵌入式 printf。 普通计算和循环计数可以使用 int。通信协议、Flash 数据、文件格式和寄存器字段需要明确长度时,优先使用固定位宽类型。 类型转换主要注意下面几种情况: 情况 需要注意什么 大类型转小类型 高位可能被截断 有符号转无符号 负数会变成很大的正数 无符号与有符号比较 有符号数可能先被转成无符号数 指针类型转换 只改变读取内存的方式,不会改变原来的数据 注意:有符号数和无符号数比较前,尽量把两边统一成合适的类型。进行指针类型转换时,要确认原内存长度不小于目标类型的大小。例如原数据只有 1 字节,转换成 uint32_t * 后却按照 4 字节读取,就会读到不属于它的内存。 二、指针、数组与生命周期 指针保存的是地址。使用前主要检查四件事: 指针是否为空。 指向的内存是否仍然有效。 访问长度是否越界。 指针指向的数据类型是否正确。 void update_state(uint8_t *state) { if (state == NULL) { return; } *state = 1; } 数组传入函数后通常会退化成指针,函数内部无法再通过 sizeof 得到原数组长度。因此传递缓冲区时,最好同时传入长度。 ...

做 TWS 应用开发,到底需不需要懂协议栈

刚接触 TWS 应用开发时,我一直有一个疑问:蓝牙协议栈大部分已经由芯片原厂封装好了,平时做功能主要是调用 SDK 接口、处理事件和编写产品逻辑,还有没有必要专门学习协议栈? 刚入行的时候,我也尝试过从头学习蓝牙协议。当时下载了一份 Bluetooth Core Specification 6.0,打开后看到整整 3815 页,心里压力一下就上来了。里面有大量英文术语、状态、命令和数据包格式,我硬着头皮看了几天,还是很难把规范里的内容和手上的代码对应起来,最后没有坚持下去。 工作两年左右,我对协议栈内部仍然谈不上有多深入的理解,平时接触最多的还是应用层代码。所以我现在的看法是:**需要了解一些,但没必要一开始钻得特别深。**这篇文章只是记录我目前在项目中用到的一些认识。 一、我目前主要关注什么 以我目前的工作内容来说,HCI、L2CAP 以及各个 Profile 的内部状态机,我其实没有深入研究。日常开发更常见的是调用 SDK 接口、接收事件,再根据产品状态处理业务。 为了不把不同问题混在一起,我会先记住几个和工作直接相关的区别: ACL 连接和 Profile 连接不是一回事。 A2DP 负责音乐,AVRCP 负责播放控制和音量同步。 HFP 负责通话控制,SCO/eSCO 承载通话语音。 SPP 和 BLE GATT 常用于 App 数据通信。 接口调用成功,不一定代表异步操作已经完成,还要等待后续事件。 为了更直观地区分这些连接和业务,可参考蓝牙连接关系简化图: 图中把 GATT 单独放在 BLE 连接下。严格来说,协议内部的承载关系还要更细,这里只保留我在应用开发中经常接触到的部分。 我目前也就是先把这些常见概念分清。这样遇到异常时,至少知道先看哪一类状态,不至于一上来就把所有现象都归结成“蓝牙有问题”。 二、实际项目里,我能接触到什么 以我使用的中科蓝讯 bt8910 SDK 为例,工程里可以看到 A2DP、HFP、SPP 和 TWS 相关的配置及适配代码,但真正的核心实现主要由预编译的 libbtstack.a 提供。 应用层这边,A2DP 和 HFP 主要是调整部分参数、接收事件和处理业务回调;SPP 的 SDP Record 和数据收发回调可以看到并修改;GATT 可以添加 Service、Characteristic 和读写回调;TWS 这边则能做一些业务状态同步和主从切换处理。 ...

一副 TWS 耳机里,有哪些软件模块

一、先看整体 如果暂时不考虑具体芯片平台,TWS 耳机的软件大致可以分成下面几个部分: 这不是严格的分层架构。实际 SDK 中,各部分往往会互相调用,甚至放在同一个模块里。这样划分主要是为了看清楚:一个耳机功能背后,通常有哪些软件在配合。 软件模块 主要负责什么 常见内容 系统与 RTOS 让程序和多个任务运行起来 任务、消息、定时器、内存、看门狗 驱动与电源 与耳机硬件交互 GPIO、ADC、I2C、I2S、充电、休眠、唤醒 蓝牙连接 与手机建立和维护蓝牙业务 配对、回连、A2DP、AVRCP、HFP、BLE 双耳协同 让左右耳保持一致 双耳组对、角色、状态同步、音频协同 音频系统 管理声音输入和输出 编解码、播放、录音、提示音、ANC、ENC 产品应用 决定耳机具体怎样工作 按键、LED、佩戴检测、状态机、功能优先级 数据与升级 保存配置并更新固件 配对记录、用户设置、OTA、版本管理 调试与测试 帮助发现和定位问题 日志、异常信息、测试模式、量产支持 二、系统与 RTOS TWS 耳机一般不是从上到下只执行一条固定流程。蓝牙事件、按键、音频、充电和定时任务可能在不同时间发生,因此软件需要同时管理多种事情。 这一部分通常包括: 系统启动和各模块初始化 任务或线程的创建与调度 事件、消息和队列 软件定时器 内存分配与任务栈 中断处理 看门狗和异常恢复 应用层开发中经常接触到的,并不是 RTOS 调度器本身,而是平台提供的任务、消息和回调接口。 例如,按键驱动检测到一次双击后,不一定会直接执行“切换降噪模式”。它可能先产生按键事件,再把事件投递给应用任务,最后由应用代码根据当前状态决定是否执行这个功能。 所以,当我们阅读一个新 SDK 时,找到事件入口和消息流转路径很重要。 三、硬件驱动与电源管理 耳机虽然体积不大,但里面仍然有不少硬件。软件需要通过不同接口读取状态或者控制这些器件。 常见内容包括: GPIO:NTC供电、LED、使能信号 ADC:按键电压、其他模拟量 UART:日志输出、机盒 充电与盒仓检测:识别 DC、入盒、出盒、开盖、关盖、充电和满电等状态 佩戴检测:红外、触摸或其他传感器 I2C、SPI:传感器、外部芯片或存储器 I2S、PCM:数字音频数据传输 驱动层负责把硬件状态转换成软件可以识别的数据或事件,应用层再决定怎样处理。 “耳机入盒”背后涉及盒仓状态检测、TWS 对耳同步、按键禁用、ANC 和音乐处理、DAC 控制及主从切换;关盖后还要关闭蓝牙并进入 FUNC_IDLE或 charge等其他模式。处理不完整,可能导致左右耳状态不一致、盒内仍播放声音或关盖后仍连接手机。 ...

蓝牙核心系统架构介绍

一、蓝牙的两种模式 (1)经典蓝牙(BR/EDR) 用于高数据速率应用,如无线耳机、音箱、键盘。 特点是连接稳定,适合持续传输音频或大量数据。 (2)低功耗蓝牙(BLE) 专为低功耗设备设计,如智能手环、温度计、传感器。 特点是耗电低,适合间歇性传输小数据。 总结:两种模式底层都用无线信号传输数据,都遵循蓝牙协议,只是侧重点不同。经典蓝牙重视速度和稳定,BLE重视省电和简单连接。 二、蓝牙核心系统组成 蓝牙核心系统由主机(Host)和控制器(Controller)两部分组成。 主机负责高层协议和控制逻辑,控制器处理底层射频和信号传输。两者分工合作,设备才能正常工作。 三、主机部分(Host) 主机包含多个协议模块,经典蓝牙和BLE有所不同。 经典蓝牙主要模块: GAP(通用访问协议):管理设备发现和连接建立。 SDP(服务发现协议):帮助设备发现对方支持的服务。 L2CAP(逻辑链路控制协议):管理数据流,负责数据分段和重组。 SMP(安全管理协议):负责加密连接和密钥管理。 BLE主要模块: GAP(通用访问协议):管理设备发现和连接建立。 GATT(通用属性协议):规定设备如何描述和交换数据属性。 ATT(属性协议):按照GATT规则传输数据。 SMP(安全管理协议):负责加密连接和密钥管理。 经典蓝牙工作流程: GAP搜索附近设备并建立连接 SDP查找对方支持的服务 L2CAP处理数据传输,分段重组 SMP管理密钥和加密 BLE工作流程: GAP搜索附近设备并建立连接 GATT列出设备支持的服务和数据属性 ATT按照GATT规定格式传送数据 SMP保障连接和数据安全 四、控制器部分(Controller) 控制器处理蓝牙底层功能,直接与硬件交互。 主要模块: LL(链路层):管理蓝牙设备的链路状态和数据包传输。 RF(射频层):处理蓝牙信号的发送和接收。 IAL(等时音频层):BLE特有,处理高实时性数据传输,例如音频。 控制器主要负责: 链路管理:连接的建立、维持、断开。 无线信号传输:信号调制解调、频率管理、纠错编码。 硬件交互:直接控制无线电模块发射和接收。 五、HCI(主机控制器接口) HCI是连接主机和控制器的桥梁,负责两部分之间通信。 特点: 标准化接口,让不同厂商的设备互相兼容。 传输命令、事件和数据包。 举例:手机的应用层通过HCI命令告诉蓝牙芯片"开始扫描附近设备",芯片执行后通过HCI事件返回扫描结果。 六、双模蓝牙 双模蓝牙同时支持经典蓝牙和BLE,一个设备两种能力 硬件层面同时支持BR/EDR和BLE。软件层面整合经典蓝牙和BLE的高层协议。 支持经典蓝牙的SDP和BLE的GATT,灵活切换。 举例:手机可以同时连接蓝牙耳机(经典蓝牙)和智能手环(BLE) 七、总结 经典蓝牙和BLE虽然侧重不同,但架构相似:都是主机管逻辑,控制器管硬件,通过HCI通信 经典蓝牙适合持续大数据传输,BLE适合低功耗间歇传输。 双模设备兼具两种能力,应用更广泛。 原文:CSDN · 蓝牙核心系统架构介绍

BLE设备地址介绍

什么是BLE设备地址 BLE设备地址48位长度,用来识别低功耗蓝牙设备。 地址分为公共地址和随机地址两大类,现代BLE设备为保护隐私,很少直接用公共地址广播。 注意:BLE地址和经典蓝牙地址虽然都是48位,但机制不同。 一、公共设备地址 由IEEE官方分配,全球唯一,永久不变。 常见设备:早期蓝牙键盘、鼠标。 优点:全球唯一,不会冲突。 缺点:申请要钱,容易被追踪定位。 地址结构:通常前3字节是厂商代码,后3字节厂商自己分配,也可以自定义。 举例:00:1A:7D:12:34:56 00:1A:7D = 苹果厂商代码 12:34:56 = 苹果内部设备序号 二、随机设备地址 BLE随机设备地址,设备自己生成,分三种: 1. 静态随机地址 开机时随机生成,本次开机内不变,重启后重新生成。 地址特征:最高两位为"11",地址C0-FF开头。 常见设备:智能手环、体重秤、温度计。 优点:免费,开机内稳定连接。 缺点:设备多了可能冲突,重启后地址变化可能影响自动重连。 2. 可解析私有地址 BLE隐私保护核心。地址定期变化(通常15分钟),配对过的设备可通过IRK密钥识别真实身份。 地址特征:最高两位为"01",地址40-7F开头。 常见设备:iPhone、Apple Watch、Android手机、AirPods。 工作原理:设备用IRK密钥生成临时地址,配对设备存有IRK可验证身份,陌生设备只看到随机地址。 举例:商场里手机地址每10分钟变一次,商家无法追踪你。但AirPods能认出你的手机,因为有共享密钥。 优点:防位置追踪,不影响已配对设备连接。 缺点:需要密钥管理和地址解析算法。 3. 不可解析私有地址(NRPA) 完全随机临时地址,任何设备都无法识别。 地址特征:最高两位为"00",地址00-3F开头 常见场景:BLE Beacon广播、一次性数据推送。 举例:商场Beacon广播促销信息,路人收到即可,无需连接和识别。 优点:最强隐私保护。 缺点:无法建立连接,只能单向广播。 三、应用场景对比 蓝牙键盘鼠标:公共地址,稳定识别。 智能手环体重秤:静态随机地址,成本低。 iPhone和智能手表:可解析私有地址,防追踪。 BLE Beacon:不可解析私有地址,一次性推送。 四、BLE和经典蓝牙地址区别 经典蓝牙主要用公共地址,很少变化。 BLE主流用随机地址(特别是可解析私有地址),定期变化保护隐私。 同一设备可能同时有经典蓝牙地址和BLE地址,它们独立。 BLE地址最高2位标识类型,经典蓝牙没有。 五、实用知识 查看BLE地址(Android):设置→关于手机→状态信息→蓝牙地址。 手机地址为什么总变?现代手机用可解析私有地址,每10-15分钟换一次,防止被追踪。 识别地址类型看第一字节: C0-FF:静态随机 40-7F:可解析私有 00-3F:不可解析私有 其他:公共地址 总结: BLE地址虽然分为四类,但一般都使用随机地址,在开发中 小型外设一般用静态随机,简单省钱 手机可穿戴一般用可解析私有,保护隐私 广播类一般用不可解析私有,单向推送 原文:CSDN · BLE设备地址介绍

BLE的7种工作状态

BLE芯片的链路层定义了7种工作状态,同一时间只能处于一种状态,不同状态之间可以切换,一颗芯片可以有多个状态机同时工作,下面对这些状态进行介绍。 七大状态介绍 一、待机状态(Idle) 芯片既不发送也不接收数据,处于休眠。 特点: 可以从任何状态进入待机状态 可以从待机进入除连接状态外的所有状态 不发射不接收,最省电 举例:你的手环没在用时,芯片就在待机状态睡觉。 二、广播状态(Advertising) 芯片主动发送广告包,告诉周围"我在这里"。 作用:让别人发现你,并能回复扫描请求。 举例:蓝牙音箱进入配对模式,不断广播"我是XX音箱,快来连我"。 可以从广告状态直接进入连接状态。 三、扫描状态(Scanning) 芯片监听周围的广告包,寻找可用设备。 作用:发现附近的BLE设备。 举例:手机打开蓝牙,扫描附近设备,此时手机处于扫描状态。 四、发起状态(Initiating) 芯片接收特定设备的广告包,并回复连接请求。 作用:主动发起连接。 举例:手机点击"连接手环",进入发起状态,向手环发送连接请求。 可以从发起状态进入连接状态。 五、连接状态(Connection) 设备已建立连接,可以双向传输数据。 作用:进行数据交互。 举例:手环和手机已连接,正在同步步数和心率数据。 注意:只能从广播状态或发起状态进入连接状态,不能从待机直接连接 六、同步状态(Synchronization) 芯片接收周期性广告的数据包。 作用:同步接收定期更新的信息。 举例:接收BLE定位信标的周期性位置信息。 适用场景:需要定时接收广播数据但不建立连接。 七、等时广播状态(Isochronous Broadcasting) 芯片在等时信道上发送数据包。 作用:发送对时间敏感的数据流。 举例:BLE音频设备同步传输音乐到多个耳机(LE Audio)。 适用场景:需要精确时序的音频或数据传输。 八、状态切换规则 常见切换路径: 待机 → 广播 → 连接(外设被连接) 待机 → 扫描 → 发起 → 连接(中心设备主动连接) 连接 → 待机(断开连接) 任何状态 → 待机(随时可以休眠省电) 待机 → 广播/扫描/同步/等时广播(但不能直接到连接) 九、实际应用场景 智能手环: 没用时:待机状态(省电) 等待连接:广播状态(被发现) 已连接:连接状态(传数据) 断开后:回到待机 手机: ...

无线通信是如何实现的

无线通信技术早已经融入我们的生活,如手机通信,WiFi,蓝牙。背后都离不开它的支撑。那么,这项技术究竟是如何实现的呢? 一、基本实现原理 无线通信用的是电磁波信号,我们说话的语音,拍的图片,听的音乐,这些信息首先通过调制技术加载到无线载波上,然后由发射设备发送出去。接收方通过解调操作,把载波上的信息取下来,恢复成原始信号。 二、系统构建复杂性 构建一个无线通信系统很复杂,它主要涉及以下几个部分: 1.模数转换 (确保传输和处理时兼容) 2.RF射频设计 (负责信号发射和接收频率调控) 3.协议栈 (无线通信标准) 专业开发要求 硬件设计需要高精度元器件匹配,系统调试需专门开发环境与经验,因此市场上很少从头搭建系统,而是普遍采用常用无线通信模块。把多个核心元器件集成在一起,直接实现特定通信功能,大大降低了应用门槛。 无线通信模块 无线通信模块就像是一个与装好的工具箱,主要由基带芯片,射频收发器等关键元器件组成,能直接作为通信终端使用,其中两大核心部分尤为重要。 1.系带芯片:调制解调。同时还会检测传输中可能出现的错误,并及时纠正,确保信息准确。 2.射频前端电路:信号强化器。射频信号在传输过程中可能会衰减,混入杂音,射频前端就负责对信号进行放大(提升强度,让传输更远)和滤波(过滤杂音)处理好的信号在通过天线发射出去,确保对方能清晰收到。 总结 无线通信系统的实现就是信息数字化“编码调制-射频发射-接收解调-信息还原”的闭环,在通过核心硬件的协同和统一标准的规定,最终实现稳定,高效的无线通信。 原文:CSDN · 无线通信是如何实现的

无线通信原理

1. 无线通信的本质:把信息“寄”到空气里 无线通信就是利用电磁波在空中传递信息——类似寄快递: 电磁波 = 快递盒:看不见摸不着,却能把内容送出去。 要传的内容 = 信息:音乐、指令、传感器数据等。 无线通信的流程只有两步: 调制(打包):把信息装进“电磁波快递盒”。 解调(拆包):收件方拆开快递,还原信息。 ✏️ 蓝牙通信实例 调制:手机播放音乐时,蓝牙芯片把音频数据调制到 2.4 GHz 电磁波上,同时选择合适的频道,避免和 Wi-Fi “撞车”。 解调:蓝牙耳机接收到电磁波后,芯片解调数据并还原成声音。 2. 无线通信绕不开的麻烦:干扰 常见两种干扰类型: 同频干扰 Wi-Fi、蓝牙鼠标都在用 2.4 GHz,像多辆快递车挤同一条路。一旦有人开大功率 Wi-Fi,旁边的蓝牙键盘就会延迟。解决办法是让蓝牙跳频,类似换车道。 环境干扰 金属、墙体会衰减信号;厚衣物、人体遮挡都会减弱电磁波;旁边的蓝牙音箱可能会“滋滋”响。 3. 蓝牙的抗干扰技术 自适应跳频(AFH) 蓝牙在 2.4 GHz 频段的 79 个子信道里高速跳频,每秒最多跳 1600 次。检测到某个频道被占用,就换到空闲频道,降低碰撞概率。 纠错编码(FEC) 发送时附加冗余信息,即使部分数据受干扰被破坏,也能用冗余位恢复原数据,保证语音、音乐的连续性。 4. 常见无线技术对比 技术 典型用途 特点与蓝牙对比 蓝牙 耳机、音箱、手表、键鼠 功耗低、延迟小、距离短(约 10 米),适合随身设备 Wi-Fi 上网、智能家居联网 速率高、覆盖远,但功耗大,不适合小电池设备 LoRa / NB-IoT 远程传感器、智慧城市场景 覆盖远、功耗低,但速率慢,延迟大,不适合音视频 5. 常见蓝牙连接问题排查 现象 可能原因 建议处理 蓝牙耳机偶尔卡顿 Wi-Fi 同频干扰 远离路由器或尝试重连 穿墙后信号大幅衰减 墙体、金属屏蔽电磁波 尽量保持直线距离,避免多层阻挡 口袋里手机连接手表不稳定 人体吸收 2.4 GHz 信号 手机放包里或手表靠近手机 微波炉一开蓝牙噪音变大 微波炉辐射同频信号 避免同时使用或保持距离 6. 总结 无线通信的核心是“调制 + 电磁波传输 + 解调”。蓝牙之所以适合日常设备,是因为它在功耗、抗干扰和延迟之间做到了平衡。如果遇到连接问题,多半是干扰或遮挡导致。 ...

LE audio介绍

LE audio介绍 LE Audio是它全称是Low Energy Audio(低功耗音频) 是蓝牙技术联盟在5.2核心规范里引入的全新,低功耗音频技术标准 在低功耗、多设备连接和音频共享上实现了超大突破! LC3编解码器 全新的音频编解码器LC3,是LE audio的灵魂所在, 和传统SBC编解码器比起来,哪怕数据速率更低,也能提供相同甚至更好的音质。 不管是日常听歌还是打电话,都能在省功耗的同时稳稳保住音质。 多流音频技术 多流音频是LE audio的另一种优势!以前耳机主副耳要转发信号,现在智能手机等源设备能独立同步给两个耳机发多个音频流,直接消除了转发环节。 带来的好处:连接更可靠、延迟更低、左右声道同步更完美! 比如听歌时来电话,不用断开音乐,能无缝切到通话,挂完电话又自动切回音乐,丝滑不卡顿。 广播音频功能 广播音频功能是LE Audio最具有革命性的功能,直接开启了音频共享的新时代!蓝牙联盟将其品牌化为 Auracast™。 它允许一个音频源设备(比如手机)能以发射器身份,把一个音频流广播给附近无数个接收设备(比如不同品牌的耳机,只要支持LE Audio就能订阅,Auracast支持跨品牌设备接收) 比如:大家可以用不同的耳机听同一个音频,可以是音乐,电影,广播。 总结:LE Audio为啥是未来趋势? 简单说就是三个字:长!高!稳! 更长的续航,更高的音质、更稳定的连接,现在支持LE Audio的设备越来越多,妥妥的未来蓝牙音频主流方向。 新手宝子如果想了解蓝牙音频新技术,LE Audio一定要重点关注!收藏这篇,随时回看。 原文:CSDN · LE audio介绍

蓝牙启蒙认知

蓝牙入门知识 一、蓝牙名字的由来 蓝牙名字,来自1000年前丹麦国王"哈拉尔德·蓝牙"的名字,因为这位国王统一了丹麦和挪威的部落。而蓝牙技术则统一了无线通信标准。 二、蓝牙解决了什么问题 代替有线连接:告别数据线的束缚 设备互联互通:不同设备也能通信(统一标准) 低成本低功耗:比wifi省钱,比红外线灵活 蓝牙让短距离无线连接变得简单,便宜,省电。 三、蓝牙是如何工作的 发现(Discovery):搜索附近的蓝牙设备 配对(Paring):首次建立信任,交换秘钥 连接(Connection):正式通信,传输数据 技术层面: 跳频,采用2.4Ghz 频段,这个频段很多设备。为了不被干扰,蓝牙采用了跳频技术,所以不会被窃听或干扰。 握手,设备首次建立信任,交换密钥,验证双方的身份,验证通过后,就能传输数据。 蓝牙传输数据,蓝牙传输数据就像是寄快递,会把大文件切成多个小包(经典蓝牙单包最多339字节,BLE单包最多251字节),每个包都贴上“收件人地址”和“顺序编号”,通过无线电波“快递”过去,对方收到后按编号重新拼装。 连接稳定性,当距离太远(一般有效范围10~100米,取决于蓝牙功率,一般设置为10米左右),障碍物遮挡,电量不足,电磁干扰(wifi,微波炉),发射和接收功率设置,蓝牙版本不兼容,都会影响蓝牙连接的稳定性。 补充:蓝牙是如何空气中传输数据的 四、什么是2.4GHz频段 频率范围:2.400-2.4835GHZ 全球免许可:不需要申请就能用 穿透力适中:能穿墙但不会太远,10米左右 注意:2.4Ghz频段很拥挤,WIFI,微波炉,无线鼠标都在用,所以蓝牙必须有抗干扰技术 蓝牙为什么不用其他频段? 低频段(比如900Mhz):穿透性强但传输速度慢,天线太大装不进小设备 高频段(比如5GHz):传输速度快但穿透性差,耗电更多 2.4Ghz刚好平衡了所有需求,够快,够小,够省电,够穿透 五、跳频技术原理 经典蓝牙把2.4Ghz分成79个信道(每个1Mhz),频率范围2402~2480,跳频速率固定1600次/秒(每625微秒跳一次,一个时隙625微秒),跳频序列是随机的,只有配对设备才知道。工作原理是提前约定好下一跳的信道,在79个信道中快速切换见面。经典蓝牙没有专门的广播专用信道,数据信道79个都可以用于传输。 BLE和经典蓝牙不同的点在于,BLE把2.4Ghz分成40个信道(每个2Mhz),跳频速率自适应,有3个广播专用通道,37个数据通道。 六、为什么蓝牙不会互相干扰 跳频序列不同,每个蓝牙设备都在不同的跳频,即使跳到同一信道,时间也是错开的,万一真的碰上,有重传机制。 七、主设备&从设备 主设备(Master):发起连接,管理网络,控制时钟 从设备(Slave):响应连接,被动接收指令 举例: 手机连蓝牙总是手机主动,耳机被动。这是蓝牙世界的基本规则,所以必须分出老大和小弟,这是蓝牙世界的等级制度。其中,一个当老大(Master),其他当小弟(Slave),通常是主动发起连接的当老大,老大说了算,小弟负责听指挥。 责任划分: 主设备决定大家按什么顺序跳频,分配谁什么时候可以“说话”,当多个从设备同时要传输数据时,主设备决定谁先传谁后传。 从设备必须跟着主设备时钟走,主从设备会定期进行时钟同步,短时间偏差会通过重传机制纠正,只有长时间失去同步才会断连。蓝牙采用时分双工机制,主设备占用偶数时隙,从设备占用奇数时隙,每个时隙为625微秒。 分主从是避免混乱,如果设备都平等,谁来决定跳频顺序和分配传输时间。所以必须分主从来进行管理。主从结构让协议变的简单,主设备负责复杂的管理工作,从设备只需听指令就行。主设备下达命令,从设备立即执行,不用讨论。但主从之间有距离限制,距离太远,主设备管不到的地方,从设备就会断连。主从角色在某些情况可以切换,比如在TWS耳机中,耳机组队可以协商谁当主设备,谁当从设备。 典型例子: 手机=主设备,蓝牙耳机=从设备 电脑=主设备,蓝牙鼠标=从设备 注意:一个主设备最多连接7个从设备(蓝牙使用3位地址标识从设备,其中000保留,所以实际可用001~111=7个) 八、微微网概念 **核心理解:**微微网是蓝牙世界的基本单位,微微网=1个主设备+最多7个从设备组成的蓝牙小网络。 基本规则:必须有一个主设备,最多有8个成员,并且保持同一个频率节奏,所有成员必须同步跳频,跟着主设备的节拍走。 生命周期:主设备发起网络连接,从设备陆续加入,大家按规则通信,主设备可以选择关闭或断开从设备的通信。 通信规则:从设备只能和主设备说话,不能直接和其他从设备聊天,必须通过主设备中转。 轮流通信:主设备分配时隙,每个从设备按顺序说话,每0.625毫秒为一个时间片。 时间轴(每个时隙625微秒): 0 1 2 3 4 5 6 7 |____|____|____|____|____|____|____| 主 从1 主 从2 主 从3 主 从1 规则: - 偶数时隙:主设备发送 - 奇数时隙:从设备发送 为什么叫微微网? ...

01-蓝牙协议栈介绍

01 蓝牙入门-蓝牙协议栈介绍 一、蓝牙类型 特性 经典蓝牙(BR,EDR) 低功耗蓝牙(BLE) 备注 全称 Basic Rate / Enhanced Data Rate Bluetooth Low Energy 经典蓝牙在嵌入式领域基本被放弃使用,现在着重使用低功耗蓝牙 主要用途 音频传输 低功耗设备 经典蓝牙适合大数据传输,BLE适合小数据、低功耗场景 传输速度 1-3 Mbps 1 Mbps 功耗 高 极低 BLE的功耗是经典蓝牙的1/10到1/100,适合电池供电设备 连接时间 较长(通常需要几秒) 极短(毫秒级) BLE连接快,适合频繁连接和断开的场景 兼容性 仅支持经典蓝牙 仅支持BLE的蓝牙 双模蓝牙设备可以同时支持经典蓝牙和BLE,兼容性更强 说明: 这两种协议都包括 搜索管理,连接管理等机制,但他们底层是相互独立,不能互通的技术 厂家如果只实现了一种,那么只能与同样实现该技术的设备互通,如果厂家需要所有的蓝牙设备互通,那么就必须同时实现两种技术,而不去管是否真的需要 二、方案介绍 三种方案对比: 方案 单芯片方案 蓝牙+MCU方案 Host+Controller方案 适用场景 蓝牙音响、蓝牙耳机 智能手环、智能手表 手机、平板等复杂设备 功能复杂度 功能固定,较简单 功能中等,需要额外处理能力 功能复杂,需要高性能处理 开发难度 低 中等 高 成本 低 中等 高 功耗 低 中等 高 蓝牙协议栈位置 集成在单芯片中 蓝牙芯片负责通信,MCU负责逻辑处理 蓝牙协议栈在主芯片中,蓝牙芯片负责底层通信 三、蓝牙协议栈 HFP:接电话、挂电话。 【蓝牙电话协议】 A2DP:听音乐。 【蓝牙音频传输协议】 AVRCP:切歌、调音量。 【蓝牙音视频远程控制协议】 PBAP:同步联系人。 【蓝牙电话本访问协议】 MAP:查看短信。 【蓝牙短信访问协议】 蓝牙协议的简化架构图 ...