RT-Thread平台zephyr_polling软件包Bluenrg2蓝牙芯片启动流程

RTT zephyr_polling软件包 Bluenrg2 蓝牙芯片启动流程


“开源之夏”“蓝牙HOST协议栈zephyr_polling完善” 项目个人记录

菜鸡参与项目的个人记录

项目软件包地址:RTT_PACKAGE_zephyr_polling

前面已经完成了 SPI 接口的实现,要让 zephyr_polling 在 Bluenrg2 上运行起来,下一步是实现其特殊的芯片启动流程。


蓝牙芯片启动流程


在用标准的 HCI 指令控制设备进行蓝牙操作之前,需要提前通过 VS Command 对设备进行配置,只有正确配置好的设备才能正常使用。

芯片产商只出售芯片,并不关注外围电路和具体的产品形态,这些是具体的ODM厂商来实现的。也就是芯片产商提供带HCI蓝牙功能的芯片,ODM设计电路并设计产品,之后通过HCI和芯片进行交互。实际各家ODM产商的需求各不相同,芯片产商为了满足不同客户的需要,并且为了减少和客户的对接,就必然在同一套代码的基础上,需要提供一系列的配置参数来满足不同 ODM 厂商的需要。

配置可以包括:固件烧录(部分没有带 FLASH 的蓝牙芯片每次上电都需要重新烧录最新的固件)、蓝牙地址配置、硬件接口配置(如RF接口,晶振类型等,部分蓝牙芯片需要)、波特率配置(HCI 一般是UART接口,默认是115200)以及芯片需要的由厂商要求的其他参数配置。

此外,对于一些有Flash的芯片,完全可以将配置参数等预烧录到了 Flash 中,使用时完全不需要配置任何参数,直接通过HCI接口操作使用即可。

zephyr_polling 协议栈提供了 Boot 流程接口和 Prepare 流程接口,可以根据实际芯片的需求实现启动配置。

Boot流程:

完成厂商的初始化流程,如固件下载,蓝牙地址配置等。在 chipset 注册好接口后,协议栈启动时会通过boot_start()回调启动 chipset(指协议栈 chipset 目录下的启动流程代码,下同) 的 Boot 流程,由于操作接口是 HCI,所以一般都是下发一个VS Command,然后根据 VS Event 来进行后续动作,协议栈会通过event_process()回调接口将收到的 event 上报给 chipset,当 chipset 认为操作结束时,通过调用bt_hci_set_boot_ready()接口通知协议栈boot流程结束。

Prepare流程:

部分厂商的参数要求在 HCI_Reset Command 之后进行(意思是它们的 HCI_Reset Command 会清空配置的参数)。为了兼容这类参数形态,HCI_Reset Command 之后还加入了 Prepare 流程。协议栈收到 HCI_Reset 的 Command Complete Event 后会通过prepare_start()回调启动 chipset 的 Prepare 流程,和 Boot 流程一样,协议栈会通过event_process()回调接口将收到的 event 上报给 chipset ,当chipset 认为操作结束时,通过调用bt_hci_set_prepare_ready()接口通知协议栈prepare流程结束。


BlueNRG-2 启动流程


查阅 ST 官方提供的手册和例程资料,可以了解到 BlueNRG-2 的启动配置需求。

对于 BlueNRG-2:

Boot 流程:无事务。

Prepare 流程:关闭Host功能;蓝牙地址配置;设置 TX power;GATT配置;GAP配置。


BlueNRG-2 启动流程实现


Boot 流程

BlueNRG-2 的 HCI_Reset Command 会清空配置的参数,所以实际的配置放在协议栈的 Prepare 流程中。Boot 流程的回调函数直接调用bt_hci_set_boot_ready()结束流程。

1void boot_start(void) {
2    state = STATE_POLLING_BOOTING;
3    // nothing to do
4    bt_hci_set_boot_ready();          //finish boot
5}

Prepare 流程 - 关闭 Host 功能

