当前位置: 首页 > 工具软件 > btstack > 使用案例 >

蓝牙协议栈(三、如何配置Btstack)

孙言
2023-12-01

BTstack实现了一组蓝牙协议和配置文件。要连接其他蓝牙设备或提供蓝牙服务,必须正确配置BTstack。

BTstack的配置既可以在编译时完成,也可以在运行时完成:

  • 编译时配置:

    • adjust btstack_config.h - 此文件描述系统配置,使用的功能以及内存配置

    • 将必要的源代码文件添加到项目中

  • 运行时配置:

    • 蓝牙芯片组

    • 运行循环

    • HCI传输层

    • 提供的服务

    • 包处理程序

在下文中,我们概述了设置BTstack所需的配置。从执行运行循环开始,应用程序作为有限状态机运行,处理从BTstack接收的事件。BTstack在逻辑上对事件进行分组,并通过数据包处理程序提供它们。我们在此提供他们的概述。对于需要检查BTstack和蓝牙芯片组之间交换的数据的情况,我们描述了如何配置数据包记录机制。最后,我们概述了蓝牙中的电源管理以及如何在BTstack中节省能源。

在btstack_config.h中配置

文件btstack_config.h包含三个部分:

  • 此处列出了 #define HAVE_ *指令。这些指令描述了可用的系统属性,类似于autoconf设置中的config.h。

  • 此处列出了 #define ENABLE_ *指令。这些指令列出了启用的属性,最重要的是ENABLE_CLASSIC和ENABLE_BLE。

  • 其他用于BTstack配置的#define指令,最值得注意的是静态内存,请参阅下一节NVM配置

HAVE_ *指令

系统属性:

#限定

描述

HAVE_MALLOC

使用动态内存

HAVE_AES128

使用平台AES128引擎 - 通常不需要

HAVE_BTSTACK_STDIN

STDIN可用于CLI界面

HAVE_MBEDTLS_ECC_P256

mbedTLS提供NIST P-256操作,例如LE安全连接

嵌入式平台属性:

#限定

描述

HAVE_EMBEDDED_TIME_MS

系统提供以毫秒为单位的时间

HAVE_EMBEDDED_TICK

系统提供滴答中断

FreeRTOS平台属性:

#限定

描述

HAVE_FREERTOS_INCLUDE_PREFIX

FreeRTOS标题位于'freertos'文件夹中(例如ESP32的esp-idf)

POSIX平台属性:

#限定

描述

HAVE_POSIX_B300_MAPPED_TO_2000000

解决方法是使用2 mbps的串行端口

HAVE_POSIX_B600_MAPPED_TO_3000000

解决方法使用3 mpbs的串行端口

HAVE_POSIX_FILE_IO

POSIX文件i / o用于hci转储

HAVE_POSIX_TIME

系统提供时间功能

LINK_KEY_PATH

存储链接密钥的路径

LE_DEVICE_DB_PATH

存储LE设备信息的路径

 

 

 

 

ENABLE_ *指令

BTstack属性:

#限定

描述

ENABLE_CLASSIC

在HCI和L2CAP中启用经典相关代码

ENABLE_BLE

在HCI和L2CAP中启用BLE相关代码

ENABLE_EHCILL

在TI CC256x / WL18xx芯片组上启用eHCILL低功耗模式

ENABLE_LOG_DEBUG

启用log_debug消息

ENABLE_LOG_ERROR

启用log_error消息

ENABLE_LOG_INFO

启用log_info消息

ENABLE_SCO_OVER_HCI

为芯片组启用SCO over HCI(如果支持)

ENABLE_HFP_WIDE_BAND_SPEECH

启用对宽带语音的HFP配置文件中使用的mSBC编解码器的支持

ENBALE_LE_PERIPHERAL

在HCI和安全管理器中启用对LE外设角色的支持

ENBALE_LE_CENTRAL

