Silicon labs BLE 开发人员指南

  • 介绍

该文档涵盖了各个方面的发展,并且是对使用C开发的所有运行Bluetooth堆栈的Wireless Gecko产品的所有人的重要参考。

该文档涵盖以下主题:

  • “ 应用程序开发流程”部分讨论了应用程序开发流程和项目结构。

  • 部分配置的蓝牙协议栈和无线设备壁虎解释该项目包括库和应用程序代码的实际无线壁虎配置。

  • 第蓝牙堆栈事件处理是每个人与Silicon Labs的蓝牙协议栈开发的一个重要部分,因为它说明了在基于事件的架构堆栈的同步运行应用程序如何。

  • “ 中断和无线Gecko资源 ”部分讨论了外设和芯片组资源的主题,涵盖了为堆栈使用保留的内容,应如何处理中断以及堆栈的内存占用空间和应用程序可用内存。

  • 应用开发流程

下图描述了高级固件结构。开发人员在堆栈的顶部创建一个应用程序,Silicon Labs将其作为预编译的目标文件提供给应用程序,从而为最终设备实现蓝牙连接。

蓝牙堆栈架构框图

蓝牙堆栈包含以下块。

  • 引导加载程序— Gecko引导加载程序不是堆栈的一部分,而是随蓝牙SDK一起提供的。有关更多信息,请参见UG266:Gecko引导程序用户指南和AN1086:将Gecko引导程序与Silicon Labs蓝牙应用程序配合使用。有关常规引导加载的信息,请参见UG103.06:引导加载基础。

  • 蓝牙堆栈-蓝牙功能,包括链接层,通用访问配置文件,安全管理器,属性协议和通用属性配置文件。

  • 蓝牙AppLoader-在引导程序之后启动的应用程序。它检查用户应用程序是否有效,如果有效,则AppLoader启动该应用程序。如果应用程序映像无效,则AppLoader将启动OTA进程以尝试接收有效的应用程序映像。这需要使用Gecko Bootloader。

  • 应用程序构建流程

蓝牙项目构建流程

按照QSG139:Simplicity Studio中的蓝牙应用程序开发中的描述,通过定义蓝牙服务和特性(GATT定义)并编写来自Silicon Labs提供的示例的应用程序源代码或空的项目模板开始构建项目。SDK v2.1.0和更高版本提供了两种定义蓝牙服务和特性的方法。第一个选项是Simplicity Studio中的Visual GATT编辑器GUI。这是用于设计GATT并生成gatt_db.c和gatt_db.h的图形工具。此外,它可以导入.xml和.bgproj GATT定义文件。Visual GATT编辑器是Simplicity Studio项目中用于GATT定义和生成的默认工具。第二种选择是根据UG118:Blue GeckoBluetooth®Profile Toolkit开发人员指南创建.xml或.bgproj,然后将BGBuild可执行文件用作预编译步骤,以将GATT定义文件转换为.c和.h。此方法在IAR Embedded Workbench项目中使用。编译项目会生成一个目标文件,然后将其与SDK中提供的预编译库链接。链接的输出是一个闪存图像,可以对支持的Wireless Gecko设备进行编程。

  • 项目结构

本节说明了应用程序项目结构以及必须包含在项目中的必需和可选资源。

  • 蓝牙文件

库文件:

蓝牙堆栈库是:

  • binapploader.o:蓝牙AppLoader的二进制映像,提供了可选的OTA(无线)功能。

  • binapploader_nvm3.o:具有NVM3支持的Series 1的Bluetooth AppLoader的二进制映像。

  • libbluetooth.a:蓝牙堆栈库。

  • libmbedtls.a:蓝牙堆栈的mbed TLS加密库。

  • libpsstore.a:蓝牙堆栈的PS Store功能。这在EFR32BG2x器件上不可用。必须改用NVM3。

RAIL:

蓝牙堆栈使用RAIL访问无线电,并且RAIL库需要与蓝牙堆栈链接。对于每个设备系列以及单协议和多协议环境,RAIL都有单独的库。Gecko SDK中提供了RAIL库。有关更多信息,请参考UG103.13:RAIL基础知识和其他RAIL文档。

注意:为了确保无线电模块符合法规要求,需要将无线电模块的蓝牙堆栈与无线电模块的RAIL库和配置库链接在一起。这些是librail_module__release.a和librail_conFIG。一个。

EMLIB和EMDRV:

蓝牙堆栈使用EMLIB和EMDRV库访问EFR32硬件。EMLIB和EMDRV外设库在源代码中提供,并且需要包含在项目中。EMLIB和EMDRV是Gecko SDK的一部分。有关EMLIB和EMDRV的更多详细信息,请参阅《 Gecko Bootloader API参考》中的\ platform \ bootloader \ documentation \ Gecko_Bootloader_API_Reference \ index.html,以及相应文件夹下的文档 \平台。

睡眠定时器

睡眠计时器是一个平台组件,提供单次计时器和定期计时器。蓝牙协议栈将其用于深度睡眠,并且必须包含在项目中。

头文件

bg_version.h

该文件包含蓝牙协议栈版本。

API头文件

这些文件定义了蓝牙协议栈API。对于不同的用例,有三个不同的文件。只能包含其中一个文件。native_gecko.h与裸机蓝牙应用程序一起使用。在构建支持NCP的SoC应用程序时使用ncp_gecko.h。rtos_gecko.h与Micrium RTOS一起使用。

这些文件用于两个目的:首先,它们包含实际的Bluetooth堆栈API以及该堆栈的命令和事件;其次,它们为Bluetooth堆栈提供配置,事件和睡眠管理API。

下面介绍了配置,事件和睡眠管理API。

errorcode_t gecko_init(const gecko_configuration_t*config)

该函数接受一个参数-指向gecko_configuration_t结构的指针。其目的是使用结构中提供的参数配置和初始化Bluetooth堆栈。gecko_init()在使用gecko_stack_init()进行的蓝牙配置一节中将详细讨论配置选项及其使用方法。gecko_init()必须由应用程序调用以初始化蓝牙堆栈。

提供此功能是为了方便。它将初始化蓝牙堆栈中的所有功能。要使配置更加详细,请按以下说明使用gecko_stack_init()。

errorcode_t gecko_stack_init(const gecko_configuration_t*config)

此函数接受一个参数-指向gecko_configuration_t结构的指针。其目的是使用结构中提供的参数配置和初始化Bluetooth堆栈。gecko_stack_init()调用函数后,必须分别初始化每个使用的堆栈组件。这种分离允许通过不包括那些不需要的堆栈组件来优化内存。

以下API可用于分别初始化堆栈组件:

gecko_bgapi_class_dfu_init();gecko_bgapi_class_system_init();gecko_bgapi_class_le_gap_init();gecko_bgapi_class_le_connection_init();gecko_bgapi_class_gatt_init();gecko_bgapi_class_gatt_server_init();gecko_bgapi_class_endpoint_init();gecko_bgapi_class_hardware_init();gecko_bgapi_class_flash_init();gecko_bgapi_class_test_init();gecko_bgapi_class_sm_init();struct gecko_cmd_packet* gecko_wait_event(void)

这是一个阻止功能,它等待来自蓝牙堆栈的事件并阻止,直到接收到事件为止。接收到事件后,将gecko_cmd_packet返回指向结构的指针。

如果在蓝牙堆栈配置中启用了EM睡眠模式,则当未从蓝牙堆栈接收到任何事件时,设备将自动进入EM1或EM2模式。使用gecko_wait_event()是确保设备尽可能处于最低功耗睡眠模式的最简单方法。

蓝牙堆栈事件处理中将详细讨论蓝牙堆栈的事件处理。

struct gecko_cmd_packet* gecko_peek_event(void)

这是一种非阻塞功能,用于从蓝牙堆栈请求蓝牙事件。当请求事件且事件队列不为空时,将gecko_cmd_packet struct返回指向的指针。如果事件队列中没有事件,则返回NULL。

使用此非阻塞事件侦听器时,必须由应用程序代码管理EM睡眠模式,因为它们不会由Bluetooth堆栈自动管理。睡眠模式管理通过gecko_can_sleep_ms()和gecko_sleep_for_ms()功能完成,稍后将进行讨论。

