蓝牙网状网络的基本原理及应用开发

借助蓝牙 5 的网状网络功能,开发人员可以增强无线连接系统(如物联网设备)的通信范围和网络可用性。但是,网状网络的低功耗无线硬件设计与网状网络软件开发之间存在着复杂的层次,这可能会使开发人员迅速陷入混乱并危及项目进度。

  随着支持蓝牙 5 的智能手机和其他移动平台的出现,时间成为一个关键因素,因为几乎所有行业领域和应用对蓝牙网状网络能力都有需求,而且预计需求会爆炸式增长,开发人员需要快速响应。作为回应,硅片和软件供应商正在推出简化和加速开发流程的解决方案。

  本文将概述蓝牙网状网络的基本原理,然后使用 Silicon Labs 支持网状网络的蓝牙 5 模块系列中的特定设备逐步介绍开发流程。利用这种集成式蓝牙 5 解决方案,开发人员可以快速部署联网设备和应用,从而充分利用蓝牙网状网络。

  本文最后介绍 Silicon Labs 蓝牙网状网络软件开发包,其中详细说明了使用样例网状网络应用代码演示的事件驱动模型。

  蓝牙网状网络需求

  蓝牙网状网络超越了传统蓝牙技术的点对点连接能力。通过相邻联网设备中继消息,蓝牙网状网络将低功耗设备的有效覆盖范围扩展到其发射器功率输出和接收器灵敏度所能支持的实际范围以外。最重要的是,智能手机和其他移动设备的普及使得大家对蓝牙应用非常熟悉,蓝牙网状网络藉由这一事实,为更复杂的网状网络连接应用提供自然的演进。

  在网状网络支持下,使用蓝牙的开发人员现在能够轻松连接家庭自动化、楼宇管理和任意数量物联网应用涉及的大量设备。

  蓝牙网状网络工作原理

  蓝牙网状网络使用概念上很简单的网络节点交互模型(图 1)。专用节点类型可提供节点之间中继消息所需的附加功能,从而扩展通过代理节点与支持蓝牙的移动设备进行交互的网络的有效范围。

编辑搜图