在HCI和安全管理器中启用对LE Central角色的支持

ENABLE_LE_SECURE_CONNECTIONS

启用LE安全连接

ENABLE_LE_CENTRAL_AUTO_ENCRYPTION

在重新连接时为绑定设备启用自动加密

ENABLE_GATT_CLIENT_PAIRING

启用GATT Client以开始配对并重试安全性错误操作

ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS

使用micro-ecc库进行ECC操作

ENABLE_LE_DATA_CHANNELS

在基于信用的流量控制模式下启用LE数据通道

ENABLE_LE_DATA_LENGTH_EXTENSION

启用LE数据长度扩展支持

ENABLE_LE_SIGNED_WRITE

在ATT / GATT中启用LE签名写入

ENABLE_ATT_DELAYED_RESPONSE

启用对延迟ATT操作的支持,请参阅GATT Server

ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE

启用L2CAP增强重传模式。AVRCP浏览必须提供

ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL

启用HCI控制器以主机流量控制,请参见下文

ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND

在波特率更改期间启用CC256x流量控制中的错误解决方法,请参阅芯片组文档。

ENABLE_CYPRESS_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND

在波特率更改期间启用CYW2070x流量控制中的错误解决方法,类似于CC256x。

ENABLE_TLV_FLASH_EXPLICIT_DELETE_FIELD

在TLV Flash实现中启用显式删除字段 - 当无法用零覆盖闪存值时需要

笔记:

  • ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS:只有一些蓝牙4.2+控制器(例如,EM9304,ESP32)支持ECC的必要HCI命令。启用ECC软件实现的其他原因是主机速度更快或者是否已提供micro-ecc库(例如,ESP32,WICED,或者ECC HCI命令不可靠)。

HCI控制器主机流量控制

通常,BTstack依靠HCI传输的流量控制,通过UART的硬件CTS / RTS流量控制或常规USB流量控制。如果这不可能,例如在SoC上,BTstack可以通过定义ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL来使用HCI控制器来主机流控制。如果启用,则HCI传输实现必须能够缓冲指定的数据包。此外,它还需要能够缓冲一些HCI事件。使用较少数量的主机缓冲区可能会导致吞吐量降低。

HCI控制器到主机流控制的主机缓冲区配置:

#限定

描述

HCI_HOST_ACL_PACKET_NUM

最大ACL包数

HCI_HOST_ACL_PACKET_LEN

HCI主机ACL数据包的最大大小

HCI_HOST_SCO_PACKET_NUM

最大ACL包数

HCI_HOST_SCO_PACKET_LEN

HCI主机SCO数据包的最大大小

内存配置指令

服务,活动连接和远程设备的结构可以用两种不同的方式分配:

  • 静态来自单个内存池,其最大数量的元素在btstack_config.h文件中定义。要初始化静态池,需要在运行时调用btstack_memory_init函数。清单{@lst:memoryConfigurationSPP}中显示了具有最小L2CAP MTU的单个SPP服务的内存配置示例。

  • 如果在btstack_config.h文件中定义了HAVE_MALLOC,则动态使用malloc / free函数。

对于每个HCI连接,保留大小为HCI_ACL_PAYLOAD_SIZE的缓冲区。但是,对于快速数据传输,建议使用1021字节的大型ACL缓冲区。要使用3-DH5数据包,需要大型ACL缓冲区。

#限定

描述

HCI_ACL_PAYLOAD_SIZE

HCI ACL有效负载的最大大小

MAX_NR_BNEP_CHANNELS

最大BNEP通道数

MAX_NR_BNEP_SERVICES

BNEP服务的最大数量

MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES

RAM中缓存的最大链接密钥条目数

MAX_NR_GATT_CLIENTS

GATT客户的最大数量

MAX_NR_HCI_CONNECTIONS

最大HCI连接数

MAX_NR_HFP_CONNECTIONS

最大HFP连接数