堆栈的事件处理将在蓝牙堆栈事件处理一节中详细讨论。

int gecko_event_pending(void)

此功能检查事件队列中是否有任何未解决的蓝牙堆栈事件。如果找到了未决的蓝牙事件,该函数将返回一个非零值,以指示该事件应由gecko_peek_event()或进行处理gecko_wait_event()。如果未找到事件,则返回零。

uint32 gecko_can_sleep_ms(void)

此功能用于确定蓝牙协议栈可以休眠多长时间。返回值是堆栈必须休眠的毫秒数,直到必须进行下一个蓝牙操作为止。如果无法休眠,则返回零。此功能仅与非阻塞gecko_peek_event()事件处理一起使用。

uint32 gecko_sleep_for_ms(uint32 max)

此函数用于将堆栈放入EM睡眠中的最大毫秒数(在函数的单个参数中设置)。返回值是实际睡眠的毫秒数。堆栈可能由于外部事件而唤醒。此功能仅与非阻塞gecko_peek_event()事件处理一起使用。

native_gecko.h

该文件用于没有RTOS的应用程序。它使用直接函数调用向蓝牙协议栈提供IPC(进程间通信)。

ncp_gecko.h

该文件将在为主机提供NCP功能的应用程序中使用。它使用NCP标头作为函数调用向蓝牙堆栈提供IPC。

host_gecko.h和gecko_bglib.h 这些文件在为外部主机开发应用程序时使用。host_gecko.h具有API定义,而gecko_bglib.h包含主机应用程序和BGAPI串行协议之间的适配层。

rtos_gecko.h

当为Micrium OS构建应用程序时,将使用rtos_gecko.h。蓝牙堆栈是Micrium OS的一项单独任务,并使用其电源,睡眠和内存管理。rtos_gecko.h为IPC提供了一个包装器,以使用Micrium OS中任何任务中的蓝牙堆栈。该文件包含蓝牙协议栈API,该协议栈的命令和事件以及蓝牙协议栈的配置API。

  • GATT数据库

GATT(通用属性配置文件)数据库是描述蓝牙配置文件,服务和蓝牙设备特征的标准化方法。使用Silicon Labs蓝牙堆栈,可以在Simplicity Studio的Visual GATT编辑器GUI中直接编辑GATT定义,也可以用XML编写GATT定义,并将其作为预构建任务传递给BGBuild可执行文件。有关如何创建GATT数据库和语法的更多信息,请参阅UG118:Blue GeckoBluetooth®Smart Profile Toolkit开发人员指南。

gatt_db.c和gatt_db.h

所述gatt_db.c定义GATT数据库结构和内容,以及是自动生成由BGBuild.exe或由Visual GATT编辑器。gatt_db.h包含此数据库以及本地特征和服务的句柄。GATT的类型定义会自动从gatt_db_def.h包含到gatt_db.h中。

  • 设备固件升级

设备固件升级(DFU)是通过串行链接或无线(OTA)升级应用程序的过程。在这两种情况下,应用程序都需要添加以下文件来启用对DFU的支持。

application_properties.c

该文件包括应用程序属性结构,该结构包含有关应用程序映像的信息,例如类型,版本和安全性。该结构是在Gecko Bootloader API的application_properties.h中定义的(请参阅参考资料中的Gecko Bootloader API参考)。\ platform \ bootloader \ documentation \ Gecko_Bootloader_API_Reference \ index.html)。Simplicity Studio项目中包含一个预生成的文件,可以对其进行修改以包含特定于应用程序的属性。可以使用Gecko Bootloader API访问应用程序属性。可以通过更改定义来更新以下成员:

// Version number for this application (uint32_t)#define BG_APP_PROPERTIES_VERSION// Capabilities of this application (uint32_t)#define BG_APP_PROPERTIES_CAPABILITIES// Unique ID (e.g. UUID or GUID) for the product this application is built for (uint8_t[16])#define BG_APP_PROPERTIES_ID

当将OTA进程与Bluetooth AppLoader一起使用时,应用程序属性结构应立即驻留在应用程序向量表之后。使用蓝牙协议栈提供的链接器文件时,将自动启用此功能。

  • 实时操作系统支持

蓝牙堆栈也可以在Micrium RTOS上运行。在这种情况下native_gecko.h被替换rtos_gecko.h和下列文件添加到项目中:rtos_bluetooth.c和rtos_bluetooth.h。

rtos_bluetooth.c和rtos_bluetooth.h

rtos_bluetooth.c和rtos_bluetooth.h通过蓝牙协议栈和其他Micrium OS任务为IPC(进程间通信)提供Micrium OS任务。使用Micrium OS时,还必须包括下面描述的rtos_gecko.h头文件。它提供API IPC封装,以使用任何Micrium OS任务中的Bluetooth堆栈。

需要在结构中为蓝牙协议栈配置对RTOS的支持gecko_configuration_t。config_flags字段需要GECKO_CONFIG_FLAG_RTOS设置。这导致蓝牙堆栈依赖Micrium OS进行睡眠,而不是直接睡眠。scheduler_callback并且stack_schedule_callback必须配置为调用适当的功能。这些回调用于唤醒相应的任务。

与Micrium OS一起使用的Bluetooth Stack配置如下:

.config_flags = GECKO_CONFIG_FLAG_RTOS,

.scheduler_callback = BluetoothLLCallback,

.stack_schedule_callback = BluetoothUpdate,

调用之后,可以调用gecko_stack_init()bluetooth_start_task()。

void bluetooth_start_task(OS_PRIO ll_priority, OS_PRIO stack_priority);

它以任务优先级为参数。ll_priority用于链路层,stack_priority用于蓝牙协议栈。链路层优先级必须是系统中的最高优先级,因为及时执行对于系统性能至关重要。

  • 多协议支持

在多协议环境中使用蓝牙协议栈时,必须使用以下功能启用蓝牙协议栈中的多协议功能:

gecko_init_multiprotocol(const void *config);

该config参数当前始终设置为NULL,保留用于将来的扩展。

在多协议环境中使用蓝牙还需要使用具有多协议支持的RAIL库。

  • 硬体支援

以下文件是Gecko SDK的一部分,它们添加了对硬件特定功能的支持。

hal-config.h

该头文件包含MCU外设初始化设置,例如用于时钟和电源管理的设置以及用于UART,SPI等外设的设置。请注意,此文件仅包含外设的非特定于板的设置,例如UART的波特率,而不包含特定于板的特定设置,例如UART的输入/输出引脚。

init_mcu.c和init_mcu.h

这些文件包括设备初始化功能,该功能初始化MCU的内部设置,例如时钟和电源管理。

init_board.c和init_board.h

这些文件包括电路板初始化功能,该功能可初始化电路板上的外部部件。例如,它启用GPIO,并初始化无线电板上的外部闪存。

init_app.c和init_app.h

这些文件包括应用程序初始化功能,该功能根据应用程序初始化WSTK上的外部部件。例如,它在WSTK上启用VCOM,传感器和LCD显示。

pti.c和pti.h

这些文件包括PTI初始化功能,该功能启用了数据包跟踪接口。

hal-config-board.h

该头文件包含板初始化设置,例如按钮和LED引脚,UART和SPI引脚等。在为Silicon Labs的无线电板开发应用程序时,可以在SDK中提供的示例中正确设置这些设置,但是为自定义硬件设计创建应用程序的开发人员需要相应地配置设置。

bspconfig.h / bsphalconfig.h

BSP(板级支持包)标头包含特定于无线电板的配置,这些配置用作WSTK特定功能的参数,例如切换WSTK上的IO或驱动入门工具包上的LCD显示器。如果使用了硬件配置器工具,则示例使用bsphalconfig.h。否则,将使用bspconfig.h。

mx25flash_spi.h

该头文件包含用于将某些无线电板上的SPI闪存芯片(例如BRD4100A)配置为低功耗模式的功能。例如,这在进行睡眠电流测量时非常有用,因为如果SPI闪存不在低功耗模式下,则不会达到最低的EM2,EM3或EM4电流。

  • 配置蓝牙协议栈和无线Gecko设备

要在Wireless Gecko上运行Bluetooth堆栈和应用程序,必须正确配置MCU及其外围设备。初始化硬件后,还必须使用gecko_init()函数初始化堆栈。

  • 无线Gecko MCU和外围设备配置

initMcu()

该initMCU()函数用于初始化MCU内核。该功能启动振荡器并配置器件的能量模式。可以将与板卡设置无关的外围设备初始化(例如,计时器初始化)添加到此功能中。该函数必须在main()的开头调用。

initBoard()

该initBoard()功能用于初始化电路板功能,例如初始化外部闪存。可以将取决于电路板设计的外设初始化(例如GPIO初始化或UART初始化)添加到此功能。该函数必须在initMcu()之后调用。

initApp()

该initApp()函数用于初始化特定于应用程序的功能,例如在WSTK上启用SPI显示。该函数必须在之后调用initBoard()。

自适应跳频

蓝牙协议栈实现了自适应跳频(AFH),符合ETSI EN 300 328标准。使用+10 dBm以上的发射功率时,需要AFH。AFH还可以通过避免信道拥塞来提高性能。

要在蓝牙协议栈中启用AFH,必须调用以下初始化函数:

void gecko_init_afh();

在主从连接中,两端可以独立使用AFH。主机可能是非自适应的,但从机仍可能需要自适应。该标准允许在阻塞的通道上使用控制传输。出于合规性原因,如果从站检测到正在使用阻塞的信道,它将仅在该信道上发送单个数据包以防止连接超时。

注意:旧版广告不使用自适应跳频。旧版广告使用3个渠道,而AFH至少需要15个渠道才能满足ETSI标准的要求。必须使用扩展广告来启用AFH广告功能。

蓝牙时钟

时钟设置在initMcu_clocks()函数中初始化。时钟设置包括使用诸如调谐之类的参数初始化振荡器(HFXO,LFXO和LFRCO),初始化时钟(HFCLK,LFCLK,LFA,LFB,LFE)以及将时钟分配给振荡器。注意:此功能未启用外设时钟(如GPIO时钟,TIMER时钟)。初始化外围设备时必须启用它们。

高频时钟

HFCLK用于无线电协议计时器(PROTIMER)。HFCLK是一个高频时钟,精度必须至少为±50 ppm。该时钟需要一个外部晶振才能足够准确(HFXO)。

HFXO初始化将外部晶体配置为时序关键型连接和睡眠管理。必须将HFXO设置为高频时钟(HFCLK),并物理连接到Wireless Gecko的HFXO输入引脚。

低频时钟

低频时钟LFCLK有两个用途。在蓝牙堆栈中,它用于蓝牙协议计时。还需要在睡眠模式下跟踪时间。

当设备进入睡眠模式时,将保存PROTIMER的当前状态。设备唤醒后,它将计算经过多少个睡眠时钟滴答,并相应地调整PROTIMER。在收音机中,PROTIMER似乎一直在滴答作响。

此时钟的准确性取决于设备的工作模式。在做广告或扫描时,精度不是那么重要,但是当连接断开时,精度必须至少为±500 ppm。该时钟可以由LFXO或LFRCO驱动,具体取决于精度要求。如果应用程序仅需要广告或扫描,则可以将LFRCO用作时钟源。但是,如果需要蓝牙连接,则时钟源必须是LFXO或PLFRCO(具有精确模式的LFRCO)。使用PLFRCO时,时钟的精度必须配置为±500 ppm。

时钟的准确性在蓝牙协议栈配置结构中定义,请参阅“蓝牙协议栈配置”部分。

在默认配置中,LFXO连接到Wireless Gecko,并设置为LFCLK的时钟源。如果设计中没有LFXO,但可用PLFRCO,则连接PLFRCO并将其设置为时钟源。如果没有连接LFXO或PLFRCO,但是在设计中需要蓝牙连接,则必须从应用程序中明确禁用睡眠。如“睡眠”部分所述,如果LFCLK不够准确,则必须禁用睡眠模式才能使蓝牙连接正确运行。

这些示例均默认设置了HFXO和LFXO的晶体调谐(CTUNE)设置,以与所有Silicon Labs的蓝牙模块,参考设计和无线电板一起使用。但是,在某些情况下,最终产品设计需要针对每个器件或每个设计进行特定的晶体校准。可以使用hfxoInit.ctuneSteadyState和功能中的lfxoInit.ctune设置根据设计调整CTUNE值initMcu_clocks()。

// Initialize HFXOCMU_HFXOInit_TypeDef hfxoInit = BSP_CLK_HFXO_INIT;hfxoInit.ctuneStartup = BSP_CLK_HFXO_CTUNE;hfxoInit.ctuneSteadyState = BSP_CLK_HFXO_CTUNE;CMU_HFXOInit(&hfxoInit);

有关配置HFXO和LFXO的更多信息,请参阅《 EFR32参考手册》。

HFXO CTUNE默认值

系统使用以下逻辑顺序检查多个源的默认HFXO CTUNE值:

  1. CTUNE PSKEY已设置。此项的ID为50(十六进制为32),并包含2个字节的数据,用于16位CTUNE值。可以使用BGAPI命令cmd_flash_ps_save进行编程

  2. 校准值存在于DEVINFO中。某些模块在DEVINFO页中包含工厂编程的值。

  3. 制造令牌存在于用户数据页面中。这由开发人员编程,或者如果板EEPROM包含该值,则可以由Simplicity Studio自动设置。该令牌由2个字节组成,与EFR32xG1x器件的“用户数据”页的起始地址或从EFR32xG21x器件的最后一个闪存页的起始地址偏移0x0100。有关完整的Flash映射,请参阅您的EFR变体的《 EFR32参考手册》。

  4. 如果在生成项目时选择了无线电板,则使用板头文件中的默认值

  5. 如果找不到其他内容,请使用CMU头文件中的默认值。

注意:蓝牙协议栈仅支持38.4 MHz HFXO频率。不支持其他HFXO频率。

DC-DC配置

在具有DC-DC的设备上,配置是在initMCU()函数中设置的。SDK中的示例已将DC-DC配置设置为可与Silicon Labs的蓝牙模块,无线电板和参考设计一起使用,但是自定义设计可能需要特定的DC-DC设置。这些自定义设置可以在hal-config-board.h中进行设置。

#define BSP_DCDC_INIT \{ \emuPowerConfig_DcdcToDvdd, /* DCDC to DVDD */ \emuDcdcMode_LowNoise, /* Low-noise mode in EM0 */ \1800, /* Nominal output voltage for DVDD mode, 1.8V */ \15, /* Nominal EM0/1 load current of less than 15mA */ \10, /* Nominal EM2/3/4 load current less than 10uA */ \200, /* Maximum average current of 200mA(assume strong battery or other power source) */ \emuDcdcAnaPeripheralPower_DCDC,/* Select DCDC as analog power supply (lower power) */ \160, /* Maximum reverse current of 160mA */ \emuDcdcLnCompCtrl_1u0F, /* 1uF DCDC capacitor */ \}

有关配置DC-DC的更多信息,请参阅EFR32参考手册,第11章,以及AN0948:电源配置和DC-DC。

低噪声放大器

低噪声放大器(LNA)是一种电子放大器,可放大非常低功率的信号而不会显着降低其信噪比。LNA改善了RF灵敏度。

某些MGM12P模块中的板载LNA作为前端模块(FEM)的一部分。要在这些模块中使用LNA,需要正确配置和启用FEM。使用前缀BSP_FEM_ 在hal-config-board.h中配置 FEM。

如果主板支持FEM ,则initFem()在initBoard()功能内初始化FEM。

定期广告

定期广告使多个收听者可以与单个广告设备同步。因此,它是组播的一种形式。

每个收听者在开始接收数据之前都需要与广告设备同步。定期广告使用监听设备上的扫描仪建立与广告设备的同步。同步后,可以停止扫描仪。这比全时使用扫描仪收听广播广告要省电得多。

定期广告由两个部分组成:定期广告主角色和侦听侧的定期广告同步这两个组件彼此独立,需要分别进行初始化。

max_advertisers 在蓝牙配置中,还配置了周期性广告主的最大数量。

要在Bluetooth堆栈中启用Periodic Advertiser,必须在通用gecko_init()函数之后调用以下初始化函数:

void gecko_init_periodic_advertising();

定期广告同步

max_periodic_sync 蓝牙配置中的,用于配置蓝牙协议栈需要支持的最大同步次数。

要在蓝牙协议栈中启用定期广告同步,必须在通用gecko_init()函数之后调用以下初始化函数:

void gecko_bgapi_class_sync_init();

此命令还将初始化BGAPI同步类,使其可供使用。

PTI

PTI(数据包跟踪接口)是Wireless Gecko SoC中的内置模块,用于将传入和传出的无线电数据包作为原始数据路由到调试接口。然后可以捕获这些数据包并将其显示在Simplicity Studio的网络分析器中。网络分析仪具有用于蓝牙数据包的解码器,可用于调试,分析和测量蓝牙网络。

configEnablePti()在initApp()函数中初始化PTI 。可以使用 定义在hal-config.h中设置波特率HAL_PTI_BAUD_RATE,而可以使用带有前缀的定义在hal-config-board.h中配置引脚BSP_PTI_。

从Bluetooth 2.6.x开始,PTI已配置有RAIL提供的功能。

发射功率

蓝牙的发射功率取决于无线电允许的最大功率,软件配置,RF路径增益补偿以及自适应跳频(AFH)的使用。

ETSI EN 300 328标准要求在发射机功率为+10 dBm以上时使用AFH。

如果适应性要求阻止,则最大允许功率限制为小于+10 dBm。ETSI标准要求AFH至少使用15个通道。在以下情况下,此要求可防止使用+10 dBm及以上:旧版广告,扫描响应以及在没有足够信道可用时的连接。

白名单

白名单用于过滤设备。当前仅在发现设备时才支持。连接请求,通告期间来自远程设备的扫描请求以及连接启动不受白名单的限制。

白名单大小与绑定设备最大数量的配置匹配。如果在使用白名单时更改了绑定设备的最大数量,则需要在新设置生效之前重置设备。

绑定的设备会自动添加到白名单中。或者,可以使用BGAPI命令手动添加它们gecko_cmd_sm_add_to_whitelist()。

不支持随机地址解析。使用可解析的随机地址的设备在扫描过程中将不可见。由于大多数Android和iOS手机使用可解析的随机地址,因此白名单功能将在设备发现期间有效地阻止这些设备。

要在蓝牙堆栈中启用白名单,必须在通用gecko_init函数之后调用以下初始化函数:

void gecko_init_whitelisting();

启用该功能后,可以在运行时通过BGAPI命令启用和禁用该功能gecko_cmd_le_gap_enable_whitelisting()。

Wi-Fi共存

Wi-Fi共存(COEX)是一种协议,蓝牙和Wi-Fi可以仲裁该协议可以使用无线电进行传输的协议。启用后,它可以改善Wi-Fi和蓝牙的性能。在hal-config-board.h中使用带有前缀BSP_COEX_和的定义来配置COEX HAL_COEX_。

要启用COEX,请在之后调用以下函数gecko_stack_init()。

gecko_initCoexHAL();

COEX实现了Wi-Fi IC的GPIO接口。它取决于EMLIB em_gpio.c和EMDRV gpiointerrupt.c,并且要求两个文件都包含在项目中。

  • 使用gecko_stack_init()进行蓝牙配置

g ecko_stack_init()函数用于配置Bluetooth堆栈,包括睡眠模式配置,为连接分配的内存,OTA配置等。在配置蓝牙堆栈之前,不能使用任何蓝牙堆栈功能。

蓝牙堆栈配置示例:

uint8_t bluetooth_stack_heap[DEFAULT_BLUETOOTH_HEAP(MAX_CONNECTIONS)];static const gecko_configuration_t config = {.config_flags=0,.sleep.flags=SLEEP_FLAGS_DEEP_SLEEP_ENABLE,.bluetooth.max_connections=MAX_CONNECTIONS,.bluetooth.heap=bluetooth_stack_heap,.bluetooth.heap_size=sizeof(bluetooth_stack_heap),.bluetooth.sleep_clock_accuracy = 100, // ppm.gattdb=&bg_gattdb_data,.ota.flags=0,.ota.device_name_len=3,.ota.device_name_ptr="OTA",.max_timers=4};

该gecko_stack_init()功能中的配置选项包括:睡眠启用/禁用,蓝牙连接计数,堆大小,睡眠时钟准确性,GATT数据库,OTA配置和PA配置。

gecko_stack_init()调用函数后,必须分别初始化每个使用的堆栈组件。这种分离允许通过不包括不必要的堆栈组件来优化内存。

以下命令可用于分别初始化堆栈组件:

命令

描述

gecko_bgapi_class_dfu_init()

启用设备固件升级(dfu)API。

gecko_bgapi_class_system_init()

启用本地设备(系统)API。

gecko_bgapi_class_le_gap_init()

启用通用访问配置文件(gap)API。

gecko_bgapi_class_le_connection_init()

允许通过连接API管理连接的建立,参数设置和断开过程。

gecko_bgapi_class_gatt_init()

使您能够通过gatt API浏览和管理远程GATT服务器中的属性。

gecko_bgapi_class_gatt_server_init()

使您能够浏览和管理本地GATT数据库gatt_server API中的属性。

gecko_bgapi_class_hardware_init()

启用对软件计时器的访问和配置。

gecko_bgapi_class_flash_init()

启用持久性存储命令(闪存)API,这些API可用于管理闪存中的用户数据。

gecko_bgapi_class_test_init()

启用DTM测试API。

gecko_bgapi_class_sm_init()

使安全管理器(sm)API启用。

gecko_bgapi_class_util_init()

启用实用函数API,例如atoi和itoa。

配置标志

当前标志

GECKO_CONFIG_FLAG_RTOS1 =应用程序使用RTOS。堆栈不配置RTOS提供的时钟,向量,TEMPDRV或休眠。

mbedTLS

堆栈使用的Mbedtls加密库是使用配置文件配置的,该文件定义了支持哪些算法以及实现是使用硬件加速还是在软件上完成。Mbedtls配置文件路径使用给出#define MBEDTLS_CONFIG_FILE。默认配置文件mbedtls_config.h位于SDK中,如果需要更改配置,则应将其用作模板。

多协议优先级配置

在多协议环境中将蓝牙协议栈与其他协议一起使用时,可能有必要更改RAIL的蓝牙优先级设置以优化某些用例。

应用程序需要分配配置结构并将其提供给蓝牙堆栈:

gecko_bluetooth_ll_priorities custom_priorities;static const gecko_configuration_t config = {//.bluetooth.linklayer_priorities = &custom_priorities,//};

gecko_bluetooth_ll_priorities必须通过GECKO_BLUETOOTH_PRIORITIES_DEFAULT常量将结构初始化为默认状态。

该gecko_bluetooth_ll_priorities结构包含以下字段:

  • scan_min&scan_max-扫描操作的优先级范围。

  • adv_min&adv_max-广告操作的优先级范围。

  • conn_min&conn_max-连接数据包的优先级范围。

  • init_min&init_max-连接启动的优先级范围。

  • threshold_coex -提高优先级信号时的阈值水平,仅在启用coex时使用。

  • rail_mapping_offset -蓝牙优先级所在的RAIL优先级。

  • rail_mapping_range -蓝牙优先级所在的RAIL优先级范围。

对于每个优先级范围,0是最大优先级,0xff是最小优先级。蓝牙优先级与RAIL优先级不同。也就是说,蓝牙在所有蓝牙优先级所在的位置都有自己的介于0和0xff之间的空间。要将Bluetooth优先级映射到RAIL优先级,请使用字段中的值rail_mapping_offset并rail_mapping_range形成单次方程式:

RAIL_priority=(BT_priority/0xFF)*rail_mapping_range+rail_mapping_offset

睡眠

必须在该gecko_init()功能中启用Wireless Gecko的睡眠模式EM2(节能模式2)。睡眠标志是该gecko_configuration_t结构的一部分。该SLEEP_FLAGS_DEEP_SLEEP_ENABLED标志必须设置为启用睡眠。如发生阻塞事件,休眠模式将由堆栈自动处理,如“ 蓝牙堆栈事件处理”一节中所述。

在gecko_configuration_tstruct(main.c)中启用睡眠的示例:

.sleep.flags = SLEEP_FLAGS_DEEP_SLEEP_ENABLE // EM sleeps enabled

睡眠模式要求硬件中存在准确的32 kHz低频时钟(LFCLK)。如果没有准确的睡眠时钟可用于蓝牙协议栈,那么如果应用程序需要支持蓝牙连接,则无法进入低功耗睡眠模式。对于不需要低功耗睡眠模式的应用,可以省去LFXO或LFRCO,但是壁虎配置结构中的睡眠标志必须设置如下:

.sleep.flags = 0, // Sleeps disabled

在运行时禁用睡眠

如果需要在运行时禁用睡眠,则可以通过调用睡眠驱动程序函数SLEEP_SleepBlockBegin(sleepEM2)来完成。要重新启用EM2深度睡眠模式,请使用SLEEP_SleepBlockEnd(sleepEM2)。当EM2被禁用(/阻塞)时,堆栈将在EM0和EM1之间切换。有关更多信息,请参阅知识库文章“将能源模式与Bluetooth Stack一起使用”。

蓝牙堆栈配置

堆栈记忆体

蓝牙堆栈使用内部内存管理为每个连接和内部数据缓冲区分配内存。该内存需要由应用程序分配并传递给蓝牙堆栈。内存大小取决于连接数。C宏DEFAULT_BLUETOOTH_HEAP()计算所需内存的默认大小(以字节为单位)。

分配bluetooth_stack_heap数组并将其传递到Bluetooth堆栈的示例:

uint8_t bluetooth_stack_heap[DEFAULT_BLUETOOTH_HEAP(MAX_CONNECTIONS)];static const gecko_configuration_t config = {//.bluetooth.heap = bluetooth_stack_heap,.bluetooth.heap_size = sizeof(bluetooth_stack_heap),//};

连接数

同时进行的蓝牙连接的绝对最大数量为8。为连接管理分配的内存量进一步限制了连接数量。在中初始化时分配内存gecko_init()。MAX_CONNECTIONS可以定义C-define 来设置连接数。然后,如上所述,相同的定义也可用于计算蓝牙堆栈的内存大小。MAX_CONNECTIONS然后将其进一步传递给.bluetooth.max_connections配置结构中字段中的Bluetooth堆栈。

将蓝牙连接限制为一(1)的示例。

#define MAX_CONNECTIONS 1

有关连接RAM使用情况的更多信息,请参阅7.3.2蓝牙连接池。

睡眠时钟精度

蓝牙堆栈用于.sleep_clock_accuracy优化从睡眠中唤醒的时间。单位为ppm(百万分之一)。如果该值太大,则蓝牙堆栈太早从睡眠中唤醒,无法等待实际事件,这会导致过多的功耗。如果此值太小,则蓝牙协议栈唤醒时间太晚,并且错过了连接事件,这会导致连接断开。

如果未定义或设置为0,则使用默认值250 ppm。

设置睡眠时钟精度的示例。

.bluetooth.sleep_clock_accuracy = 100, // ppm

广告商

可以通过此配置选项定义广告集的最大数量。这些集合可用于启动多个广告商。此配置选项还配置了定期通告的最大数量。每个广告上下文分配约60个字节的RAM。

.bluetooth.max_advertisers = 5; //!< Maximum number of advertisers to support, if 0 defaults to 1

注意:最大可连接广告受到MAX_CONNECTIONS的限制。

同步广告

需要配置支持的最大同步广告数量。每个上下文分配约40个字节的RAM。

.bluetooth.max_periodic_sync = 5; //!< Maximum number of synhronous advertisers to support. Default is 0, none supported

OTA配置

由于部分固件升级由蓝牙AppLoader应用程序处理,因此支持蓝牙无线(OTA)固件升级。

OTA模式使用.ota.flags配置字段。目前,它只有一个选项,GECKO_OTA_FLAGS_RANDOM_ADDRESS该选项将OTA设置为使用静态随机地址而不是公共地址。

当Wireless Gecko处于AppLoader的OTA模式时,可以通过gecko配置结构配置其设备名称和设备名称长度。

.ota.device_name_len = 3, // OTA name length

.ota.device_name_ptr = "OTA", // OTA Device Name

最后,应确保将设备设置为OTA DFU模式,以便只有受信任的设备才具有该功能。

有关OTA固件更新的更多详细信息,请参考《UG266:Silicon Labs Gecko Booloader用户指南》和《AN1086:将Gecko Bootloader与Silicon Labs蓝牙应用程序结合使用》。

功放

在基于EFR32 SoC的设计中,可以从DC / DC的输出或从3.3 V电源直接提供PAVDD(功率放大器电压调节器VDD输入)。

蓝牙协议栈配置默认使用DC / DC作为PAVDD输入。如果从3.3 V电源提供PAVDD,则.pa.input需要定义该字段。

蓝牙堆栈会自动选择高功率PA(如果有)。在pa_mode配置中设置1 将使蓝牙协议栈始终使用低功率PA。

.pa.config_enable = 1, // PA Configuration is enabled

.pa.input = GECKO_RADIO_PA_INPUT_VBAT, // PAVDD is upplied from an 3.3 V power supply

.pa.pa_mode=0 // selects high power PA if available

软件计时器

可以配置最大可用软件计时器。每个计时器都需要来自堆栈的资源才能实现。在某些使用情况下,软计时器数量的增加可能会导致性能下降。

.max_timers = 4; // Maximum number of soft timers, up to 16, Default: 4

射频路径增益

该应用程序可以分别定义RX和TX的RF路径增益值。

调整发射器功率时,蓝牙堆栈会考虑TX RF路径增益。然后,从天线辐射的功率会匹配应用程序的请求。例如,如果应用程序要求的最大功率为+10 dBm,路径损耗为-1 dBm,则引脚上的实际功率为+11 dBm。

RX RF路径增益用于补偿来自蓝牙协议栈的RSSI报告。

.rf.tx_gain = -20; // RF TX path gain in unit of 0.1 dBm

.rf.rx_gain = -18; // RF RX path gain in unit of 0.1 dBm

  • 蓝牙堆栈事件处理

Wireless Geckos的蓝牙堆栈是事件驱动的体系结构,其中事件在主while循环中处理。

  • 阻止事件监听器

gecko_wait_event()是阻塞等待函数的实现,该函数等待事件出现到事件队列中并将它们返回给事件处理程序。这是蓝牙堆栈建议的操作模式,因为它可以最有效和自动地管理睡眠,同时保持设备和连接同步。

  • 该gecko_wait_event()函数处理内部消息队列,直到接收到事件为止。

  • 如果没有任何待处理的事件或消息要处理,则设备将进入EM1或EM2睡眠模式。

  • 该函数返回一个指向gecko_cmd_packet保存所接收事件的结构的指针。

下面的代码段显示了iBeacon示例中使用的简单主while循环,该示例gecko_wait_event()在启动后设置广告。

/* Main loop */while (1) {struct gecko_cmd_packet* evt;/* Wait (blocking) for a Bluetooth stack event. */evt = gecko_wait_event();/* Run application and event handler. */switch (BGLIB_MSG_ID(evt->header)){/* This boot event is generated when the system is turned on or reset. */case gecko_evt_system_boot_id:/* Initialize iBeacon ADV data */bcnSetupAdvBeaconing();break;/* Ignore other events */default:break;}
  • 非阻塞事件监听器

这种操作模式需要更多的手动调整,例如,睡眠管理需要由应用程序完成。在某些用例中,需要非阻塞操作。

  • 该gecko_peek_event()函数处理内部消息队列,直到接收到事件或所有消息被处理为止。

  • 该函数返回一个指针,该指针指向gecko_cmd_packet保存已接收事件或NULL队列中没有事件的结构。

睡眠和非阻塞事件监听器

当应用程序使用非阻塞gecko_peek_event()功能创建事件处理程序时,睡眠实现也有所不同。应用程序必须用于gecko_can_sleep_ms()查询堆栈设备可以休眠多长时间,然后使用该gecko_sleep_for_ms()函数将该设备设置为休眠该时间。必须在调用gecko_can_sleep_ms()或gecko_sleep_for_ms()函数之前禁用中断,并在执行函数后启用中断。

注意:建议不要在此关键部分添加任何其他功能。这将增加中断延迟并降低性能。

下面的示例显示了使用非阻塞事件处理时如何实现睡眠管理。

/* Main loop */while (1) {struct gecko_cmd_packet* evt;CORE_DECLARE_IRQ_STATE;/* Poll (non-blocking) for a Bluetooth stack event. */evt = gecko_peek_event();/* Run application and event handler. */if(evt != NULL){switch (BGLIB_MSG_ID(evt->header)){/* This boot event is generated when the system is turned on or reset. */case gecko_evt_system_boot_id:/* Initialize iBeacon ADV data */bcnSetupAdvBeaconing();break;/* Ignore other events */default:break;}}CORE_ENTER_ATOMIC(); // Disable interrupts/* Check how long the stack can sleep */uint32_t durationMs = gecko_can_sleep_ms();/* Go to sleep. Sleeping will be avoided if there isn't enough time to sleep */gecko_sleep_for_ms(durationMs);CORE_EXIT_ATOMIC(); // Enable interrupts}

更新事件监听器的通知

在某些情况下,可能需要在应用程序的另一个事件循环中运行Bluetooth事件循环。蓝牙堆栈具有回调机制,用于通知应用程序有关更新蓝牙堆栈事件监听器的需求。通过在蓝牙配置结构中定义回调函数来启用此功能。

注意:这stack_schedule_callback是从中断上下文中调用的。重要的是不要致电gecko_peek_event或gecko_wait_event从此上下文中进行呼叫。应用程序必须设置一个标志或使用其他机制来启用应用程序主循环以更新蓝牙堆栈。

static const gecko_configuration_t config = {//.stack_schedule_callback = bluetooth_update//};void bluetooth_update(){//set notification for application}
  • Micrium OS的事件监听器

该应用程序使用不同的过程来使用Micrium OS接收事件。应用程序需要调用Micrium OS标志,而不是调用函数来接收事件。只能从单个任务接收事件。

Micrium OS标志bluetooth_event_flags用于通知蓝牙蓝牙状态的不同任务。该应用程序仅使用BLUETOOTH_EVENT_FLAG_EVT_WAITING和BLUETOOTH_EVENT_FLAG_EVT_HANDLED。

应用程序事件处理程序需要保留BLUETOOTH_EVENT_FLAG_EVT_WAITING。

OSFlagPend(&bluetooth_event_flags, (OS_FLAGS)BLUETOOTH_EVENT_FLAG_EVT_WAITING 0,OS_OPT_PEND_BLOCKING +

OS_OPT_PEND_FLAG_CONSUME, NULL,&os_err);

`

然后,传入事件在中可用bluetooth_evt。

switch (BGLIB_MSG_ID(bluetooth_evt->header)) {

}

`

处理事件后,需要释放它以允许接收下一个事件。这是通过发布标志通知蓝牙任务来完成的BLUETOOTH_EVENT_FLAG_EVT_HANDLED。

OSFlagPost(&bluetooth_event_flags, (OS_FLAGS)BLUETOOTH_EVENT_FLAG_EVT_HANDLED, OS_OPT_POST_FLAG_SET, &os_err);

注意:当应用程序待处理时,睡眠和电源管理将由Micrium OS而不是由应用程序自动处理。

来自多个任务的命令

可以从多个Micrium OS任务发送蓝牙命令。它要求每个任务在发送命令之前都具有排他性,然后再释放它。

为了方便起见,蓝牙协议栈提供了两种功能。BluetoothPend获取Micrium OS互斥锁并BluetoothPost释放该互斥锁。

以下代码块在蓝牙命令之前获取了蓝牙互斥锁,并在之后释放了该互斥锁。

BluetoothPend(&err); //acquire mutex for Bluetooth stack

gecko_cmd_gatt_server_send_characteristic_notification(0xff, gattdb_temp_measurement, 5, temp_buffer);

BluetoothPost(&err);//release mutex

  • 中断

中断在其各自的中断处理程序中创建事件,无论是无线电中断还是来自IO引脚的中断。事件随后在主事件循环中从消息队列进行处理。应用程序应始终尽量减少中断处理程序中的处理时间,并将处理留给事件回调或主循环使用。

通常,中断方案根据任何基于事件的编程体系结构进行,但是一些独特且重要的例外适用于蓝牙协议栈:

  • 不能从中断上下文中调用BGAPI命令。

  • 只能gecko_external_signal()从中断上下文中调用该函数。

  • gecko_sleep_for_ms()如前面的代码示例所示,在调用之前必须禁用中断。

  • 外部事件

外部事件用于捕获所有外围中断,作为要传递到主事件循环并在该循环内进行处理的外部信号。外部事件中断可以来自任何外围中断源,例如IO,比较器或ADC等。信号位数组用于通知事件处理程序已发出哪些外部中断。

  • 外部信号的主要目的是触发从中断上下文到主事件循环的事件。

  • system_external_signal可以通过调用该void gecko_external_signal(uint32 signals)函数来生成BGAPI事件。

  • gecko_external_signal可以从中断上下文中调用该函数。

  • gecko_external_signal函数的signals参数传递给system_external_signal event。

/*** Main*/void main(){...//Event loopwhile(1){...//External signal indication (comes from the interrupt handler)case gecko_evt_system_external_signal_id:// Handle GPIO IRQ and do something// External signal command’s parameter can be accessed using// event->data.evt_system_external_signal.extsignalsbreak;...}}/*** Handle GPIO interrupts and trigger system_external_signal event*/void GPIO_ODD_IRQHandler(){static bool radioHalted = false;uint32_t flags = GPIO_IntGet();GPIO_IntClear(flags);//Send gecko_evt_system_external_signal_id event to the main loopgecko_external_signal(...);}

优先事项

强烈建议无线电应具有最高优先级的中断。这是默认配置,其他中断的优先级较低。无线电的默认中断优先级为1,对于链路层,优先级为2,USART中断为3,其他中断的默认优先级为4。

如果应用程序需要禁用中断,建议使用BASEPRI寄存器而不是PRIMASK寄存器。该BASEPRI寄存器以中断优先级PRIMASK禁用,而禁用所有中断。可以将EMLIB Core配置为使用BASEPRI寄存器,然后可以将其与CORE_ENTER_ATOMIC()和CORE_EXIT_ATOMIC()宏一起使用。

在没有RTOS的情况下,链路层使用PendSV来获得高于应用程序软件的优先级。使用RTOS,链接层将不使用PendSV,但是链接层任务将比应用程序任务具有更高的优先级。然后,RTOS调度程序将优先于链接层任务而不是应用程序任务。

下表描述了在不同操作上下文中运行的蓝牙协议栈中的三个不同组件,以及它们为禁用每个组件以确保连接的最大中断时间。

零件

描述

计时精度

操作环境

最大IRQ禁用

如果忽略时间要求

无线电

对时间要求严格的低电平TX / RX无线电控制

微秒

广播IRQ

<〜10μs

数据包未发送或接收,最终将导致监管超时和蓝牙链接丢失。

链接层

时间紧迫的连接管理程序和加密

毫秒

PendSV IRQ *

<〜20毫秒

如果未及时处理链接控制过程,则可能会发生蓝牙链接丢失。从侧通道映射更新和连接更新时序由主机控制。

主机栈

蓝牙主机堆栈,安全管理器,GATT

应用

<30秒

SMP和GATT的超时时间为30 s,如果在此超时时间内未处理任何操作,则将导致蓝牙链接丢失。

* PendSV中断仅在没有RTOS的情况下使用

wrieless Gecko资源

蓝牙协议栈使用了Wireless Gecko的一些资源,这些资源对应用程序不可用。下表列出了资源,并说明了堆栈的使用情况。前四个资源(红色)始终由蓝牙堆栈使用。

类别

资源资源

用于软件

笔记

PRS

PRS7

PRS7 PROTIMER RTC同步

PRS7始终由蓝牙协议栈使用。

计时器

即时通讯

EM2计时

用于睡眠时间。两个通道总是保留的。

应用程序只能读取RTC值,而不能写入RTC值或使用RTCC。

RTCC仅在EFR32BG1和EFR32BG12中保留。有关更多信息,请参见RTCC。

计时器

计时器

蓝牙

该应用程序无权访问PROTIMER。

无线电

无线电

蓝牙

始终使用,所有无线电寄存器均保留用于蓝牙堆栈。

通用输入输出

国家协调委员会

主机通讯

根据使用的功能(UART,RTS / CTS,唤醒和主机唤醒),可以为NCP使用分配2至6个I / O引脚。

可选使用,仅对NCP用例有效。

通用输入输出

PTI

封包追踪

2至N x I / O引脚。

可选使用。

通用输入输出

发送使能

TX活动指示

1个I / O引脚

可选使用。

通用输入输出

接收使能

RX活动指示

1个I / O引脚

可选使用。

通用输入输出

COEX

Wi-Fi共存

4个I / O引脚。

可选使用。

CRC

GPCRC

PS Storge

可以在应用程序中使用,但是应用程序应始终在使用前重新配置GPCRC,并且不得在CMU中禁用GPCRC时钟。

flash

MSC

PS Storge

可由应用程序使用,但不得禁用MSC。

加密

加密

蓝牙链接加密

CRYPTO外设只能通过mbedTLS密码库访问,而不能通过任何其他方式访问,该库应该能够在堆栈和应用程序访问之间进行调度。

FLASH

应用程序和蓝牙堆栈从闪存执行。闪存可分为用于引导加载程序,Bluetooth AppLoader,应用程序和非易失性存储器的块,如下图所示。

  • 引导加载程序对于实现蓝牙堆栈和应用程序升级能力至关重要。引导加载程序经过专门设计,可针对未来进行改进,以改进引导加载程序和增加功能。在具有单独的引导加载程序闪存的设备上,它位于此处。

  • 蓝牙AppLoader为应用程序提供OTA可升级性。这是一项可选功能,但使用它需要同时使用引导加载程序。

  • PS Store和NVM3是非易失性数据存储(NVM),蓝牙堆栈和应用程序都可以在其中存储永久数据,例如蓝牙绑定密钥,应用程序配置数据,硬件配置等。

  • 该应用程序位于Bluetooth AppLoader和NVM之间。蓝牙堆栈是与应用程序链接的库。蓝牙堆栈包括实际的蓝牙固件,包括链路层,GAP,SM,ATT。和GATT层。

  • 用户数据页面用于存储制造令牌。在EFR32BG2X器件上,它位于主闪存的末端。

有和没有独立的引导加载程序闪存时的 闪存使用情况

下表显示了每个块的闪存使用情况。估计值可能会因使用案例,配置,应用程序资源或SDK版本而异。

flash使用

* soc-empty和soc-thermometer是Bluetooth SDK中提供的示例应用程序。它们是通过大型优化进行编译的。GCC使用该-Os标志,而IAR使用该-Ohz标志。

优化闪存使用率

消除死代码

蓝牙堆栈库旨在受益于链接器的无效代码消除优化。通过这种优化,所有未使用的代码将从应用程序中删除。

为了充分利用此优化功能,重要的是不要调用应用程序不需要的任何函数。这些功能包括蓝牙堆栈的所有初始化功能。

蓝牙堆栈组件的选择性初始化

gecko_init()函数会自动初始化每个堆栈组件。对于更多的选择性初始化,gecko_stack_init()必须使用。然后,每个必需的堆栈组件都将单独初始化。有关更多信息,请参阅“ 使用gecko_stack_init()进行蓝牙配置”部分。

连结中

蓝牙堆栈作为一组库文件提供。该应用程序将蓝牙堆栈库与其他应用程序链接。然后,链接器将创建一个ELF文件,其中包含准备好要加载到闪存中的应用程序代码和数据。

为了生成OTA DFU文件,必须将应用程序的代码和数据链接到ELF文件中自己的部分。这是通过蓝牙堆栈随附的链接器文件自动完成的。

链接器文件中定义的节及其放置 链接器文件中定义的节及其放置

链接器文件定义了两个存储区,一个用于主闪存,一个用于引导加载程序闪存。如果不存在单独的引导加载程序闪存,则链接器文件会从主闪存中为引导加载程序保留一些内存。蓝牙AppLoader放在主闪存的开头,带有所有库的应用程序从下一个免费闪存页面开始。

有关OTA更新及其启用方法的更多信息,请参考UG266:《 Silicon Labs Gecko Bootloader用户指南》和《AN1086:将Gecko Bootloader与Silicon Labs蓝牙应用程序结合使用》。

内存

蓝牙堆栈保留了Wireless Gecko的部分RAM,并将未使用的RAM留给应用程序。

蓝牙功能的RAM消耗分为:

  • 蓝牙堆栈

  • 蓝牙连接池

  • 蓝牙GATT数据库

  • C堆栈

  • 堆内存

下表显示了RAM使用情况的详细信息。

零件

分配的RAM

蓝牙堆栈

12 kB

蓝牙连接池

4824 +连接数* 480字节

蓝牙GATT数据库

取决于应用程序(20到200个字节)

调用堆栈

2 kB

堆内存

3 KB

蓝牙堆栈

蓝牙协议栈至少需要12 kB RAM。它包括具有低级无线电驱动程序和应用程序编程接口的蓝牙堆栈软件。

蓝牙连接池

蓝牙堆栈使用其自己的静态内存池进行动态内存分配。分配的内存池的大小取决于并行连接的数量。该数字是通过gecko_init()函数中的.bluetooth.max_connections参数设置的。

Bluetooth Connection Pool Size = 4824 + Number of connections * 436 bytes

蓝牙GATT数据库

蓝牙GATT数据库使用RAM。RAM的使用量取决于用户定义的GATT数据库,因此不能一概而论。所有启用了写操作的特性都使用与其定义的长度一样多的RAM。另外,GATT中的每个属性都需要几个字节的RAM来维护属性权限。典型的RAM使用量约为20到200个字节。

调用堆栈

蓝牙堆栈至少需要从RAM保留1.5 kB的呼叫堆栈。应用程序开发人员必须在堆栈要求的1.5 kB之上为应用程序调用堆栈分配RAM。

调用堆栈大小定义的位置取决于编译器和启动文件。默认呼叫堆栈大小为2 kB。可以通过以下命令行选项来覆盖它:

编译器

命令行选项

注意

IAR

--config_def __STACK_SIZE=<size>

调用堆栈在链接器文件中定义。该参数需要传递给链接器。

GCC

-D __STACK_SIZE=<size>

调用堆栈在启动代码中定义。这需要为编译器定义。

堆内存

必须根据应用程序要求保留堆内存。

堆大小定义的位置取决于编译器和启动文件。最小堆大小为3328(0xD00)字节,这也是默认值。可以通过以下命令行选项来覆盖它:

编译器

命令行选项

注意

IAR

--config_def __HEAP_SIZE=<size>

调用堆栈在链接器文件中定义。该参数需要传递给链接器。

GCC

-D__HEAP_SIZE=<size>

调用堆栈在启动代码中定义。这需要为编译器定义。

即时通讯

本章仅适用于EFR32BG1和EFR32BG12。其他设备具有单独的蓝牙定时器,应用程序可自由使用RTCC。

硬件RTCC(实时时钟和日历)已由Bluetooth堆栈设置为以计数器模式运行,并且保留供堆栈使用。但是,RTC值可以由应用程序读取,但不能由应用程序写入。每次启动设备时,都会重置RTC值。

如果应用程序需要类似RTCC的功能,则可以开发以下应用程序代码:

  1. 建立一种从诸如智能手机之类的外部设备检索当前时间的机制。某些智能手机实现了蓝牙时间配置文件,可用于读取时间和日期值。

  2. 将时间转换为“自纪元以来的秒数”(例如,mktime从stdlib 使用)。

  3. 使用蓝牙协议栈的API hardware_get_time(),自重置起经过秒数。

  4. 计算“自纪元以来的秒数”与自复位以来的秒数之间的差异,并将其存储到例如PS键中。

  5. 如果要获取当前日历时间,请使用hardware_get_time获取当前RTC值,将PS键中的值添加到其中,然后使用localtimestdlib获取当前日历时间。

应用ELF文件

ELF(可执行和可链接格式)是可执行文件的标准文件格式。本章介绍ELF文件中与应用程序和Bluetooth堆栈相关的部分。

一些链接器提供了描述已消耗的闪存的输出,但是持续的状态并不明显。蓝牙项目可能包含引导加载程序和蓝牙AppLoader,并且该设备可能具有用于引导加载程序的单独闪存。ELF文件提供有关RAM和闪存使用情况的确切信息。

Simplicity Studio提供了GCC工具链,其中包含命令行工具objdump。该工具可用于从ELF文件获取节信息。

objdump需要输入ELF文件。如果使用该参数-h,则objdump转储节头信息。

IAR

从命令行为示例应用程序调用objdump:

arm-none-eabi-objdump -h IAR\ ARM\ -\ Default/soc-thermometer-iar-mg1p.out

`

然后,objdump提供以下输出:

Sections:

Idx Name Size VMA LMA File off Algn

0 .text_apploader rw 00008fc0 00004000 00004000 00000034 2**11

CONTENTS, ALLOC, LOAD, READONLY, DATA

1 .text_application us 0001e3d3 0000d000 0000d000 00008ff4 2**11

CONTENTS, ALLOC, LOAD, READONLY, CODE

2 A1 rw 00000800 20000000 20000000 000273c8 2**3

ALLOC

3 P3 rw 00000246 20000800 20000800 000273c8 2**2

ALLOC, CODE

4 P3 ui 00000d00 20000a48 20000a48 000273c8 2**3

ALLOC

5 P3 zi 00002b60 20001748 20001748 000273c8 2**8

.text_apploader 包含蓝牙AppLoader。

.text_application包含应用程序代码和只读数据。在此示例中,应用程序的大小以十六进制为0x1e3d3,以十进制为123859字节。

有关其余部分的说明,请参阅IAR文档。

海湾合作委员会

从命令行为示例应用程序调用objdump:

arm-none-eabi-objdump -h GNU\ ARM\ v4.9.3\ -\ Default/soc-thermometer-gcc-mg1p.axf

然后,objdump提供以下输出:

Sections:

Idx Name Size VMA LMA File off Algn

0 .text_bootloader 00000000 00000000 00000000 000306d0 2**0

CONTENTS

1 .text_apploader 00009000 00004000 00004000 00004000 2**0

CONTENTS, ALLOC, LOAD, READONLY, DATA

2 .text_application 0001e4c4 0000d000 0000d000 0000d000 2**8

CONTENTS, ALLOC, LOAD, READONLY, CODE

3 .text_application_ARM.exidx 00000008 0002b4c4 0002b4c4 0002b4c4 2**2

CONTENTS, ALLOC, LOAD, READONLY, DATA

4 .stack_dummy 00000400 20000000 20000000 000306d0 2**3

CONTENTS

5 .text_application_data 000002d0 20000400 0002b4cc 00030400 2**2

CONTENTS, ALLOC, LOAD, CODE

6 .bss 00002a88 20000700 0002b800 00030700 2**8

ALLOC

7 .heap 00000c00 20003188 20003188 00030ad0 2**3

CONTENTS

`

.text_bootloader包含引导加载程序。在此示例中,它是单独加载的,该部分为空。

.text_apploader 包含蓝牙AppLoader。

.text_application包含应用程序代码和只读数据。在此示例中,应用程序的大小为十六进制的0x1e3c3和十进制的124100字节。

.text_application_ARM.exidx 用于调试

.stack_dummy 是调用堆栈的占位符部分。

.text_application_data 是初始化变量的RAM部分。

.bss 是未初始化变量的RAM部分。

.heap 是堆的RAM部分。

有关其余部分的说明,请参阅GCC文档

第一章 Silicon labs BLE 开发介绍相关推荐

  1. 第一章 Python Kivy 学习 -- Kivy介绍及环境安装

    系列文章目录 第一章 Python Kivy 学习 – Kivy介绍及环境安装 第二章 Python Kivy 学习 – Kivy项目开发原理(待编辑) 第三章 Python Kivy 学习 – Ki ...

  2. 软件构造 第一章第二节 软件开发的质量属性

    ​软件构造 第一章第二节 软件开发的质量属性 1.软件系统质量指标 External quality factors affect users 外部质量因素影响用户 Internal quality ...

  3. 第一章 工业机器视觉光源种类介绍

    系列文章目录 第一章 工业机器视觉光源种类.光源控制器介绍 目录 系列文章目录 前言 一.机器视觉--光介绍 1.生活中不同光的来源 2.机器视觉中光的颜色介绍 3.可见光的三原色 二.机器视觉--光 ...

  4. 2023Matlab初级教程- 第一章 初识Matlab与界面介绍

    第一章 Matlab 初识Matlab与界面介绍 文章目录 第一章 Matlab 初识Matlab与界面介绍 Matlab初级教程 1.课程介绍 2.初识Matlab与界面介绍 2.1Matlab介绍 ...

  5. java怎么开始学dos,第一阶段-Java基础知识:【第一章 DOS命令与开发环境的配置 + 第一个程序HelloWorld】...

    加油Ideal星河滚烫  你是人间理想 第一阶段 JAVA基础知识 第一章 开发环境的配置 Dos 命令 在正式进入Java学习之前我们来了解一个看起来B格很高的东西--Dos命令 DOS命令,计算机 ...

  6. 机器学习理论入门:第一章 监督学习与非监督学习介绍

    第一章 监督学习与非监督学习简介 一.机器学习基本概念 概念:研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有 的知识结构使之不断改善自身的性能 输入 基本概念 –特征向量: ...

  7. 【菠萝狗四足机器人】二次开发教程--第一章 【简介与开发环境搭建】

    Py-apple Dynamics 简介与开发环境搭建 1 简介 1.1 何为 菠萝狗 和 Py-Apple Dynamics 1.2 目前支持的功能 2 开发环境搭建 2.1 硬件的搭建 2.1 软 ...

  8. 第一章Java概述及开发环境搭建

    本章目标: 了解SUN公司 了解Java语言的发展史 了解Java主要技术的三个分支 了解Java可移植性的实现原理 SUN公司:java的缔造者 Java发展简史: Oak:Java的前身,1991 ...

  9. 从零学Linux第一章——操作系统演变及历史介绍

    操作系统演变及历史介绍 操作系统的目标 方便:使计算机系统易于使用 有效:以更有效的方式使用计算机系统资源 扩展:方便用户有效开发.测试和引进新功能 操作系统的功用: 进程管理/内存管理/文件 ...

最新文章

  1. 求10 翻译c语言,求助:谁能帮我翻译下最基础的C语言,我是新手,谢谢了!
  2. Unicode 和 UTF-8 的区别
  3. 寒冬已至,传统零售业如何打破僵局“逆境生长”
  4. 双机热备、双机互备与 双机双工的区别
  5. 人工智能的未来是强化学习_多主体强化学习与AI的未来
  6. 字符串常量池(StringTable)总结
  7. MFC之学习绘制矩形、画刷使用
  8. NVIDIA Riva中文手册 (五) —— Riva TTS语音合成API的使用
  9. 2021年安全员-C证(山东省-2021版)考试总结及安全员-C证(山东省-2021版)作业模拟考试
  10. c语言抛物线弓形图像,行列式计算(C#)
  11. 5大原因告诉你,Python程序员为何如此难招!
  12. 自己开发iOS版按键精灵--TTouch
  13. 准确的找到BAT实习机会~我入职了腾讯
  14. 大学计算机教育国外著名教材系列 数据结构,经典数据结构(Java语言版)(影印版)——大学计算机教育国外著名教材系列...
  15. linux虚拟网桥 docker,Docker 使用自定义网桥
  16. 洗地机性价比高的是哪款?性价比高适合入手的洗地机介绍
  17. 使用数据库进行用户身份认证
  18. 自动驾驶感知——毫米波雷达
  19. win10平板模式_双系统更方便,不妨来试试这款大屏幕平板
  20. 51单片机定时器初值计算详解

热门文章

  1. 写小说如何运用思维导图
  2. 老子-----《道德经》
  3. 工作之余找到生活的意义
  4. java 学习网站_Java学习必不可少的十大网站
  5. 专利缴费信息网上补充及管理系统--操作指南
  6. Eclipse中Cannot nest src folder解决方法
  7. android屏幕共享demo,屏幕共享
  8. 共同构建全球发展共同体,代谢组学义不容辞
  9. 2013年企业信息化必备的五大软件
  10. 一周面试题错题整理(一)