图 1:除基本边缘节点外,蓝牙网状网络还能使用特殊节点类型为其他节点传递消息(中继),充当低功耗节点的缓存(好友),或者将网络(代理)连接到支持蓝牙的移动设备。(图片来源:Silicon Labs)

  其他专用节点类型则可应对降低功耗的要求,使用好友节点缓存消息,以供低功耗节点在长时间休眠状态之间定期轮询。尽管具有这种附加功能,蓝牙网状网络设备仍然可以利用通用属性配置文件 (GATT) 服务来与使用早期蓝牙版本的旧设备进行连接。因此,网状网络设备可以充分利用现有低功耗蓝牙 (BLE) 能力(例如信标),以生成区域特定消息并发送给智能手机,或者将自身标识为资产管理应用。

  蓝牙网状网络还能解决日益增长的对楼宇自动化或其他物联网应用所需受保护网络的安全性的关注。与提供可选安全性以保护单个设备的 BLE 不同,蓝牙网状网络实施的安全性试图保护整个网状网络。

  蓝牙网状网络实现安全的方法特别有意义。其安全方案将“关注点分离”概念引入到网状网络中,为每个设备、网络和整体应用使用单独的安全措施。与每个设备相关联的私有设备密钥 (DevKey) 为仅涉及该节点的配置和调配等操作提供安全性。每个设备都需要网络密钥 (NetKey),才能与网络或子网中的其他节点进行通信。最后,应用级交互(例如发送消息以开灯)则需要应用密钥 (AppKey)。其他安全措施可用于防范中间人或重放攻击等常见威胁。所有措施相互配合,蓝牙网状网络中的安全机制为更复杂的物联网应用所需的信任提供了关键基础。

  然而,实现蓝牙网状网络连接应用给开发人员带来了很大困难。大多数使用网状网络的应用是建立在功耗受限的设备之上,依靠网状网络来扩展低功耗无线电子系统的有效覆盖范围。创建支持网状网络的合适低功耗硬件设备所涉及的挑战,甚至能让最有经验的硬件开发人员停滞不前。即使在完成其定制蓝牙设计之后,为满足国家认证要求,开发人员也可能面临巨大的成本压力和旷日持久的延迟。软件开发人员在寻找兼容的蓝牙网状网络堆栈并利用其来构建软件层以便能支持自己的应用时,也会发生延迟。然而,借助 Silicon Laboratories 的蓝牙硬件和软件,开发人员可以在低功耗设备中快速部署蓝牙网状网络功能,以满足自己的应用需求。

  蓝牙模块

  Silicon Labs 的蓝牙网状网络解决方案基于其低功耗蓝牙 BGM13P 硬件模块,该模块结合了无线处理器和全套蓝牙堆栈,以 12.9×15.0×2.2 mm 的封装提供经过认证的完整蓝牙系统。该模块的核心是 EFR32BG13 Blue Gecko 无线片上系统 (SoC),可提供核心功能。EFR32BG13 SoC 集成了 32 位 Arm® Cortex®-M4 内核、2.4 GHz 无线电子系统、512 KB 闪存、64 KB RAM 以及丰富的模拟和数字外设。除了片上硬件加密加速器之外,该 SoC 还通过安全管理单元支持不断增长的更高安全性需求;该安全管理单元为外设提供的细粒度访问控制与存储器保护单元为存储器提供的相同。

  EFR32BG13 SoC 可作为定制蓝牙硬件设计的基础。使用 SoC 时,开发人员不仅要负责满足 SoC 支持电路等设计要求,还要对完成的设计进行必要的认证。该模块提供有全面认证的设计,其中的 EFR32BG13 带有所需的支持电路,包括数个振荡器源、两个晶体和端口驱动器。与此同时,该模块还提供了一系列省电特性,因此开发人员能够响应持续存在的低功耗设备需求。

  该模块在活动模式下仅消耗 87 µA/MHz,在全 RAM 保持的深度休眠模式下仅消耗 1.4 μA。为了帮助最大限度地延长停留在低功耗深度休眠模式下的时间,工程师可以利用低能耗传感器接口和低能耗定时器等特性。使用低能耗传感器接口,工程师可以对模块的集成有限状态机和模拟外设进行编程,以在处理器保持深度休眠模式的同时采集和处理传感器信号。类似地,通过低能耗定时器,工程师可以输出简单波形并监控实时时钟/计数器,以便在指定时间内执行操作,而无需处理器参与。

  当然,无线设备的功耗一般取决于无线电子系统的效率。本例中,该模块的 2.4 GHz 无线电子系统在接收模式下仅消耗 9.9 mA,在 0 dBm 输出功率的发射模式下仅消耗 8.5 mA。即便如此,该模块还提供了通过射频控制节省功耗的额外特性。开发人员可以对模块中的射频检测功能进行编程,以在检测到宽带射频能量时唤醒处理器。通过这种方法,开发人员可以在无活动期间使模块保持深度休眠而不会丧失通信。但是,如前所述,开发人员也可以将某个设备配置为蓝牙 5 低功耗节点,其能够简单地定期从深度休眠中唤醒以轮询好友节点,获取缓存的消息。

  系统开发

  针对其所有特性,该模块在实现方面几乎没有任何困难。开发人员可以简单地将该模块放入一个带有处理器的设计中,将其用作蓝牙网络协处理器(图 2A)。或者,开发人员可以将该模块用作完整的系统解决方案(图 2B)。在这种独立模式下,开发人员可以在模块的 EFR32BG13 处理器上运行应用代码,并使用 EFR32BG13 集成的模拟和数字外设在简单的物联网设计中进行信号采集。

编辑搜图