MAX_NR_L2CAP_CHANNELS

最大L2CAP连接数

MAX_NR_L2CAP_SERVICES

最大L2CAP服务数

MAX_NR_RFCOMM_CHANNELS

最大RFOMMM连接数

MAX_NR_RFCOMM_MULTIPLEXERS

最大数量的RFCOMM多路复用器,每个HCI连接有一个多路复用器

MAX_NR_RFCOMM_SERVICES

最大数量的RFCOMM服务

MAX_NR_SERVICE_RECORD_ITEMS

最大SDP服务记录数

MAX_NR_SM_LOOKUP_ENTRIES

Security Manager查找队列中的最大项目数

MAX_NR_WHITELIST_ENTRIES

要连接的GAP LE白名单中的最大项目数

MAX_NR_LE_DEVICE_DB_ENTRIES

LE设备DB中的最大项目数

通过调用btstack_memory_init函数来设置内存:

btstack_memory_init();

这是基本SPP服务器的内存配置。

#define HCI_ACL_PAYLOAD_SIZE 52#define MAX_NR_HCI_CONNECTIONS 1#define MAX_NR_L2CAP_SERVICES 2#define MAX_NR_L2CAP_CHANNELS 2#define MAX_NR_RFCOMM_MULTIPLEXERS 1#define MAX_NR_RFCOMM_SERVICES 1#define MAX_NR_RFCOMM_CHANNELS 1#define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 3

