<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>蓝牙协议栈 on 栈外随记</title>
    <link>https://btio.cn/tags/%E8%93%9D%E7%89%99%E5%8D%8F%E8%AE%AE%E6%A0%88/</link>
    <description>Recent content in 蓝牙协议栈 on 栈外随记</description>
    <image>
      <title>栈外随记</title>
      <url>https://btio.cn/images/logo-arong.svg</url>
      <link>https://btio.cn/images/logo-arong.svg</link>
    </image>
    <generator>Hugo</generator>
    <language>zh-CN</language><lastBuildDate>Mon, 03 Aug 2026 11:26:31 +0800</lastBuildDate>
    <atom:link href="https://btio.cn/tags/%E8%93%9D%E7%89%99%E5%8D%8F%E8%AE%AE%E6%A0%88/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>做 TWS 应用开发，到底需不需要懂协议栈</title>
      <link>https://btio.cn/posts/2026/08/03/%E5%81%9A-tws-%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E5%88%B0%E5%BA%95%E9%9C%80%E4%B8%8D%E9%9C%80%E8%A6%81%E6%87%82%E5%8D%8F%E8%AE%AE%E6%A0%88/</link>
      <pubDate>Mon, 03 Aug 2026 11:26:31 +0800</pubDate>
      <guid>https://btio.cn/posts/2026/08/03/%E5%81%9A-tws-%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E5%88%B0%E5%BA%95%E9%9C%80%E4%B8%8D%E9%9C%80%E8%A6%81%E6%87%82%E5%8D%8F%E8%AE%AE%E6%A0%88/</guid>
      <description>&lt;p&gt;刚接触 TWS 应用开发时，我一直有一个疑问：蓝牙协议栈大部分已经由芯片原厂封装好了，平时做功能主要是调用 SDK 接口、处理事件和编写产品逻辑，还有没有必要专门学习协议栈？&lt;/p&gt;
&lt;p&gt;刚入行的时候，我也尝试过从头学习蓝牙协议。当时下载了一份 Bluetooth Core Specification 6.0，打开后看到整整 3815 页，心里压力一下就上来了。里面有大量英文术语、状态、命令和数据包格式，我硬着头皮看了几天，还是很难把规范里的内容和手上的代码对应起来，最后没有坚持下去。&lt;/p&gt;
&lt;p&gt;工作两年左右，我对协议栈内部仍然谈不上有多深入的理解，平时接触最多的还是应用层代码。所以我现在的看法是：**需要了解一些，但没必要一开始钻得特别深。**这篇文章只是记录我目前在项目中用到的一些认识。&lt;/p&gt;
&lt;h2 id=&#34;section-1&#34;&gt;一、我目前主要关注什么&lt;/h2&gt;
&lt;p&gt;以我目前的工作内容来说，HCI、L2CAP 以及各个 Profile 的内部状态机，我其实没有深入研究。日常开发更常见的是调用 SDK 接口、接收事件，再根据产品状态处理业务。&lt;/p&gt;
&lt;p&gt;为了不把不同问题混在一起，我会先记住几个和工作直接相关的区别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ACL 连接和 Profile 连接不是一回事。&lt;/li&gt;
&lt;li&gt;A2DP 负责音乐，AVRCP 负责播放控制和音量同步。&lt;/li&gt;
&lt;li&gt;HFP 负责通话控制，SCO/eSCO 承载通话语音。&lt;/li&gt;
&lt;li&gt;SPP 和 BLE GATT 常用于 App 数据通信。&lt;/li&gt;
&lt;li&gt;接口调用成功，不一定代表异步操作已经完成，还要等待后续事件。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为了更直观地区分这些连接和业务，可参考蓝牙连接关系简化图：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;手机与 TWS 耳机的蓝牙连接关系&#34; loading=&#34;lazy&#34; src=&#34;https://btio.cn/images/csdn/163436393/%E6%89%8B%E6%9C%BA%E4%B8%8ETWS%E8%80%B3%E6%9C%BA%E7%9A%84%E8%93%9D%E7%89%99%E8%BF%9E%E6%8E%A5%E5%85%B3%E7%B3%BB.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;图中把 GATT 单独放在 BLE 连接下。严格来说，协议内部的承载关系还要更细，这里只保留我在应用开发中经常接触到的部分。&lt;/p&gt;
&lt;p&gt;我目前也就是先把这些常见概念分清。这样遇到异常时，至少知道先看哪一类状态，不至于一上来就把所有现象都归结成“蓝牙有问题”。&lt;/p&gt;
&lt;h2 id=&#34;section-2&#34;&gt;二、实际项目里，我能接触到什么&lt;/h2&gt;
&lt;p&gt;以我使用的中科蓝讯 &lt;code&gt;bt8910&lt;/code&gt; SDK 为例，工程里可以看到 A2DP、HFP、SPP 和 TWS 相关的配置及适配代码，但真正的核心实现主要由预编译的 &lt;code&gt;libbtstack.a&lt;/code&gt; 提供。&lt;/p&gt;
&lt;p&gt;应用层这边，A2DP 和 HFP 主要是调整部分参数、接收事件和处理业务回调；SPP 的 SDP Record 和数据收发回调可以看到并修改；GATT 可以添加 Service、Characteristic 和读写回调；TWS 这边则能做一些业务状态同步和主从切换处理。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