图 2:设计人员可以将 BGM13P 模块用作主机 CPU 的蓝牙协处理器 (A),或者单独使用 (B),利用模块集成的 EFR32BG13 SoC 执行应用程序甚至采集传感器数据。(图片来源:Silicon Labs)

  开发人员可以使用该模块的一个集成天线的版本 BGM13P22F512GA-V2,以进一步简化蓝牙设计。针对要应对更具挑战性射频环境的设计,开发人员可以采用 BGM13P22F512GE-V2,这是一个带有 U.FL 连接器的版本,可以连接蓝牙兼容的平贴片天线,例如 Taoglas 的 FXP74.07.0100A。

  Silicon Labs 甚至通过 SLWSTK6101C 开发套件消除了该级别的硬件实现。SLWSTK6101C 设计用于配合其不同蓝牙设备的插件板使用,提供代表性的物联网设计,包含 Macronix 的 MX25R8035F 8 Mb 闪存、Sharp Microelectronics 的 LS013B7DH03 128 x 128 LCD 和 Silicon Labs 的 Si7021 温度与湿度传感器。在这种情况下,开发人员将包含 BGM13P 模块的 SLWRB4306A 无线电电路板插入 SLWSTK6101C 板。

  除了作为可立即投产的设计之外,全套电路板还提供经过验证的参考设计,工程师可以使用它来检查与闪存、LCD 和传感器等设备接口的不同方法。

  例如,8 Mb 闪存和 LCD 通过其 SPI 总线连接到模块,而 Si7021 传感器的 I2C 接口与开发板上的外部针座共享总线。Silicon Labs 演示了一种设计简单接口的方法,它使传感器在正常情况下保持禁用并与共享总线电气隔离。当模块的 PD15 输入变为高电平时,SENSOR_ENABLE 输出变为高电平,将传感器连接到 3.3 V VMCU 电源轨和 I2C 总线(图 3)。

编辑搜图

图 3:除了提供硬件评估平台之外,Silicon Labs SLWSTK6101C 开发套件还可充当参考设计,展示与此处所示的 Silicon Labs Si7021 传感器等外部设备接口的方法。(图片来源:Silicon Labs)

  共享 I2C 总线针座只是设计用来支持该平台开发的几个特性之一(图 4)。除了板载 J-Link 调试器之外,该板还提供了数据包追踪接口 (PTI),允许工程师详细分析数据包。PTI 建立在 EFR32BG13 SoC 内置的数据包和状态追踪单元之上,提供对系统发送和接收的所有数据包的非侵入式捕捉。为了分析蓝牙网状网络等复杂协议,该数据包追踪功能提供了一个对于优化和调整低级网络通信至关重要的工具。

编辑搜图

图 4:Silicon Labs SLWSTK6101C 套件有多个接口用于数据包追踪、能量监测和低级 Arm 嵌入式追踪宏单元 (ETM) 追踪,为工程师深入分析设计操作和性能提供了丰富的工具集。(图片来源:Silicon Labs)

  虽然网络专家需要 PTI 这样的功能来优化网络,但系统开发人员需要能帮助其发现可能导致功耗过大的应用低效问题的工具。对于此类应用级功耗优化,Silicon Labs Simplicity Studio 能量分析器可提供代码级功耗分析。

  同数据包追踪工具一样,能量分析器也是对底层硬件加以利用。在这种情况下,电路板包括一个专用能量监测电路,其由电流传感器电阻、电流检测放大器和增益级组成,将输出传送到电路板的控制器,供开发主机系统访问(图 5)。并联增益级允许能量监测器以两个不同的分辨率级别测量 0.1 μA 至 95 mA 的电流:250 μA 以上使用 0.1 mA 分辨率;低于 250 μA 阈值使用 1 μA 分辨率。

编辑搜图

图 5:内置于 BGM13P 蓝牙模块的专用能量监测电路和处理控制器可提供 0.1 μA 至 95 mA 的非侵入式电流测量。(图片来源:Silicon Labs)

  当能量监测电路产生电流测量结果时,EFR32BG13 内置的低级追踪机制可以定期对处理器的程序计数器进行采样,并将结果通过设备的串行线输出引脚输出。通过将能量监测器的结果与此程序追踪输出相结合,能量分析器可以实时显示与设备上运行的代码相关的能耗(图 6)

编辑搜图

图 6:Simplicity Studio 能量分析器将能量监测器输出与程序追踪数据相结合,以实时显示与实际代码相关的电流消耗。(图片来源:Silicon Labs)

  网状网络应用开发

  硬件工程师可以使用开发套件来优化其硬件设计,而软件开发人员可以利用 Silicon Labs 的综合软件开发环境来快速创建网状网络应用。Silicon Labs 的蓝牙 5 网状网络堆栈随同 Simplicity Studio 提供,其用特定网状网络资源扩展了基本蓝牙堆栈。因此,开发人员可以轻松地从较传统的蓝牙协议(如信标或点对点通信)转移到全网状网络拓扑(图 7)。