开发使用的蓝牙模块 X-NUCLEO-BNRG2A1 中的 BLE 本身是一个 SOC,里面集成了 host 的协议栈。厂商 ST 提供了一套 ACI 指令来控制芯片行为,包括 host 的接口。也就是说默认的情况下,这个芯片的 ACL 交互都被接管了,所以需要通过 ACI 命令,关闭 host 行为。需要通过aci_hal_write_config_data里的CONFIG_DATA_LL_WITHOUT_HOST关闭 host。

Prepare 流程第一步,关闭 host:

1void prepare_start(void) {
2    state = STATE_POLLING_PREPARING;
3    step = 1;
4    // step 1 close host
5    bluenrg2_config_without_host(); // It can be written only if aci_hal_write_config_data() is the first command after reset.
6}

关闭 host 的指令的 ogf 为0x3f,ocf 为0x00c,参数为2c11。其中,0x2C是关闭 Host 在 CONFIG_DATA 中的 offset。

1#define CONFIG_DATA_LL_WITHOUT_HOST         (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. */
2#define CONFIG_DATA_LL_WITHOUT_HOST_LEN     (1)
3static int bluenrg2_config_without_host()
4
{
5    uint8_t cmd_buffer[CONFIG_DATA_LL_WITHOUT_HOST_LEN + 2];
6    struct net_buf *buf;
7    cmd_buffer[0] = CONFIG_DATA_LL_WITHOUT_HOST;                //offset
8    cmd_buffer[1] = CONFIG_DATA_LL_WITHOUT_HOST_LEN;            //config len
9    cmd_buffer[2] = 1;                                          //Set to 1 to disable Host
10    uint16_t ogf = 0x3f, ocf = 0x00c;
11    uint16_t opcode = (uint16_t)((ocf & 0x03ff)|(ogf << 10));
12    buf = bt_hci_cmd_create(opcode, sizeof(cmd_buffer));
13    if (!buf)
14    {
15        return -ENOBUFS;
16    }
17    net_buf_add_mem(buf, cmd_buffer, sizeof(cmd_buffer));
18    return bt_hci_cmd_send(opcode, buf);
19}

Prepare 流程 - 蓝牙地址设置

需要通过aci_hal_write_config_data里的CONFIG_DATA_PUBADDR_OFFSET配置蓝牙地址。

配置蓝牙地址的指令的 ogf0x3f,ocf 为0x00c。配置蓝牙地址指令在 CONFIG_DATA 中的 offset 为 0x00,后面跟上地址长度和设置的蓝牙地址。

1#define BLE_MAC_ADDR                                                                               \
2    {                                                                                              \
3        {                                                                                          \
4            0xf5, 0x00, 0x00, 0xE1, 0x80, 0x02                                                   \
5        }                                                                                          \
6    }

7#define CONFIG_DATA_PUBADDR_OFFSET          (0x00) /**< Bluetooth public address */
8#define CONFIG_DATA_PUBADDR_LEN             (6)
9static int bluenrg2_config_set_public_addr()
10
{
11    uint8_t cmd_buffer[CONFIG_DATA_PUBADDR_LEN + 2];
12    struct net_buf *buf;
13    bt_addr_t addr = BLE_MAC_ADDR;
14    cmd_buffer[0] = CONFIG_DATA_PUBADDR_OFFSET;                 //offset
15    cmd_buffer[1] = CONFIG_DATA_PUBADDR_LEN;                    //config len
16    memcpy(cmd_buffer + 2, addr.val, CONFIG_DATA_PUBADDR_LEN);   // addr
17    uint16_t ogf = 0x3f, ocf = 0x00c;
18    uint16_t opcode = (uint16_t)((ocf & 0x03ff)|(ogf << 10));
19    buf = bt_hci_cmd_create(opcode, sizeof(cmd_buffer));
20    if (!buf)
21    {
22        return -ENOBUFS;
23    }
24    net_buf_add_mem(buf, cmd_buffer, sizeof(cmd_buffer));
25    return bt_hci_cmd_send(opcode, buf);
26}

Prepare 流程 - 设置发射功率

配置发射功率的指令的 ogf 为0x3f,ocf 为0x00f。命令参数为是否启用高功率模式(0x00启用普通功率,0x01启用高功率)和功率放大器输出电平(允许的PA电平取决于设备)。