清单:基本SPP服务器的内存配置。{#lst:memoryConfigurationSPP}

在此示例中,ACL数据包的大小限制为最小52个字节,从而导致L2CAP MTU为48个字节。任何时候都只能建立一个单一的连接。在其上,提供了两个L2CAP服务,它们可以同时处于活动状态。这里,这两个可以是RFCOMM和SDP。然后,保留一个RFCOMM多路复用器的存储器,其中一个连接可以是活动的。最后,最多可以将三个链接密钥缓存在RAM中。

非易失性存储器(NVM)指令

如果实现,则绑定信息存储在非易失性存储器中。对于Classic,存储单个链接键及其类型。对于LE,绑定信息包含各种值(长期密钥,随机数,EDIV,签名计数器,标识......)通常,这是使用闪存实现的。然后,存储的条目数受以下因素限制:

#限定

描述

NVM_NUM_LINK_KEYS

可存储的最大经典链接密钥数

NVM_NUM_DEVICE_DB_ENTRIES

可存储的LE设备DB条目的最大数量

NVN_NUM_GATT_SERVER_CCC

GATT Server可以存储的最大“客户端特征配置”值

源树结构

源树已经组织起来,可以轻松设置新项目。

路径

描述

芯片组

支持单个蓝牙控制器芯片组

DOC

BTstack文档的来源

可用于所有端口的示例应用程序

平台

支持特殊操作系统和/或MCU架构

港口

完整的MCU +芯片组组合端口

SRC

蓝牙堆栈实现

测试

单元和PTS测试

工具

BTstack的助手工具

BTstack的核心,包括所有协议和配置文件,都在src /中。

平台/子文件夹提供对特定平台的支持。对于大多数嵌入式端口,platform / embedded /提供了btstack_run_loop_embedded和hci_transport_h4_embedded实现,需要hal_cpu.h,hal_led.h和hal_uart_dma.h以及hal_tick.h或hal_time_ms来实现。

为了适应特定的蓝牙芯片组,芯片组/子文件夹提供各种btstack_chipset_ 实现。请查看端口/ * 中的现有端口。

运行循环配置

要初始化BTstack,您需要分别初始化内存 和运行循环,然后设置HCI和所有需要的更高级别协议。

BTstack使用运行循环的概念来处理传入的数据并安排工作。运行循环处理来自两种不同类型的源的事件:数据源和计时器。数据源代表通信接口,如UART或USB驱动程序。BTstack使用定时器来实现各种与蓝牙相关的超时。它们还可用于处理定期事件。

数据源和计时器分别由btstack_data_source_t和 btstack_timer_source_t结构表示。这些结构中的每一个至少包含一个链表节点和一个指向回调函数的指针。所有活动的计时器和数据源都保存在链接列表中。虽然数据源列表未排序,但计时器按到期超时排序以进行有效处理。

定时器是单发的:在执行事件处理程序回调之前,计时器将从计时器列表中删除。如果需要周期性定时器,可以在回调函数中重新注册相同的定时器源,如清单[PeriodicTimerHandler]所示。请注意,BTstack期望定期调用以保持其时间,有关滴答硬件抽象的更多内容,请参阅时间抽象部分 。

BTstack提供了实现btstack_run_loop_t接口的不同运行循环实现:

  • 嵌入式:嵌入式系统的主要实现,特别是没有RTOS。

  • FreeRTOS:在专用的FreeRTOS线程上运行BTstack的实现

  • POSIX:基于select()调用的POSIX系统实现。

  • CoreFoundation:iOS和OS X应用程序的实现

  • WICED:包含FreeRTOS或ThreadX的Broadcom WICED SDK RTOS抽象的实现。

  • Windows:基于Event对象和WaitForMultipleObjects()调用的Windows实现。

根据平台,数据源可以被轮询(嵌入式,FreeRTOS),或者平台提供了一种等待数据源准备好进行读取或写入的方法(POSIX,CoreFoundation,Windows),或者不用作HCI传输驱动程序和运行循环以不同的方式实现(WICED)。在任何情况下,必须使用btstack_run_loop_enable_data_source_callbacks(..)函数显式启用回调。

在您的代码中,您必须在启动之前配置运行循环,如清单[listing:btstackInit]所示。该应用程序可以注册数据源和定时器,例如,用于传感器的定期采样,或用于通过UART进行通信。

通过调用btstack_run_loop_init函数并提供实际运行循环的实例来设置运行循环。例如,对于嵌入式平台,它是:

btstack_run_loop_init(btstack_run_loop_embedded_get_instance());

此处提供完整的Run循环API 。

运行循环嵌入

在嵌入式运行循环实现中,如果在轮询所有数据源期间没有发生IRQ,则不断轮询数据源并使系统进入休眠状态。

完整的运行循环周期如下所示:首先,以循环方式调用所有已注册数据源的回调函数。然后,执行准备好的定时器的回调函数。最后,将检查中断处理程序是否已请求另一个运行循环迭代。如果没有,运行循环将使MCU进入睡眠模式。

通过UART,USB或定时器滴答的输入数据将产生中断并唤醒微控制器。为了避免在运行循环进入睡眠模式之前数据源就绪的情况,中断驱动的数据源必须调用 btstack_run_loop_embedded_trigger函数。对btstack_run_loop_embedded_trigger的调用 设置了一个内部标志,该标志在进入睡眠模式之前在临界区中进行检查,从而导致另一个运行循环周期。

要启用计时器,请确保在配置文件中定义了HAVE_EMBEDDED_TICK或HAVE_EMBEDDED_TIME_MS。

运行循环FreeRTOS

FreeRTOS运行循环用于专用的FreeRTOS线程,它使用FreeRTOS队列来调度运行循环的回调。在每次迭代中:

  • 对所有数据源进行轮询

  • 所有预定的回调都会被执行

  • 所有过期的计时器都被调用

  • 最后,它获得了下一次超时。然后等待“触发”或下一次超时(如果已设置)。

要触发运行循环,可以调用btstack_run_loop_freertos_trigger和btstack_run_loop_freertos_trigger_from_isr。这会导致数据源被轮询。

另外。btstack_run_loop_freertos_execute_code_on_main_thread可用于在主循环上调度回调。请注意,队列是有限的(请参阅btstack_run_loop_embedded中的RUN_LOOP_QUEUE_LENGTH)。

运行循环POSIX

数据源是标准文件描述符。在运行循环执行实现中,select()调用用于等待文件描述符准备好读取或写入,同时等待下一个超时。

要启用计时器,请确保在配置文件中定义了HAVE_POSIX_TIME。

运行循环CoreFoundation(OS X / iOS)

此运行循环直接将BTstack的数据源和计时器源映射到CoreFoundation对象。它支持类似于POSIX实现的准备读写。然后调用 btstack_run_loop_execute()只调用CFRunLoopRun()。

要启用计时器,请确保在配置文件中定义了HAVE_POSIX_TIME。

运行循环Windows

数据源是Event对象。在运行循环实现中,WaitForMultipleObjects()调用all用于等待Event对象在等待下一个超时时变为就绪状态。

运行循环WICED

WICED SDK API不提供对UART的异步读写,也没有直接等待一个或多个外设准备就绪的方法。因此,BTstack不提供对数据源的直接支持。相反,运行循环提供了一个消息队列,允许通过btstack_run_loop_wiced_execute_code_on_main_thread()在其线程上调度函数调用 。

然后,HCI传输H4实现使用两个轻量级线程来执行阻塞读取和写入操作。在辅助线程上完成读取或写入操作时,将安排对BTstack的回调。

HCI传输配置

HCI初始化必须使BTstack适应所使用的平台。第一个调用是hci_init(),需要有关要使用的HCI传输的信息。论点是:

  • HCI传输实施:在嵌入式系统上,可以通过USB或UART端口连接蓝牙模块。在嵌入式设备上,BTstack实现了HCI UART传输层(H4)和H4,支持eHCILL,这是德州仪器(TI)的轻量级低功耗变体。对于POSIX,有HCI H4,HCI H5和H2 libUSB以及WICED HCI H4 WICED的实现。通过链接相应的文件(例如 platform / embedded / hci_transport_h4_embedded.c) 然后获取指向HCI传输实现的指针来访问它们。有关将HCI传输适应不同环境的更多信息,请参见此处

hci_transport_t * transport = hci_transport_h4_instance();

  • HCI传输配置:由于H4传输接口中使用的UART的配置未标准化,因此必须由主应用程序提供给BTstack。除初始UART波特率外,还可以指定主波特率。在蓝牙模块的基本设置之后,BTstack的HCI层将初始波特率更改为主波特率。必须在HCI和硬件级别以协调的方式进行波特率更改。例如,在CC256x上,首先发送更改波特率的HCI命令,然后必须等待蓝牙模块的确认事件。只有现在,UART波特率才能改变。

hci_uart_config_t* config = &hci_uart_config;

在这些准备好之后,HCI被初始化为:

hci_init(transport, config);

除此之外,大多数基于UART的蓝牙芯片组都需要一些特殊的逻辑来进行正确的初始化,蓝牙规范未涵盖这些逻辑。特别是,这包括:

  • 设置波特率

  • 为没有内部永久存储的设备设置BD ADDR

  • 上传一些固件补丁。

这是由芯片组/子文件夹中的各种btstack_chipset_t实现提供的。例如,bstack_chipset_cc256x_instance函数返回一个指向适用于CC256x芯片组的芯片组结构的指针。

btstack_chipset_t * chipset = btstack_chipset_cc256x_instance();

hci_set_chipset(chipset);

在某些设置中,硬件设置可以明确控制蓝牙功率和睡眠模式。在这种情况下,可以使用hci_set_control设置btstack_control_t结构。

最后,HCI实现需要某种形式的持久存储,用于在传统配对或安全简单配对(SSP)期间生成的链接密钥。这通常需要特定于平台的代码才能访问MCU的闪存存储器EEPROM。对于第一步,BTstack在内存中提供(非)持久性存储。欲了解更多请参见这里

btstack_link_key_db_t * link_key_db = &btstack_link_key_db_memory_instance();

btstack_set_link_key_db(link_key_db);

较高层仅依赖于BTstack并通过调用相应的* _init函数进行初始化。这些init函数将自己注册到底层。此外,应用程序可以注册数据包处理程序以获取事件和数据,如以下部分所述。

服务

BTstack的一个重要构造是服务。服务表示处理传入连接的服务器端组件。到目前为止,BTstack提供L2CAP,BNEP和RFCOMM服务。L2CAP服务处理L2CAP信道的传入连接,并使用其协议服务多路复用器ID(PSM)进行注册。同样,RFCOMM服务处理传入的RFCOMM连接,并使用RFCOMM通道ID进行注册。传出连接不需要特殊注册,它们是在需要时由应用程序创建的。

数据包处理程序配置

设置硬件和BTstack后,进入运行循环。从现在开始,一切都是事件驱动的。应用程序调用BTstack函数,BTstack函数又可以向蓝牙模块发送命令。生成的事件将传递回应用程序。BTstack不是为每个可能的事件编写单个回调处理程序(在其他一些蓝牙堆栈中完成),而是逻辑地对事件进行分组,并通过单个通用接口提供它们。附录 事件和错误 总结了L2CAP和RFCOMM事件的参数和事件代码,以及可能的错误和相应的错误代码。

以下是应用程序可能使用的数据包处理程序的汇总列表:

  • HCI事件处理程序 - 允许观察HCI,GAP和一般BTstack事件。

  • L2CAP数据包处理程序 - 处理LE连接参数requeset更新

  • L2CAP服务数据包处理程序 - 处理传入的L2CAP连接,即由远程启动的通道。

  • L2CAP信道数据包处理程序 - 处理传出的L2CAP连接,即内部启动的信道。

  • RFCOMM服务包处理程序 - 处理传入的RFCOMM连接,即由远程启动的通道。

  • RFCOMM信道数据包处理程序 - 处理传出的RFCOMM连接,即内部启动的信道。

这些处理程序使用下表列出的函数进行了注册 。

包处理程序

注册功能

HCI包处理程序

hci_add_event_handler

L2CAP包处理程序

l2cap_register_packet_handler

L2CAP服务包处理程序

l2cap_register_service

L2CAP通道包处理程序

l2cap_create_channel

RFCOMM服务包处理程序

rfcomm_register_service和rfcomm_register_service_with_initial_credits

RFCOMM频道包处理程序

rfcomm_create_channel和rfcomm_create_channel_with_initial_credits

表:注册数据包处理程序的函数。

HCI,GAP和一般BTstack事件被传递到由hci_add_event_handler函数指定的数据包处理程序。在L2CAP中,BTstack区分传入和传出连接,即事件和数据包被传递给不同的数据包处理程序。传出连接用于访问远程服务,传入连接用于提供服务。对于传入连接,使用由l2cap_register_service指定的数据包处理程序。对于传出连接, 使用l2cap_create_channel提供的处理程序。RFCOMM和BNEP类似。

应用程序可以为所有协议和服务注册单个共享数据包处理程序,或为每个协议层和服务使用单独的数据包处理程序。共享数据包处理程序通常用于堆栈初始化和连接管理。

单独的数据包处理程序可用于每个L2CAP服务和传出连接。例如,要连接蓝牙HID键盘,您的应用程序可以使用三个数据包处理程序:一个用于在发现由l2cap_register_packet_handler注册的键盘期间处理HCI事件 ; 一个将注册到外发L2CAP频道以连接到键盘并接收由l2cap_create_channel注册的键盘数据; 之后键盘可以自行重新连接。为此,您需要使用l2cap_register_service为HID控制和HID中断PSM注册L2CAP服务 。在此调用中,您还将指定一个数据包处理程序来接受和接收键盘数据。

所有事件名称现在都具有MODULE_EVENT_NAME形式,例如gap_event_-advertising_report。为了便于处理事件并摆脱手动计算数据包的偏移量,BTstack为src / hci_event.h中所有事件的所有字段提供自动生成的getter 。所有函数都定义为静态内联,因此如果不使用它们就不会浪费任何程序内存。如果使用,则内存占用量应与通过偏移量直接访问数据包相同。例如,要从gap_event_advertising_report事件访问字段address_type和address,请使用以下getter:

uint8_t address type = gap_event_advertising_report_get_address_type(event);

bd_addr_t address;

gap_event_advertising_report_get_address(event, address);

蓝牙HCI数据包日志

如果事情没有按预期工作,那么看看BTstack和蓝牙芯片组之间交换的数据通常会有所帮助。

为此,BTstack通过hci_dump.h提供可配置的数据包记录机制:

// formats: HCI_DUMP_BLUEZ, HCI_DUMP_PACKETLOGGER, HCI_DUMP_STDOUTvoid hci_dump_open(const char *filename, hci_dump_format_t format);

在POSIX系统上,您可以在设置中使用路径和HCI_DUMP_BLUEZ 或HCI_DUMP_PACKETLOGGER调用hci_dump_open,即在进入运行循环之前。可以使用Wireshark或Apple的PacketLogger工具分析生成的文件。

在没有文件系统的嵌入式系统上,您仍然可以调用hci_dump_open(NULL,HCI_DUMP_STDOUT)。它将通过printf将所有HCI数据包记录到控制台。如果您捕获控制台输出,包括 您自己的调试消息,您可以使用tools文件夹中的create_packet_log.py工具将文本输出转换为PacketLogger文件。

除了HCI数据包,您还可以通过添加启用BTstack的调试信息

#define ENABLE_LOG_INFO

#define ENABLE_LOG_ERROR

到btstack_config.h并重新编译你的应用程序。

蓝牙电源控制

在大多数BTstack示例中,设备设置为可发现且可连接。在此模式下,即使没有活动连接,蓝牙控制器也会定期激活其接收器,以便侦听查询或连接来自其他设备的请求。能够被发现的能力需要比连接能力更多的能量。可被发现也向该地区的任何人宣布该设备。因此,在不需要时暂停监听查询是个好主意。其他具有蓝牙地址的设备仍可以连接到您的设备。

要启用/禁用可发现性,您可以致电:

/**

* @brief Allows to control if device is discoverable. OFF by default.

*/

void gap_discoverable_control(uint8_t enable);

如果您不需要在较长时间内从其他设备连接,则还可以禁用侦听连接请求。

要启用/禁用可连接性,您可以调用:

/**

* @brief Override page scan mode. Page scan mode enabled by l2cap when services are registered

* @note Might be used to reduce power consumption while Bluetooth module stays powered but no (new)

* connections are expected

*/

void gap_connectable_control(uint8_t enable);

对于蓝牙低功耗,无线电周期性地用于广播用于发现和建立连接的广告。

要启用/禁用广告,您可以致电:

/**

* @brief Enable/Disable Advertisements. OFF by default.

* @param enabled

*/

void gap_advertisements_enable(int enabled);

如果蓝牙控制器既不可发现也不可连接,则无需定期打开其无线电,只需响应来自主机的命令。在这种情况下,蓝牙控制器可以自由地进入某种深度睡眠,其中功耗最小。

最后,如果这对您的应用程序来说还不够,您可以请求BTstack关闭蓝牙控制器。为此,必须实现btstack_control_t结构中的“on”和“off”函数。要关闭蓝牙控制器,您可以致电:

/**

* @brief Requests the change of BTstack power mode.

*/

int hci_power_control(HCI_POWER_MODE mode);

模式设置为HCI_POWER_OFF。稍后需要时,可以通过以模式HCI_POWER_ON调用蓝牙再次启动蓝牙,如所有示例中所示。

 

 类似资料: