Android博通BCM libbt-vendor.so 分析蓝牙初始化流程

原创 专注于无线通信的蓬勃 2022-10-27 09:08

一. 声明

本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:

第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。

第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等

第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层(baseband),链路管理层(LMP)等

第四篇:传统蓝牙host介绍,主要介绍传统蓝牙的协议栈,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的协议吧。

第五篇:低功耗蓝牙controller介绍,主要介绍低功耗蓝牙芯片,包括物理层(PHY),链路层(LL)

第六篇:低功耗蓝牙host介绍,低功耗蓝牙协议栈的介绍,包括HCI,L2CAP,ATT,GATT,SM等

第七篇:蓝牙芯片介绍,主要介绍一些蓝牙芯片的初始化流程,基于HCI vendor command的扩展

第八篇:附录,主要介绍以上常用名词的介绍以及一些特殊流程的介绍等。

另外,开发板如下所示,对于想学习蓝牙协议栈的最好人手一套。以便更好的学习蓝牙协议栈,相信我,学完这一套视频你将拥有修改任何协议栈的能力(比如Linux下的bluez,Android下的bluedroid)。

------------------------------------------------------------------------------------------------------------------------------------------

蓝牙交流扣扣群(已满):970324688

蓝牙交流扣扣群:765961169

Github代码:https://github.com/sj15712795029/bluetooth_stack

------------------------------------------------------------------------------------------------------------------------------------------

二.BCM(博通)的初始化流程介绍

步骤1:发送HCI Reset command,等待芯片回复

步骤2: 提升uart波特率,准备下载固件

步骤3: 读取芯片名称,匹配固件名称

步骤4:告知芯片准备下载固件

步骤5:Write RAM

步骤6:Launch RAM

步骤7:降低串口波特率,重新发送HCI reset

步骤8: 提升uart波特率,准备后续交互command

步骤9:修改蓝牙地址

步骤10:告知协议栈下载固件完毕,协议栈进入正常初始化流程

下面我们就来一一介绍下具体的步骤:

步骤1:发送HCI Reset command,等待芯片回复

在收到协议栈给vendor发送的BT_VND_OP_FW_CFG opcode后,执行hw_config_start后发送hci reset

void hw_config_start(void)
{
    HC_BT_HDR  *p_buf = NULL;
    uint8_t     *p;

    hw_cfg_cb.state = 0;
    hw_cfg_cb.fw_fd = -1;
    hw_cfg_cb.f_set_baud_2 = FALSE;

    /* Start from sending HCI_RESET */

    if (bt_vendor_cbacks)
    {
        p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE   \
                                                       HCI_CMD_PREAMBLE_SIZE);
    }

    if (p_buf)
    {
        p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
        p_buf->offset = 0;
        p_buf->layer_specific = 0;
        p_buf->len = HCI_CMD_PREAMBLE_SIZE;

        p = (uint8_t *) (p_buf   1);
        UINT16_TO_STREAM(p, HCI_RESET);
        *p = 0; /* parameter length */

        hw_cfg_cb.state = HW_CFG_START;

        bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback);  // 通过HCI接口发送HCI reset
    }
    else
    {
        if (bt_vendor_cbacks)
        {
            ALOGE("vendor lib fw conf aborted [no buffer]");
            bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
        }
    }
}

也就是btsnoop中的packet 1~2

NOTED:此命令是标准的HCI command,一般芯片都要在初始化的时候下一个HCI reset的command

步骤2: 提升uart波特率,准备下载固件

① 代码分析

在发送完毕步骤1的HCI Reset后,我们会进入hw_config_cback callback函数中,通过hw_cfg_cb.state我们进入以下case

case HW_CFG_START:
    if (UART_TARGET_BAUD_RATE > 3000000)
    {
        /* set UART clock to 48MHz */
        UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING);
        *p   = 1; /* parameter length */
        *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */

        p_buf->len = HCI_CMD_PREAMBLE_SIZE   1;
        hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK;

        is_proceeding = bt_vendor_cbacks->xmit_cb( \
                                                  HCI_VSC_WRITE_UART_CLOCK_SETTING, \
                                                  p_buf, hw_config_cback);
        break;
    }