PA_Level 值对应功率 

0: -14 dBm (High Power) 

1: -11 dBm (High Power) 

2: -8 dBm (High Power) 

3: -5 dBm (High Power) 

4: -2 dBm (High Power) 

5: 2 dBm (High Power) 

6: 4 dBm (High Power) 

7: 8 dBm (High Power)

1static int bluenrg2_set_tx_power_level(uint8_t En_High_Power, uint8_t PA_Level)
2
{
3    uint8_t cmd_buffer[2];
4    struct net_buf *buf;
5    cmd_buffer[0] = En_High_Power;      //En_High_Power
6    cmd_buffer[1] = PA_Level;           //config PA_Level
7    uint16_t ogf = 0x3f, ocf = 0x00f;
8    uint16_t opcode = (uint16_t)((ocf & 0x03ff)|(ogf << 10));
9    buf = bt_hci_cmd_create(opcode, sizeof(cmd_buffer));
10    if (!buf)
11    {
12        return -ENOBUFS;
13    }
14    net_buf_add_mem(buf, cmd_buffer, sizeof(cmd_buffer));
15    return bt_hci_cmd_send(opcode, buf);
16}
Prepare 流程 - GATT 配置

GATT 初始化的指令的 ogf 为0x3f,ocf 为0x101,没有其它参数。

1static int  bluenrg2_gatt_init(void)
2
{
3    uint16_t ogf = 0x3f, ocf = 0x101;
4    uint16_t opcode = (uint16_t)((ocf & 0x03ff)|(ogf << 10));
5    return bt_hci_cmd_send(opcode, NULL);
6}

Prepare 流程 - GAP 配置

初始化 GAP 层。注册GAP服务,并设置标准 GAP 服务特性:设备名称、Appearance、外围设备首选连接参数(仅限外围设备)。

GAP 配置的指令的 ogf 为0x3f,ocf 为0x08a。配置为外围设备,如果需要用做其他角色,需要修改此处;不启用隐私策略(为保护地址不被窃取,进行地址加密/解密,并周期更新);设置设备名字长度。

privacy: 

0x00: Privacy disabled 

0x01: Privacy host enabled 

0x02: Privacy controller enabled

1#define GAP_PERIPHERAL_ROLE                     (0x01)
2#define GAP_BROADCASTER_ROLE                    (0x02)
3#define GAP_CENTRAL_ROLE                        (0x04)
4#define GAP_OBSERVER_ROLE                       (0x08)
5#define privacy_enabled                         (0x00)
6#define device_name_char_len                    (0x08)
7static int bluenrg2_gap_init()
8
{
9    uint8_t cmd_buffer[3];
10    struct net_buf *buf;
11    cmd_buffer[0] = GAP_PERIPHERAL_ROLE;    //role
12    cmd_buffer[1] = privacy_enabled;        //privacy
13    cmd_buffer[2] = device_name_char_len;   //device_name_char_len
14    uint16_t ogf = 0x3f, ocf = 0x08a;
15    uint16_t opcode = (uint16_t)((ocf & 0x03ff)|(ogf << 10));
16    buf = bt_hci_cmd_create(opcode, sizeof(cmd_buffer));
17    if (!buf)
18    {
19        return -ENOBUFS;
20    }
21    net_buf_add_mem(buf, cmd_buffer, sizeof(cmd_buffer));
22    return bt_hci_cmd_send(opcode, buf);
23}

启动事件处理

对于启动流程的返回响应,需要由event_process()回调进行判断和推进。这里为了方便,只对CMD_COMPLETE事件进行判断处理,推进 Prepare 流程进行。

GAP 设置完成后调用bt_hci_set_prepare_ready()结束流程。

1void event_process(uint8_t event, struct net_buf *buf)
2
{
3    if(state == STATE_POLLING_PREPARING) // boot do nothing
4    {
5        if (event == BT_HCI_EVT_CMD_COMPLETE)  //only complete
6        {
7            printk("prepare_event_process, step: %d\n", step);
8            switch (step)
9            {
10            case 1//close host just now
11                bluenrg2_config_set_public_addr();  //step2  set_public_addr
12                step = 2;
13                break;
14            case 2:
15                bluenrg2_set_tx_power_level(14);  //step3  set_public_addr
16                step = 3;
17                break;
18            case 3:
19                bluenrg2_gatt_init();               //step4  gatt_ini
20                step = 4;
21                break;
22            case 4:
23                bluenrg2_gap_init();                //step5  gap_ini
24                step = 5;
25                break;
26            case 5:
27                bt_hci_set_prepare_ready();          //finish prepare
28                step = 0;
29                break;
30            }
31        }
32    }
33}

启动流程注册

将上述实现的启动流程的函数指针打包到bt_hci_chipset_driver结构体中,供协议栈调用注册。

1static const struct bt_hci_chipset_driver chipset_drv = {
2        init_work, boot_start, prepare_start, event_process,
3};
4// public drv API
5const struct bt_hci_chipset_driver *bt_hci_chipset_impl_local_instance(void)
6
{
7    return &chipset_drv;
8}


验证


完成 HCI 接口的时候虽然成功运行了 Beacon 例程,但 Beacon 例程是不需要进行 chipset 启动配置流程的(运行时启用的是common空白回调)。运行外设的心率例程验证 Bluenrg2 蓝牙芯片启动流程。

1 \ | /
2- RT -     Thread Operating System
3 / | \     5.0.1 build Sep 20 2023 22:16:27
4 2006 - 2022 Copyright by RT-Thread team
5do components initialization.
6initialize rti_board_end:0 done
7initialize stm32l4_hw_lptim_init:0 done
8initialize finsh_system_init:0 done
9msh >zephyr
10zephyr_polling_init 
11bt_init_hci_driver 
12SPI_init_process device_name: spi10, spi_name: spi1, rate: 1000000, databits: 8, LSB_MSB: 1, Master_Slave: 0, CPOL: 0, CPHA: 1
13SPI_init_process cs_pin_num: 1, irq_pin_num: 0
14hci_driver_open, SPI_config_finish
15I: (bt_hci_core)hci_init():3230: work start.
16msh >prepare_event_process, step: 1
17prepare_event_process, step: 2
18prepare_event_process, step: 3
19prepare_event_process, step: 4
20prepare_event_process, step: 5
21I: (bt_hci_core)hci_init_end():3205: work end.
22E: (bt_smp)smp_self_test():5695: smp_self_test start
23I: (bt_hci_core)bt_dev_show_info():3008: Identity: 02:80:e1:00:00:f5 (public)
24I: (bt_hci_core)bt_dev_show_info():3042: HCI: version 5.2 (0x0b) revision 0x1222, manufacturer 0x0030
25I: (bt_hci_core)bt_dev_show_info():3044: LMP: version 5.2 (0x0b) subver 0x0015
26Bluetooth initialized
27Advertising successfully started
28Connected
29BAS Notifications enabled
30HRS notifications enabled


prepare_event_process 步骤的日志输出正常,设备连接、电池服务、心率服务正常。


———————End——————




👇 点击阅读原文进入官网


RTThread物联网操作系统 帮助您了解RT-Thread相关的资讯.
评论
  • 新年伊始,又到了对去年做总结,对今年做展望的时刻 不知道你在2024年初立的Flag都实现了吗? 2025年对自己又有什么新的期待呢? 2024年注定是不平凡的一年, 一年里我测评了50余块开发板, 写出了很多科普文章, 从一个小小的工作室成长为科工公司。 展望2025年, 中国香河英茂科工, 会继续深耕于,具身机器人、飞行器、物联网等方面的研发, 我觉得,要向未来学习未来, 未来是什么? 是掌握在孩子们生活中的发现,和精历, 把最好的技术带给孩子,
    丙丁先生 2025-01-11 11:35 465浏览
  • 根据Global Info Research(环洋市场咨询)项目团队最新调研,预计2030年全球无人机电池和电源产值达到2834百万美元,2024-2030年期间年复合增长率CAGR为10.1%。 无人机电池是为无人机提供动力并使其飞行的关键。无人机使用的电池类型因无人机的大小和型号而异。一些常见的无人机电池类型包括锂聚合物(LiPo)电池、锂离子电池和镍氢(NiMH)电池。锂聚合物电池是最常用的无人机电池类型,因为其能量密度高、设计轻巧。这些电池以输出功率大、飞行时间长而著称。不过,它们需要
    GIRtina 2025-01-13 10:49 201浏览
  • 流量传感器是实现对燃气、废气、生活用水、污水、冷却液、石油等各种流体流量精准计量的关键手段。但随着工业自动化、数字化、智能化与低碳化进程的不断加速,采用传统机械式检测方式的流量传感器已不能满足当代流体计量行业对于测量精度、测量范围、使用寿命与维护成本等方面的精细需求。流量传感器的应用场景(部分)超声波流量传感器,是一种利用超声波技术测量流体流量的新型传感器,其主要通过发射超声波信号并接收反射回来的信号,根据超声波在流体中传播的时间、幅度或相位变化等参数,间接计算流体的流量,具有非侵入式测量、高精
    华普微HOPERF 2025-01-13 14:18 497浏览
  • 随着全球向绿色能源转型的加速,对高效、可靠和环保元件的需求从未如此强烈。在这种背景下,国产固态继电器(SSR)在实现太阳能逆变器、风力涡轮机和储能系统等关键技术方面发挥着关键作用。本文探讨了绿色能源系统背景下中国固态继电器行业的前景,并强调了2025年的前景。 1.对绿色能源解决方案日益增长的需求绿色能源系统依靠先进的电源管理技术来最大限度地提高效率并最大限度地减少损失。固态继电器以其耐用性、快速开关速度和抗机械磨损而闻名,正日益成为传统机电继电器的首选。可再生能源(尤其是太阳能和风能
    克里雅半导体科技 2025-01-10 16:18 331浏览
  • ARMv8-A是ARM公司为满足新需求而重新设计的一个架构,是近20年来ARM架构变动最大的一次。以下是对ARMv8-A的详细介绍: 1. 背景介绍    ARM公司最初并未涉足PC市场,其产品主要针对功耗敏感的移动设备。     随着技术的发展和市场需求的变化,ARM开始扩展到企业设备、服务器等领域,这要求其架构能够支持更大的内存和更复杂的计算任务。 2. 架构特点    ARMv8-A引入了Execution State(执行状
    丙丁先生 2025-01-12 10:30 471浏览
  • 数字隔离芯片是现代电气工程师在进行电路设计时所必须考虑的一种电子元件,主要用于保护低压控制电路中敏感电子设备的稳定运行与操作人员的人身安全。其不仅能隔离两个或多个高低压回路之间的电气联系,还能防止漏电流、共模噪声与浪涌等干扰信号的传播,有效增强电路间信号传输的抗干扰能力,同时提升电子系统的电磁兼容性与通信稳定性。容耦隔离芯片的典型应用原理图值得一提的是,在电子电路中引入隔离措施会带来传输延迟、功耗增加、成本增加与尺寸增加等问题,而数字隔离芯片的目标就是尽可能消除这些不利影响,同时满足安全法规的要
    华普微HOPERF 2025-01-15 09:48 83浏览
  •   在信号处理过程中,由于信号的时域截断会导致频谱扩展泄露现象。那么导致频谱泄露发生的根本原因是什么?又该采取什么样的改善方法。本文以ADC性能指标的测试场景为例,探讨了对ADC的输出结果进行非周期截断所带来的影响及问题总结。 两个点   为了更好的分析或处理信号,实际应用时需要从频域而非时域的角度观察原信号。但物理意义上只能直接获取信号的时域信息,为了得到信号的频域信息需要利用傅里叶变换这个工具计算出原信号的频谱函数。但对于计算机来说实现这种计算需要面对两个问题: 1.
    TIAN301 2025-01-14 14:15 113浏览
  • 01. 什么是过程能力分析?过程能力研究利用生产过程中初始一批产品的数据,预测制造过程是否能够稳定地生产符合规格的产品。可以把它想象成一种预测。通过历史数据的分析,推断未来是否可以依赖该工艺持续生产高质量产品。客户可能会要求将过程能力研究作为生产件批准程序 (PPAP) 的一部分。这是为了确保制造过程能够持续稳定地生产合格的产品。02. 基本概念在定义制造过程时,目标是确保生产的零件符合上下规格限 (USL 和 LSL)。过程能力衡量制造过程能多大程度上稳定地生产符合规格的产品。核心概念很简单:
    优思学院 2025-01-12 15:43 533浏览
  • 在不断发展的电子元件领域,继电器——作为切换电路的关键设备,正在经历前所未有的技术变革。固态继电器(SSR)和机械继电器之间的争论由来已久。然而,从未来发展的角度来看,固态继电器正逐渐占据上风。本文将从耐用性、速度和能效三个方面,全面剖析固态继电器为何更具优势,并探讨其在行业中的应用与发展趋势。1. 耐用性:经久耐用的设计机械继电器:机械继电器依靠物理触点完成电路切换。然而,随着时间的推移,这些触点因电弧、氧化和材料老化而逐渐磨损,导致其使用寿命有限。因此,它们更适合低频或对切换耐久性要求不高的
    腾恩科技-彭工 2025-01-10 16:15 109浏览
  • 随着通信技术的迅速发展,现代通信设备需要更高效、可靠且紧凑的解决方案来应对日益复杂的系统。中国自主研发和制造的国产接口芯片,正逐渐成为通信设备(从5G基站到工业通信模块)中的重要基石。这些芯片凭借卓越性能、成本效益及灵活性,满足了现代通信基础设施的多样化需求。 1. 接口芯片在通信设备中的关键作用接口芯片作为数据交互的桥梁,是通信设备中不可或缺的核心组件。它们在设备内的各种子系统之间实现无缝数据传输,支持高速数据交换、协议转换和信号调节等功能。无论是5G基站中的数据处理,还是物联网网关
    克里雅半导体科技 2025-01-10 16:20 449浏览
  • 食物浪费已成为全球亟待解决的严峻挑战,并对环境和经济造成了重大影响。最新统计数据显示,全球高达三分之一的粮食在生产过程中损失或被无谓浪费,这不仅导致了资源消耗,还加剧了温室气体排放,并带来了巨大经济损失。全球领先的光学解决方案供应商艾迈斯欧司朗(SIX:AMS)近日宣布,艾迈斯欧司朗基于AS7341多光谱传感器开发的创新应用来解决食物浪费这一全球性难题。其多光谱传感解决方案为农业与食品行业带来深远变革,该技术通过精确判定最佳收获时机,提升质量控制水平,并在整个供应链中有效减少浪费。 在2024
    艾迈斯欧司朗 2025-01-14 18:45 68浏览
  • 随着数字化的不断推进,LED显示屏行业对4K、8K等超高清画质的需求日益提升。与此同时,Mini及Micro LED技术的日益成熟,推动了间距小于1.2 Pitch的Mini、Micro LED显示屏的快速发展。这类显示屏不仅画质卓越,而且尺寸适中,通常在110至1000英寸之间,非常适合应用于电影院、监控中心、大型会议、以及电影拍摄等多种室内场景。鉴于室内LED显示屏与用户距离较近,因此对于噪音控制、体积小型化、冗余备份能力及电气安全性的要求尤为严格。为满足这一市场需求,开关电源技术推出了专为
    晶台光耦 2025-01-13 10:42 512浏览
  • PNT、GNSS、GPS均是卫星定位和导航相关领域中的常见缩写词,他们经常会被用到,且在很多情况下会被等同使用或替换使用。我们会把定位导航功能测试叫做PNT性能测试,也会叫做GNSS性能测试。我们会把定位导航终端叫做GNSS模块,也会叫做GPS模块。但是实际上他们之间是有一些重要的区别。伴随着技术发展与越发深入,我们有必要对这三个词汇做以清晰的区分。一、什么是GPS?GPS是Global Positioning System(全球定位系统)的缩写,它是美国建立的全球卫星定位导航系统,是GNSS概
    德思特测试测量 2025-01-13 15:42 500浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