编辑搜图

图 7:Silicon Labs 蓝牙网状网络堆栈用网状网络层(绿色)扩展了早期蓝牙功能(蓝色),使得开发人员能够充分利用从信标到全网状网络配置的全部蓝牙特性。(图片来源:Silicon Labs)

  Simplicity Studio 与基于 Silicon Labs BGM13P 的 SLWRB4306A 和 SLWSTK6101C 开发板一起使用,让开发人员能利用适当的软件开发套件 (SDK) 配置其环境。对于蓝牙开发,Studio 提供了 Silicon Labs 的蓝牙网状网络 SDK 以及预先构建的演示二进制文件和源代码。在此环境中,开发人员可以使用实现了完整蓝牙网状网络应用的样例代码。

  这些样例应用程序与开发板和移动应用配合使用,旨在演示蓝牙网状网络的操作,让开发人员能全面了解典型网状网络的操作,包括调配、配置和应用相关的使用。为了部署样例应用程序,工程师针对一组开发板运行 Simplicity Studio,这些开发板分别配置为联网照明应用中的灯或开关。通过使用样例代码和硬件,工程师可以更好地了解典型网状网络应用从设备上电开始的各个操作阶段。

  借助 Silicon Labs 的软件架构,蓝牙操作可以一系列事件展开,使用预定义的事件 ID 来表示事件的性质。在样例软件包中,main() 例程在上电或复位时运行,先调用一系列初始化例程,然后进入主循环,本例中主循环只包含两行代码(列表 1)。

  int main()

  {

  #ifdef FEATURE_SPI_FLASH

  /* Put the SPI flash into Deep Power Down mode for those radio boards where it is available */

  MX25_init();

  MX25_DP();

  /* We must disable SPI communication */

  USART_Reset(USART1);

  #endif /* FEATURE_SPI_FLASH */

  enter_DefaultMode_from_RESET();

  #if (EMBER_AF_BOARD_TYPE == BRD4304A)

  LNA_init();

  #endif

  gecko_init(&config);

  #ifdef FEATURE_PTI_SUPPORT

  APP_ConfigEnablePti();

  #endif // FEATURE_PTI_SUPPORT

  RETARGET_SerialInit();

  /* initialize LEDs and buttons.Note: some radio boards share the same GPIO for button & LED.* Initialization is done in this order so that default configuration will be button for those

  * radio boards with shared pins.led_init() is called later as needed to (re)initialize the LEDs

  * */

  led_init();

  button_init();

  LCD_init();

  while (1) {

  struct gecko_cmd_packet *evt = gecko_wait_event();

  handle_gecko_event(BGLIB_MSG_ID(evt-》header), evt);

  }

  }

  列表 1:Simplicity Studio 提供了一个综合开发环境,其中包括样例代码,例如此网状网络照明主例程,其演示了初始化和事件处理循环。(代码来源:Silicon Labs)

  在主循环的第一行中,函数 gecko_wait_event() 在阻塞流程的同时等待事件出现,事件队列由较低级别填充。虽然开发人员往往会避免使用阻塞功能,但此方法在这种情况下特别有效,因为蓝牙堆栈在此阻断模式下会自动管理低功耗休眠状态。对于不能容许阻塞等待的特定应用要求,SDK 还提供了一个非阻塞函数,如果队列为空,则返回下一个事件或 NULL。但使用此函数时,开发人员需要自行处理低功耗休眠管理。

  在主循环的第二行中,处理函数 handle_gecko_event() 根据其事件 ID 处理最新事件 (evt)(列表 2)。当设备上电时,堆栈发出系统引导事件 (gecko_evt_system_boot_id)。事件处理程序进而调用一系列初始化函数,包括 gecko_cmd_mesh_node_init(),其会初始化蓝牙网状网络堆栈。然后,处理程序调用其他函数来提供与该事件类型(由其相关事件 ID 表示)相关联的功能。

  /**

  * Handling of stack events.Both Bluetooth LE and Bluetooth mesh events are handled here.*/

  static void handle_gecko_event(uint32_t evt_id, struct gecko_cmd_packet *evt)

  {

  struct gecko_bgapi_mesh_node_cmd_packet *node_evt;

  struct gecko_bgapi_mesh_generic_server_cmd_packet *server_evt;

  struct gecko_msg_mesh_node_provisioning_failed_evt_t *prov_fail_evt;

  if (NULL == evt) {

  return;

  }

  switch (evt_id) {

  case gecko_evt_system_boot_id:

  // check pushbutton state at startup.If either PB0 or PB1 is held down then do factory reset

  if (GPIO_PinInGet(BSP_GPIO_PB0_PORT, BSP_GPIO_PB0_PIN) == 0 || GPIO_PinInGet(BSP_GPIO_PB1_PORT, BSP_GPIO_PB1_PIN) == 0) {

  initiate_factory_reset();

  } else {

  struct gecko_msg_system_get_bt_address_rsp_t *pAddr = gecko_cmd_system_get_bt_address();

  set_device_name(&pAddr-》address);

  // Initialize Mesh stack in Node operation mode, wait for initialized event

  gecko_cmd_mesh_node_init();

  // re-initialize LEDs (needed for those radio board that share same GPIO for button/LED)

  led_init();

  }

  break;

  。。.case gecko_evt_mesh_node_initialized_id:

  printf(node initialized\r\n);

  struct gecko_msg_mesh_node_initialized_evt_t *pData = (struct gecko_msg_mesh_node_initialized_evt_t *)&(evt-》data);

  if (pData-》provisioned) {

  。。.} else {

  printf(node is unprovisioned\r\n);

  LCD_write(unprovisioned, LCD_ROW_STATUS);

  printf(starting unprovisioned beaconing.。。\r\n);

  gecko_cmd_mesh_node_start_unprov_beaconing(0x3); // enable ADV and GATT provisioning bearer

  }

  break;

  case gecko_evt_mesh_node_provisioning_started_id:

  printf(Started provisioning\r\n);

  LCD_write(provisioning.。。, LCD_ROW_STATUS);

  // start timer for blinking LEDs to indicate which node is being provisioned

  gecko_cmd_hardware_set_soft_timer(32768 / 4, TIMER_ID_PROVISIONING, 0);

  break;

  case gecko_evt_mesh_node_provisioned_id:

  _my_index = 0; // index of primary element hardcoded to zero in this example

  lightbulb_state_init();

  printf(node provisioned, got index=%x\r\n, _my_index);

  // stop LED blinking when provisioning complete

  gecko_cmd_hardware_set_soft_timer(0, TIMER_ID_PROVISIONING, 0);

  LED_set_state(LED_STATE_OFF);

  LCD_write(provisioned, LCD_ROW_STATUS);

  break;

  case gecko_evt_mesh_node_provisioning_failed_id:

  prov_fail_evt = (struct gecko_msg_mesh_node_provisioning_failed_evt_t *)&(evt-》data);

  printf(provisioning failed, code %x\r\n, prov_fail_evt-》result);

  LCD_write(prov failed, LCD_ROW_STATUS);

  /* start a one-shot timer that will trigger soft reset after small delay */

  gecko_cmd_hardware_set_soft_timer(2 * 32768, TIMER_ID_RESTART, 1);

  break;

  。。.}

  }

  列表 2:开发人员可以检查 Silicon Labs 网状网络样例代码中的关键设计模式,例如调配事件处理,相关代码片段位于网状网络灯主程序中调用的 handle_gecko_event() 事件处理程序(参见列表 1)。(代码来源:Silicon Labs)

  蓝牙网状网络中的关键事件系列之一与调配过程有关。设备上电并完成其初始化序列之后,便进入信标模式,向网络宣告其自身以供调配。当调配完毕(或失败)时,样例代码会使用开发套件 LCD 和 LED 来指示状态。通过检查事件处理程序针对每个调配状态的代码块,开发人员可以快速了解该调配序列和选项。

  同样,软件工程师可以使用样例处理程序代码作为创建其应用级功能的指南。例如,蓝牙网状网络中的一个关键概念是使用发布-订阅模型将共享某些功能关系的节点关联起来(图 8)。

编辑搜图

图 8:应用开发人员使用蓝牙的发布-订阅模型将设备组合成功能分组,例如由一个或多个开关控制的一组灯。(图片来源:Silicon Labs)

  通过这种方法,数个智能灯泡可以订阅一个开关发布者。当最终用户激活该开关时,其将发布 ON/OFF 事件。该事件将通过网状网络级联到订阅的智能灯泡,其事件处理程序将采取适当的操作。Silicon Labs 样例代码演示了这一过程:首先是网状网络中的联网开关发布 ON/OFF 请求(列表 3),然后是联网灯的相应响应(列表 4)。

  /**

  * This function publishes one on/off request to change the state of light(s) in the group.* Global variable switch_pos holds the latest desired light state, possible values are

  * switch_pos = 1 -》 PB1 was pressed, turn lights on

  * switch_pos = 0 -》 PB0 was pressed, turn lights off

  *

  * This application sends multiple requests for each button press to improve reliability.* Parameter retrans indicates whether this is the first request or a re-transmission.* The transaction ID is not incremented in case of a re-transmission.*/

  void send_onoff_request(int retrans)

  {

  uint16 resp;

  uint16 delay;

  struct mesh_generic_request req;

  req.kind = mesh_generic_request_on_off;

  req.on_off = switch_pos ?MESH_GENERIC_ON_OFF_STATE_ON : MESH_GENERIC_ON_OFF_STATE_OFF;

  // increment transaction ID for each request, unless it‘s a retransmission

  if (retrans == 0) {

  trid++;

  }

  /* delay for the request is calculated so that the last request will have a zero delay and each

  * of the previous request have delay that increases in 50 ms steps.For example, when using three

  * on/off requests per button press the delays are set as 100, 50, 0 ms

  */

  delay = (request_count - 1) * 50;

  resp = gecko_cmd_mesh_generic_client_publish(

  MESH_GENERIC_ON_OFF_CLIENT_MODEL_ID,

  _my_index,

  trid,

  0, // transition

  delay,

  0, // flags

  mesh_generic_request_on_off, // type

  1, // param len

  &req.on_off /// parameters data

  )-》result;

  if (resp) {

  printf(gecko_cmd_mesh_generic_client_publish failed,code %x\r\n, resp);

  } else {

  printf(request sent, trid = %u, delay = %d\r\n, trid, delay);

  }

  }

  列表 3:这个来自 Silicon Labs 网状网络开关样例应用程序的代码片段说明了如何使用蓝牙 5 发布过程 (gecko_cmd_mesh_generic_client_publish) 来请求订阅该事件流的灯的状态改变(开或关)。(代码来源:Silicon Labs)

  static void onoff_request(uint16_t model_id,

  uint16_t element_index,

  uint16_t client_addr,

  uint16_t server_addr,

  uint16_t appkey_index,

  const struct mesh_generic_request *request,

  uint32_t transition_ms,

  uint16_t delay_ms,

  uint8_t request_flags)

  {

  printf(ON/OFF request: requested state=《%s》, transition=%u, delay=%u\r\n,

  request-》on_off ?ON : OFF, transition_ms, delay_ms);

  if (lightbulb_state.onoff_current == request-》on_off) {

  printf(Request for current state received; no op\n);

  } else {

  printf(Turning lightbulb 《%s》\r\n, request-》on_off ?ON : OFF);

  if (transition_ms == 0 && delay_ms == 0) { // Immediate change

  lightbulb_state.onoff_current = request-》on_off;

  lightbulb_state.onoff_target = request-》on_off;

  if (lightbulb_state.onoff_current == MESH_GENERIC_ON_OFF_STATE_OFF) {

  LED_set_state(LED_STATE_OFF);

  } else {

  LED_set_state(LED_STATE_ON);

  }

  } else {

  // Current state remains as is for now

  lightbulb_state.onoff_target = request-》on_off;

  LED_set_state(LED_STATE_TRANS); // set LEDs to transition mode

  gecko_cmd_hardware_set_soft_timer(TIMER_MS_2_TIMERTICK(delay_ms + transition_ms), TIMER_ID_TRANSITION, 1);

  }

  lightbulb_state_store();

  }

  if (request_flags & MESH_REQUEST_FLAG_RESPONSE_REQUIRED) {

  onoff_response(element_index, client_addr, appkey_index);

  } else {

  onoff_update(element_index);

  }

  }

  列表 4:Silicon Labs 网状网络灯样例包括用于特定应用级事件的例程,例如这个打开或关闭 LED 以响应开关所发布请求的函数(参见列表 3)。(代码来源:Silicon Labs)

  除了用于节点开发的蓝牙堆栈和 SDK 之外,Silicon Labs 还提供了蓝牙网状网络的最终环节——连接移动设备。大多数移动设备支持蓝牙 4,虽然其无线电可以支持蓝牙 5 要求,但它们没有支持蓝牙 5 网状网络层的堆栈。Silicon Labs 为移动应用开发人员提供了额外的软件堆栈来,而该堆栈可提供网状网络功能,因此便能克服这一局限性(图 9)。

编辑搜图

图 9:开发人员可以将 Silicon Labs 针对移动设备的网状网络堆栈添加到其移动应用中,使得蓝牙 4 移动设备可以在蓝牙 5 网状网络中使用。(图片来源:Silicon Labs)

  总结

  蓝牙 5 网状网络为各种各样已经利用智能手机和其他移动设备进行点对点通信的应用提供了一个自然的过渡。然而,蓝牙 5 网状网络的部署对硬件和软件设计提出了重大挑战,特别是在物联网等功耗受限的应用中。此外,硬件工程师需要满足最小基底面和低功耗的要求,软件工程师则需要构建使用最少资源来执行复杂通信协议的软件。BGM13P 模块、SLWSTK6101C 开发板以及节点和移动设备的蓝牙堆栈的结合,使工程师有一个综合性平台来快速开发使用蓝牙网状网络的应用

【以上信息由艾博检测整理发布,如有出入请及时指正,如有引用请注明出处,欢迎一起讨论,我们一直在关注其发展!专注:CCC/SRRC/CTA/运营商入库】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/20726.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

今年的面试难度有点大....

大家好,最近有不少小伙伴在后台留言,又得准备面试了,不知道从何下手! 不论是跳槽涨薪,还是学习提升!先给自己定一个小目标,然后再朝着目标去努力就完事儿了! 为了帮大家节约时间&a…