/* fall through intentionally */
case HW_CFG_SET_UART_CLOCK:
    /* set controller's UART baud rate to 3M */
    UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
    *p   = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */
    *p   = 0; /* encoded baud rate */
    *p   = 0; /* use encoded form */
    UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE);

    p_buf->len = HCI_CMD_PREAMBLE_SIZE   \
                                 UPDATE_BAUDRATE_CMD_PARAM_SIZE;
    hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \
                                HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1;

    is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \
                                                        p_buf, hw_config_cback);
break;

由于我们设定的UART_TARGET_BAUD_RATE是3M,所以我们跑到case HW_CFG_SET_UART_CLOCK中,所以我们可以看到改变波特率的HCI VS command的组包过程

UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
*p   = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */
*p   = 0; /* encoded baud rate */
*p   = 0; /* use encoded form */
UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE);

其中几个宏定义为:

#define HCI_VSC_UPDATE_BAUDRATE                 0xFC18
#define UPDATE_BAUDRATE_CMD_PARAM_SIZE          6
#define UART_TARGET_BAUD_RATE           3000000

以上是发送串口波特率的HCI vs command,但是别忘了,我们收到command complete后要改变本地的驱动的波特率,代码如下:

userial_vendor_set_baud( \
                    line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \

至此,芯片以及驱动层面的波特率都改变完毕了!

② 命令格式分析

NOTED:这里询问过CYW,暂时无法拿到4349的VS command & event文档,所以无法截图,但是看code来说一共有6个byte:

1个byte的encoded baud rate 1个byte的use encoded form 4个byte的波特率

也就是btsnoop中的packet 3~4

步骤3: 读取芯片名称,匹配固件名称

读取芯片名称,NOTED:这个是标准的HCI commmand

① 代码分析

/* read local name */
UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME);
*p = 0; /* parameter length */

p_buf->len = HCI_CMD_PREAMBLE_SIZE;
hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME;

is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \
                                                    p_buf, hw_config_cback);

然后匹配到config patch的文件名称

也就是btsnoop中的packet 5~6

步骤4:告知芯片准备下载固件

找到芯片名称,匹配到fireware后,host会给controller下一个HCI VS command,这个command的作用是告知controller,我们准备要下载fw了

① 代码分析

 /* vsc_download_minidriver */
UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV);
*p = 0; /* parameter length */

p_buf->len = HCI_CMD_PREAMBLE_SIZE;
hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER;

is_proceeding = bt_vendor_cbacks->xmit_cb( \
                                            HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \
                                            hw_config_cback);

其中HCI_VSC_DOWNLOAD_MINIDRV的定义为:

#define HCI_VSC_DOWNLOAD_MINIDRV                0xFC2E

② 命令格式分析

也就是btsnoop中的packet 7~8

步骤5:Write RAM

收到Download Minnidriver的command complete后,会读取fireware文件来把数据从host下到controller中,代码如下:

p_buf->len  = read(hw_cfg_cb.fw_fd, \
              p HCI_CMD_PREAMBLE_SIZE,\
              *(p HCD_REC_PAYLOAD_LEN_BYTE));
STREAM_TO_UINT16(opcode,p);
is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \
               p_buf, hw_config_cback);

② 命令格式分析

也就是btsnoop中的packet 9~782

步骤6:Launch RAM

通过Write RAM下载完固件后,通过Launch RAM来启动固件

NOTED:Write RAM跟Launch RAM这些都在firewware固件本身中

也就是btsnoop中的packet 783~784

步骤7:降低串口波特率,重新发送HCI reset

① 代码分析

在收到lanuch ram后,降低波特率为115200,重新发送hci reset,流程如下:

/* Normally the firmware patch configuration file
* sets the new starting baud rate at 115200.
* So, we need update host's baud rate accordingly.
*/
ALOGI("bt vendor lib: set UART baud 115200");
userial_vendor_set_baud(USERIAL_BAUD_115200);

/* Next, we would like to boost baud rate up again
                 * to desired working speed.
                 */
hw_cfg_cb.f_set_baud_2 = TRUE;

/* Check if we need to pause a few hundred milliseconds
                 * before sending down any HCI command.
                 */
delay = look_up_fw_settlement_delay();
ALOGI("Setting fw settlement delay to %d ", delay);
ms_delay(delay);

p_buf->len = HCI_CMD_PREAMBLE_SIZE;
UINT16_TO_STREAM(p, HCI_RESET);
*p = 0; /* parameter length */
hw_cfg_cb.state = HW_CFG_START;
is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_RESET, p_buf, hw_config_cback);

也就是btsnoop中的packet 785~786

步骤8: 提升uart波特率,准备后续交互command

这里又通过HCI vs commad把波特率从115200提升到3M,然后收到command complete后把串口驱动的波特率提升

UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
*p   = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */
*p   = 0; /* encoded baud rate */
*p   = 0; /* use encoded form */
UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE);

p_buf->len = HCI_CMD_PREAMBLE_SIZE   \
                             UPDATE_BAUDRATE_CMD_PARAM_SIZE;
hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \
                            HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1;

is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \
                                                    p_buf, hw_config_cback);
userial_vendor_set_baud(line_speed_to_userial_baud(UART_TARGET_BAUD_RATE));

也就是btsnoop中的packet 787~788

步骤9:修改蓝牙地址

收到波特率改变成功的command complete的event后,我们通过HCI VS command来改变蓝牙地址

static uint8_t hw_config_set_bdaddr(HC_BT_HDR *p_buf)
{
    uint8_t retval = FALSE;
    uint8_t *p = (uint8_t *) (p_buf   1);

    ALOGI("Setting local bd addr to X:X:X:X:X:X",
        vnd_local_bd_addr[0], vnd_local_bd_addr[1], vnd_local_bd_addr[2],
        vnd_local_bd_addr[3], vnd_local_bd_addr[4], vnd_local_bd_addr[5]);

    UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR);
    *p   = BD_ADDR_LEN; /* parameter length */
    *p   = vnd_local_bd_addr[5];
    *p   = vnd_local_bd_addr[4];
    *p   = vnd_local_bd_addr[3];
    *p   = vnd_local_bd_addr[2];
    *p   = vnd_local_bd_addr[1];
    *p = vnd_local_bd_addr[0];

    p_buf->len = HCI_CMD_PREAMBLE_SIZE   BD_ADDR_LEN;
    hw_cfg_cb.state = HW_CFG_SET_BD_ADDR;

    retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_WRITE_BD_ADDR, p_buf, \
                                 hw_config_cback);

    return (retval);
}

② 命令格式分析

也就是btsnoop中的packet 787~788

步骤10:告知协议栈下载固件完毕,协议栈进入正常初始化流程

专注于无线通信的蓬勃 朝气蓬勃——不积跬步 无以至千里, 不积小流 无以成江海
评论 (0)
  • 一、引言:健康管理数字化浪潮下的血压监测转型在慢性病高发与老龄化加剧的双重压力下,家庭健康监测设备正从“被动测量工具”向“主动健康管家”演进。传统血压计虽能提供基础数值,却无法解决用户的核心痛点:数据如何解读?异常如何干预?风险如何预防?WT2605C芯片方案的诞生,通过“AI对话+云端互联+个性化服务”三重技术突破,重新定义了血压计的价值边界——它不仅是一台测量仪器,更是一个全天候在线的健康管理生态系统。二、传统血压计的局限与用户需求升级1. 功能单一性困境数据孤岛:仅显示收缩压/舒张压数值,
    广州唯创电子 2025-04-16 08:55 57浏览
  •   无人装备作战协同仿真系统软件:科技的关键支撑   无人装备作战协同仿真系统软件,作为一款综合性仿真平台,主要用于模拟无人机、无人车、无人艇等无人装备在复杂作战环境中的协同作战能力、任务规划、指挥控制以及性能评估。该系统通过搭建虚拟战场环境,支持多种无人装备协同作战仿真,为作战指挥、装备研发、战术训练和作战效能评估,提供科学依据。   应用案例   系统软件供应可以来这里,这个首肌开始是幺伍扒,中间是幺幺叁叁,最后一个是泗柒泗泗,按照数字顺序组合就可以找到。   核心功能   虚拟战
    华盛恒辉l58ll334744 2025-04-14 17:24 90浏览
  • 二、芯片的设计1、芯片设计的基本流程 (1)需求定义: 明确芯片功能(如处理器、存储、通信)、性能指标(速度、功耗、面积)及目标应用场景(消费电子、汽车、工业)。 (2)架构设计: 确定芯片整体框架,包括核心模块(如CPU、GPU、存储单元)的协同方式和数据流路径。 (3)逻辑设计: 通过硬件描述语言(如Verilog、VHDL)将架构转化为电路逻辑,生成RTL(寄存器传输级)代码。 (4)物理设计: 将逻辑代码映射到物理布局,涉及布局布线、时序优化、功耗分析等,需借助EDA工具(如Ca
    碧海长空 2025-04-15 11:30 177浏览
  • 一、智能门锁市场痛点与技术革新随着智能家居的快速发展,电子门锁正从“密码解锁”向“无感交互”进化。然而,传统人体感应技术普遍面临三大挑战:功耗高导致续航短、静态人体检测能力弱、环境适应性差。WTL580微波雷达解决方案,以5.8GHz高精度雷达感知技术为核心,突破行业瓶颈,为智能门锁带来“精准感知-高效触发-超低功耗”的全新交互范式。二、WTL580方案核心技术优势1. 5.8GHz毫米波雷达:精准感知的革命全状态人体检测:支持运动、微动(如呼吸)、静态(坐卧)多模态感知,检测灵敏度达0.1m/
    广州唯创电子 2025-04-15 09:20 98浏览
  • 展会名称:2025成都国际工业博览会(简称:成都工博会)展会日期:4月23 -25日展会地址:西部国际博览城展位号:15H-E010科士威传动将展示智能制造较新技术及全套解决方案。 2025年4月23-25日,中国西部国际博览城将迎来一场工业领域的年度盛会——2025成都国际工业博览会。这场以“创链新工业,共碳新未来”为主题的展会上,来自全球的600+ 家参展企业将齐聚一堂,共同展示智能制造产业链中的关键产品及解决方案,助力制造业向数字化、网络化、智能化转型。科士威传动将受邀参展。&n
    科士威传动 2025-04-14 17:55 90浏览
  • 三、芯片的制造1、制造核心流程 (1)晶圆制备:以高纯度硅为基底,通过拉晶、切片、抛光制成晶圆。 (2)光刻:光刻、离子注入、薄膜沉积、化学机械抛光。 (3)刻蚀与沉积:使用干法刻蚀(等离子体)精准切割图形,避免侧壁损伤。 (4)掺杂:注入离子形成PN结特性,实现晶体管开关功能。2、材料与工艺创新 (1)新材料应用: 高迁移率材料(FinFET中的应变硅、GaN在射频芯片中的应用); 新型封装技术(3D IC、TSV硅通孔)提升集成度。 (2)工艺创新: 制程从7nm到3nm,设计架构由F
    碧海长空 2025-04-15 11:33 221浏览
  • 一、智能语音播报技术演进与市场需求随着人工智能技术的快速发展,TTS(Text-to-Speech)技术在商业场景中的应用呈现爆发式增长。在零售领域,智能收款机的语音播报功能已成为提升服务效率和用户体验的关键模块。WT3000T8作为新一代高性能语音合成芯片,凭借其优异的处理能力和灵活的功能配置,正在为收款机智能化升级提供核心技术支持。二、WT3000T8芯片技术特性解析硬件架构优势采用32位高性能处理器(主频240MHz),支持实时语音合成与多任务处理QFN32封装(4x4mm)实现小型化设计
    广州唯创电子 2025-04-15 08:53 115浏览
  • 一、引言:智能化趋势下的学爬玩具开发挑战随着早教理念的普及,学爬玩具作为婴幼儿早期运动能力开发的重要工具,市场需求持续增长。然而,传统学爬玩具开发面临多重挑战:需集成红外遥控、语音交互、电机控制等多模块,开发周期长、硬件成本高;复杂的红外编解码与语音功能实现依赖工程师深度参与,技术门槛陡增。如何以更低成本、更快速度打造差异化产品,成为行业亟待解决的痛点。二、传统开发模式痛点分析硬件冗余红外接收模块、语音芯片、主控MCU分立设计,导致PCB面积增加,BOM成本攀升。开发周期长需工程师独立完成红外协
    广州唯创电子 2025-04-16 08:40 56浏览
  • 四、芯片封测技术及应用场景1、封装技术的发展历程 (1)DIP封装:早期分立元件封装,体积大、引脚少; (2)QFP封装:引脚密度提升,适用于早期集成电路。 (3)BGA封装:高密度互连,散热与信号传输优化; (4)3D封装:通过TSV(硅通孔)实现垂直堆叠,提升集成度(如HBM内存堆叠); (5)Chiplet封装:异质集成,将不同工艺节点的模块组合(如AMD的Zen3+架构)。 (6)SiP封装:集成多种功能芯片(如iPhone的A系列SoC整合CPU、GPU、射频模块)。2、芯片测试 (1
    碧海长空 2025-04-15 11:45 226浏览
  • 2025年4月13日(中国武汉)——在全球经济分化与地缘政治不确定性加剧的背景下,科技与金融的深度融合已成为推动创新与繁荣的关键动力。为实现科技创新、产业进步和金融发展有机结合,发挥金融对科技创新和产业进步的支持作用,国际金融论坛(IFF)科技金融委员会启动大会暨首届科技金融圆桌会议于4月13日在湖北省武汉市武汉产业创新发展研究院成功举行。同时,IFF科技金融委员会由国际金融论坛IFF与武创院联合成立。本次大会汇聚了来自政府、产业与学术研究机构及金融等多领域的精英,共同探讨科技金融如何更好地服务
    华尔街科技眼 2025-04-15 20:53 52浏览
  • 在当今汽车电子化和智能化快速发展的时代,车规级电子元器件的质量直接关系到汽车安全性能。三星作为全球领先的电子元器件制造商,其车规电容备受青睐。然而,选择一个靠谱的三星车规电容代理商至关重要。本文以行业领军企业北京贞光科技有限公司为例,深入剖析如何选择优质代理商。选择靠谱代理商的关键标准1. 授权资质与行业地位选择三星车规电容代理商首先要验证其授权资质及行业地位。北京贞光科技作为中国电子元器件行业的领军者,长期走在行业前沿,拥有完备的授权资质。公司专注于市场分销和整体布局,在电子元器件领域建立了卓
    贞光科技 2025-04-14 16:18 152浏览
  • 一、芯片的发展历程总结:1、晶体管的诞生(1)电子管时代 20世纪40年代,电子管体积庞大、功耗高、可靠性差,无法满足计算机小型化需求。(2)晶体管时代 1947年,贝尔实验室的肖克利、巴丁和布拉顿发明点接触晶体管,实现电子信号放大与开关功能,标志着固态电子时代的开端。 1956年,肖克利发明晶体管。(3)硅基晶体管时代 早期晶体管采用锗材料,但硅更耐高温、成本低,成为主流材料。2、集成电路的诞生与发展 1958年,德州仪器工程师基尔比用锗材料制成世界上第一块含多个晶体管的集成电路,同年仙童半导
    碧海长空 2025-04-15 09:30 136浏览
我要评论
0
1
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