Windows Cygwin 配置

Windows Cygwin 配置 一、什么是Cygwin? Cygwin,原Cygnus出品(已被红帽收购),目前是RedHat名下的项目。项目的目的是提供运行于 Windows 平台的类 Unix 环境(以 GNU 工具为代表)。为了达到这个…

一天吃透SpringCloud面试八股文

1、什么是Spring Cloud ? Spring cloud 流应用程序启动器是基于 Spring Boot 的 Spring 集成应用程序,提供与外部系统的集成。Spring cloud Task,一个生命周期短暂的微服务框架,用于快速构建执行有限数据处理的应用程序。 Sprin…

前端|想到什么写什么

记录当初伤害过我的一些概念😊 文章目录 一、闭包二、深拷贝、浅拷贝三、slice、splice、join、split、filter、concat、sort、some、every四、for in和for of、 map和foreach五、原型和原型链六、跨域七、vue相关1、生命周期2、响应式原理3、watch和computed4、vu…

协程切换原理与实践 -- 从ucontext api到x86_64汇编

目录 1.协程切换原理理解 2.ucontext实现协程切换 2.1 实现流程 2.2 根据ucontext流程看协程实现 2.3 回答开头提出的问题 3.x86_64汇编实现协程切换 3.1libco x86_64汇编代码分析 3.2.保存程序返回代码地址流程 3.3.恢复程序地址以及上下文 4.实现简单协程框架 1.协程…

MySQL 中 CONCAT 函数使用

1:创建数据表: CREATE TABLE user ( id int NOT NULL AUTO_INCREMENT, code varchar(255) NOT NULL, name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT3 DE…

8款数据迁移工具选型,主流且实用

前言:ETL(是Extract-Transform-Load的缩写,即数据抽取、转换、装载的过程),对于企业应用来说,我们经常会遇到各种数据的处理、转换、迁移的场景。今天特地给大家汇总了一些目前市面上比较常用的ETL数据迁移工具,希望对…

小黑子—Java从入门到入土过程:第九章-IO流

Java零基础入门9.0 Java系列第九章- IO流1. 初识IO流2. IO流的体系2.1 字节流2.1.1 FileOutputStream 字符串输出流2.1.1 - I 字符串输出流的细节2.1.1 - II FileOutputStream写数据的3种方式2.1.1 -III FileOutputStream写数据的两个小问题 2.1.2 FileInputStream 字符串输入流…

拼多多买家如何导出“个人中心”订单信息

经常在拼多多买东西,有时候需要把订单的物流信息导出来,方便记录和统计。现介绍如何使用dumuz工具来实现批量下载拼多多订单。 应用功能描述 模拟人工操作拼多多"个人中心-我的订单”订单网页,批量查询获取拼多多自己买的商品的订单数…

javaweb项目实战之myBlog

项目简介 技术栈: Java Mysql Html Ajax Css JS Json 项目说明 :项目使用maven创建,使用MVC架构模式 表示层:通俗讲就是展现给用户的界面和控制器层Servlet,接受请求、封装数据、调用业务 逻辑层,响…

JavaScript实现计算100之间能被5整除的数的代码

以下为实现计算100之间能被5整除的数的程序代码和运行截图 目录 前言 一、计算100之间能被5整除的数 1.1 运行流程及思想 1.2 代码段 1.3 JavaScript语句代码 1.4 运行截图 前言 1.若有选择,您可以在目录里进行快速查找; 2.本博文代码可以根据题…

平衡二叉树理论详解

文章目录 基本概念平衡二叉树插入结点LL(左单旋)RR(右单旋)LR(左右旋)RL(右左旋) 示例插入推导过程 基本概念 平衡二叉树是一棵空树或它的左右两个子树的高度差的绝对值不超过1&…

linux环境下设置python定时任务

linux环境下设置python定时任务 Linux 系统提供了使用者控制计划任务的命令 :crontab 命令 1、在linux环境执行命令,进入编辑界面 crontab -e2、按键盘 i 键,进入编辑模式,输入以下内容,设置2个定时任务 定时任务1:每隔10分钟执…

C语言爬取HTML-爬取壁纸 文末附源码

前言:这学期计算机软件课程设计的其中一个题目是使用C语言爬取HTML,本打算使用C语言的CSpidr库来实现,但是因为它的依赖liburi没有找到在哪里安装,所以放弃了这个想法,使用的是curl以及libxml2这两个库,能够…

GOOGLE|只有大模型才能理解你举的例子(In-context learning)是什么

一、概述 title:LARGER LANGUAGE MODELS DO IN-CONTEXT LEARNING DIFFERENTLY 论文地址:https://arxiv.org/abs/2303.03846 参考:https://www.xiaohongshu.com/user/profile/5f01057f0000000001003c91/640aa237000000001303d871 1.1 Moti…

springboot基于vue的地方美食分享网站

开发技术介绍 Java介绍 JavaScript是一种网络脚本语言,广泛运用于web应用开发,可以用来添加网页的格式动态效果,该语言不用进行预编译就直接运行,可以直接嵌入HTML语言中,写成js语言,便于结构的分离&…

Python文件上传 S3(AWS) 简单实现

1.AWS设置 建立aws账户,进入到S3界面 点击 "Create bucket" 一系列操作之后——这里给bucket命名为csfyp 2. Python部分 python需要先: pip install loguru pip install boto3 这两个包含一些连接python和s3 连接的api 然后直接上代码…

Redis学习---05

一、Redis集群搭建,Redis主从复制,读写分离 默认情况下每台redis服务器都是主节点。 (1) 主从复制:是指将一台redis服务器的数据,复制道其他redis服务。前者成为主节点,后者成为从节点。默认情况下每一台redis服务器…

puppeteer-不需重构,无痛加强vue单页面应用的SEO,提升百度收录排名

背景 最近产品觉得我们网站在百度收录上排名太靠后了,又不肯花钱,就让我们想办法提升网站的SEO。由于项目是用vue3写的,并且已经迭代多个版本了,用nuxt实在不适宜,当然俺的开发水平也不够,周期也会拉得很长…

【华为机试】——每日刷题经验分享

【华为机试】——每日刷题经验分享😎 前言🙌题目:HJ9 提取不重复的整数 总结撒花💞 😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! &a…