“NRF52832DK-Mesh组网实验”的版本间的差异
第116行: | 第116行: | ||
4、至此我们的mesh组网的lightswitch实验测试完成。 | 4、至此我们的mesh组网的lightswitch实验测试完成。 | ||
+ | |||
+ | === 源码详解 === | ||
+ | |||
+ | == Beaconing example == | ||
+ | |||
+ | === 实验简介 === | ||
+ | |||
+ | === 硬件说明 === | ||
+ | |||
+ | === 软件说明 === | ||
+ | |||
+ | === 实验现象 === | ||
+ | |||
+ | === 源码详解 === | ||
+ | |||
+ | == Coexistence example == | ||
+ | |||
+ | === 实验简介 === | ||
+ | |||
+ | === 硬件说明 === | ||
+ | |||
+ | === 软件说明 === | ||
+ | |||
+ | ==== 将Mesh集成到nRF5 SDK示例中 ==== | ||
+ | 用于网格的nRF5 SDK与Nordic的nRF5 SDK兼容。 这使您可以将nRF5 SDK中的资源包括在现有的Mesh项目中,也可以将nRF5 SDK中的Mesh功能包括在nRF5 SDK示例中。 | ||
+ | |||
+ | 请参阅构建网格堆栈和示例,以获取有关如何下载和安装nRF5 SDK的信息。 查看共存示例,以了解如何将nRF5 SDK功能与用于网格的nRF5 SDK同时使用。 | ||
+ | |||
+ | ===== 动态记忆 ===== | ||
+ | 在将nRF5 SDK功能与nRF5 Mesh SDK功能一起使用时(如并存示例所示),您可能会遇到以下情况:应用程序注意事项可能需要更改动态内存的分配方式和可分配的动态内存量。 网格堆栈使用网格内存管理器界面进行动态内存分配。 默认的后端mesh_mem_stdlib.c使用标准库malloc(),该库需要定义足够大的堆大小。 可以通过用另一个内存管理器替换后端来更改此行为。 | ||
+ | |||
+ | 如果使用Segger Embedded Studio构建应用程序,请在“项目选项”>“代码”>“运行时内存区域”设置中将“堆大小”设置为8192字节。 | ||
+ | |||
+ | ===== 并发的SoftDevice和Mesh活动 ===== | ||
+ | 同时运行SoftDevice和Mesh时,最大的性能问题通常来自无线电时间争用。虽然SoftDevice通常在预定的短脉冲中运行,但Mesh会尝试尽可能多地使用无线电。只要SoftDevice没有无线电活动,Mesh就会连续扫描和通告。 SoftDevice活动将减少Mesh广播的时间,并且为了保持一致的Mesh性能,必须在不影响用户体验的情况下尽可能保守地设置SoftDevice无线电参数。 | ||
+ | |||
+ | 在使用SoftDevice进行广告时,请尝试使用您的使用情况可以容许的最大广告间隔。如果可能,请在不需要时关闭SoftDevice广告商,仅在您希望收到连接请求时才激活它。如果您只需要发送不可连接的,不可扫描的广告(例如,针对第三方信标协议),请使用Mesh Advertiser API,因为它与Mesh一起使用时可以进行最少的上下文切换。 | ||
+ | |||
+ | 当SoftDevice在连接中运行时: | ||
+ | |||
+ | 尝试协商应用程序可以允许的最大连接间隔。如果需要通过连接的高吞吐量,则在每个连接事件中发送更多的数据要比减少连接间隔更好,因为大部分开销来自上下文切换。 | ||
+ | |||
+ | 如果网状设备在其SoftDevice连接中充当外围设备(从设备),则还可以增加“从设备等待时间”,这应使SoftDevice跳过连接事件,而不会增加通过链接的任何传出数据传输的等待时间。 | ||
+ | |||
+ | 与广告一样,建议仅在需要时才保持连接活动。空闲的软设备连接对网状网性能的影响几乎与具有大量流量的连接一样多,特别是在从属延迟较低的情况下。 | ||
+ | |||
+ | 基于SoftDevice的扫描对所有SoftDevice活动的Mesh性能影响最大。当SoftDevice正在扫描时,Mesh无法接收数据包,因此每个SoftDevice扫描窗口都会替换Mesh扫描。仅在尝试建立连接或需要活动扫描时才应使用SoftDevice扫描。如果需要常规的被动BLE扫描(用于侦听信标或其他第三方活动),请通过使用nrf_mesh_rx_cb_set函数设置RX回调来挂接到Mesh扫描器。如果您的应用程序需要主动扫描或需要启动连接,则应尽可能保守地设置扫描参数。较长的扫描间隔和较短的扫描窗口将使Mesh拥有更多的时间进行自身的无线电活动。类似地,建立上下文时在短时间内执行连续扫描可能比执行长时间运行的占空比扫描有利,因为上下文切换会导致很多不必要的开销。最后,强烈建议为SoftDevice连接启动调用设置超时,以避免长时间的空闲扫描。 | ||
+ | |||
+ | 由于Mesh无法主动阻止SoftDevice无线电活动,因此减少同时运行SoftDevice活动的设备上的Mesh活动不会直接影响SoftDevice的性能。但是,附近的其他Mesh设备会干扰广告渠道中的SoftDevice活动,这可能会使连接启动花费更长的时间。 | ||
+ | |||
+ | 通常,Mesh必须在SoftDevice活动之间执行其所有无线电操作,因此,如果设备在执行SoftDevice无线电操作时正在发送大量Mesh数据包,则它将在此上花费大部分Mesh时间,而不是接收传入的数据。为了解决这个问题,请根据可用的无线电时间调整输出数据包的数量,以减少Mesh数据包的发送。如果可能,请通过在CORE_TX_ROLE_RELAY角色上调用mesh_opt_core_adv_set来暂停耗时的SoftDevice操作期间的Mesh数据包中继。 | ||
+ | |||
+ | ===== 在用于网格示例的nRF5 SDK中包括nRF5 SDK ===== | ||
+ | 根据您的工具链: | ||
+ | |||
+ | 使用Segger Embedded Studio时,请添加代码文件并包括相应SES项目文件的路径。 | ||
+ | |||
+ | 使用CMake构建用于网格堆栈的nRF5 SDK时,添加代码文件并包括指向相应CMakeLists.txt文件的路径。 SDK_ROOT根符号用于引用nRF5 SDK安装文件夹(例如,请参阅Light Switch服务器示例中的CMakeLists.txt)。 | ||
+ | |||
+ | 网格示例项目已经在其include /目录中包含sdk_config.h文件。 这些文件是默认SDK配置文件的副本,并且网格示例所需的所有更改都包含在示例目录中的include / app_config.h文件中。 | ||
+ | |||
+ | 注意, | ||
+ | |||
+ | 必须先在SDK配置文件中显式启用某些SDK功能,然后才能使用它们。 有关详细信息,请参见SDK文档页面SDK配置头文件。 | ||
+ | |||
+ | ===== 在nRF5 SDK示例中包括用于网格功能的nRF5 SDK ===== | ||
+ | 在nRF5 SDK示例的项目文件中包括来自nRF5 SDK for Mesh的以下源文件: | ||
+ | * All C files in <code>mesh/core/src</code> | ||
+ | * All C files in <code>mesh/bearer/src</code> | ||
+ | * All C files in <code>mesh/prov/src</code> except nrf_mesh_prov_bearer_gatt.c | ||
+ | * All C files in <code>mesh/access/src</code> | ||
+ | * All C files in <code>mesh/dfu/src</code> | ||
+ | * All C files in <code>mesh/stack/src</code> | ||
+ | |||
+ | * <code>models/foundation/config/src/config_server.c</code> | ||
+ | * <code>models/foundation/config/src/composition_data.c</code> | ||
+ | * <code>models/foundation/config/src/packed_index_list.c</code> | ||
+ | * <code>models/foundation/health/src/health_server.c</code> | ||
+ | * Any other mesh models that are used in your application | ||
+ | * <code>external/micro-ecc/uECC.c</code> | ||
+ | * <code>examples/common/src/assertion_handler_weak.c</code> | ||
+ | * <code>examples/common/src/mesh_provisionee.c</code> | ||
+ | |||
+ | 注意 | ||
+ | |||
+ | 如果不需要各种网格特征(例如DFU),则可以从项目文件中省略相应的文件。但是,在其位置添加examples / nrf_mesh_weak.c以提供缺少的API函数的存根。 | ||
+ | |||
+ | 将以下文件夹添加到nRF5 SDK示例的项目包含路径: | ||
+ | * <code>mesh/core/api</code> | ||
+ | * <code>mesh/core/include</code> | ||
+ | * <code>mesh/bearer/api</code> | ||
+ | * <code>mesh/bearer/include</code> | ||
+ | * <code>mesh/prov/api</code> | ||
+ | * <code>mesh/prov/include</code> | ||
+ | * <code>mesh/access/api</code> | ||
+ | * <code>mesh/access/include</code> | ||
+ | * <code>mesh/dfu/api</code> | ||
+ | * <code>mesh/dfu/include</code> | ||
+ | * <code>mesh/stack/api</code> | ||
+ | * <code>models/foundation/config/include</code> | ||
+ | * <code>models/foundation/health/include</code> | ||
+ | * Path to include folder of any other mesh models that are used in your application | ||
+ | * <code>external/micro-ecc</code> | ||
+ | * <code>examples/common/include</code> | ||
+ | * Path to any other resources in the mesh examples that are used in your application | ||
+ | 将以下预处理器符号添加到nRF5 SDK示例的项目文件中: | ||
+ | * <code>NRF52_SERIES</code> | ||
+ | * <code>NRF_MESH_LOG_ENABLE=NRF_LOG_USES_RTT</code> (because logging in the mesh stack relies on RTT) | ||
+ | * <code>CONFIG_APP_IN_CORE</code> | ||
+ | |||
+ | ===== 可选变更 ===== | ||
+ | 此外,您可能需要应用以下一项或多项更改: | ||
+ | |||
+ | 如果与nRF5 SDK集成在一起,则可能需要更新在网格堆栈中使用simple_hal模块的示例以使用Nordic nRF5 SDK bsp模块。可以同时使用两者,但是在这种情况下,必须从其中之一删除GPIOTE_IRQHandler,并且只有一个模块可以注册回调函数。 | ||
+ | |||
+ | 如果原始的Nordic nRF5 SDK示例使用了SoftDevice,请确保在启用SoftDevice之后初始化并启用了网格堆栈。在这种情况下,必须将SoftDevice事件转发到网格堆栈。将以下代码添加到您的应用程序: | ||
+ | |||
+ | <nowiki>#</nowiki>include“ nrf_sdh_soc.h” | ||
+ | |||
+ | #定义MESH_SOC_OBSERVER_PRIO 0 | ||
+ | |||
+ | 静态void mesh_soc_evt_handler(uint32_t evt_id,void * p_context) | ||
+ | |||
+ | { | ||
+ | |||
+ | nrf_mesh_on_sd_evt(evt_id); | ||
+ | |||
+ | } | ||
+ | |||
+ | NRF_SDH_SOC_OBSERVER(m_mesh_soc_observer,MESH_SOC_OBSERVER_PRIO,mesh_soc_evt_handler,NULL); | ||
+ | |||
+ | 如果您有多个SOC观察者,请确保一次仅从其中一个观察者将SOC观察者事件转发到网格堆栈。 | ||
+ | |||
+ | 默认情况下,在网格堆栈以及某些Nordic nRF5 SDK应用程序中启用网络配置的闪存存储。用于此目的的闪光区域可能会重叠并导致错误。为了使闪存存储模块Flash管理器与网状堆栈中的闪存管理器以及Nordic nRF5 SDK中的闪存存储模块安全地共存,请在nrf_mesh_config_app.h中添加以下代码块: | ||
+ | |||
+ | <nowiki>#</nowiki>include“ fds.h” | ||
+ | |||
+ | <nowiki>#</nowiki>include“ fds_internal_defs.h” | ||
+ | |||
+ | <nowiki>#</nowiki>define FLASH_MANAGER_RECOVERY_PAGE_OFFSET_PAGES FDS_PHY_PAGES | ||
+ | |||
+ | 如果要添加自己的网格功能,而不是使用现有的网格示例,则还需要添加文件nrf_mesh_config_app.h。将其从网格堆栈存储库中的examples / templates文件夹复制到您的项目文件夹中,并删除文件顶部的#error消息。对文件内容进行其他适当的更改,例如将ACCESS_ELEMENT_COUNT和ACCESS_MODEL_COUNT调整为所需数量的元素和模型。 | ||
+ | |||
+ | ===== Flash放置项目文件 ===== | ||
+ | Segger Embedded Studio项目旁边都有一个flash_placement.xml文件,该文件充当链接器的输入。在flash_placement.xml文件中,nRF5 SDK配置了一组ProgramSection列表,用于放置某些变量。除了nRF5 SDK组件所需的所有ProgramSections外,网格还需要另外两个部分,即nrf_mesh_flash和nrf_mesh_ram。 | ||
+ | |||
+ | 必须将其他与网格相关的部分添加到flash_placement.xml文件中: | ||
+ | |||
+ | 将以下行添加到标记为<MemorySegment name =“ FLASH” ...>的内存段中: | ||
+ | |||
+ | <ProgramSection alignment =“ 4” keep =“是” load =“是” name =“。nrf_mesh_flash”输入节=“ *(SORT(.nrf_mesh_flash。*))”“ address_symbol =” __ start_nrf_mesh_flash“ end_symbol =” __ stop_nrf_mesh_flash“ /> | ||
+ | |||
+ | 将以下行添加到标记为<MemorySegment name =“ RAM” ...>的内存段中: | ||
+ | |||
+ | <ProgramSection alignment =“ 4” keep =“是” load =“否” name =“。nrf_mesh_ram” inputsections =“ *(SORT(.nrf_mesh_ram。*))”“ address_symbol =” __ start_nrf_mesh_ram“ end_symbol =” __ stop_nrf_mesh_ram“ /> | ||
+ | |||
+ | 注意 | ||
+ | |||
+ | 对于共存示例已经进行了此更改。在编辑任何现有nRF5 SDK示例的Flash放置文件时,可以在这些示例中使用flash_placement.xml文件作为参考。 | ||
+ | |||
+ | === 实验现象 === | ||
+ | |||
+ | === 源码详解 === | ||
+ | |||
+ | == Coexistence Uart example == | ||
+ | |||
+ | === 实验简介 === | ||
+ | |||
+ | === 硬件说明 === | ||
+ | |||
+ | === 软件说明 === | ||
+ | |||
+ | ==== SDK UART共存示例 ==== | ||
+ | 本示例演示了如何同时使用适用于Mesh的nRF5 SDK和nRF5 SDK示例。它围绕两个示例构建,分为两个部分: | ||
+ | |||
+ | 此示例的网格部分从nRF5 SDK for Mesh实现了灯开关客户端示例。 | ||
+ | |||
+ | 该示例的BLE部分实现了nRF5 SDK的ble_app_uart示例,但以下更改除外: | ||
+ | * BSP事件SLEEP,DISCONNECT和WHITELIST_OFF被忽略。这使得板子按钮仅控制应用程序的网格部分 | ||
+ | * 增加广告间隔以为网格堆栈留出更多时间 | ||
+ | * 可以通过发送要模拟的灯光开关客户端按钮编号,通过BLE UART来控制灯光开关服务器 | ||
+ | 运行此示例的结果是,您将能够使用网状网络,该示例中的网状网络可以代替电灯开关客户端示例。 | ||
+ | |||
+ | 在开始测试此共存示例之前,请参阅以下页面: | ||
+ | |||
+ | 将Mesh集成到nRF5 SDK示例中 | ||
+ | |||
+ | 灯光开关示例和灯光开关客户端详细信息以及Mesh API | ||
+ | |||
+ | ===== 测试示例 ===== | ||
+ | 将ble_app_uart_coexist文件夹复制到nRF5 SDK安装路径下的examples / ble_peripheral文件夹中。 | ||
+ | |||
+ | 在ble_app_uart_coexist / pca10040 / s132 / ses / ble_app_uart_pca10040_s132.emProject中打开Segger Embedded Studio项目。 | ||
+ | |||
+ | 将MESH_ROOT添加到您的Segger Embedded Studio全局宏列表: | ||
+ | |||
+ | 在SES菜单栏中,单击工具>选项...。 | ||
+ | |||
+ | 在左列中,单击建筑物。 | ||
+ | |||
+ | 在右列中,双击“全局宏”。 | ||
+ | |||
+ | 在新行中添加网格根目录:MESH_ROOT = <网格安装路径>。 | ||
+ | |||
+ | 如灯光开关示例中所述对灯光开关示例设备进行编程,但以下情况除外: | ||
+ | |||
+ | 用examples / ble_peripheral / ble_app_uart_coexist / pca10040 / s132 / ses / Output / Release / Exe / ble_app_uart_pca10040_s132.hex替换电灯开关客户端。 | ||
+ | |||
+ | 现在,您可以并行或顺序运行两个并存的示例: | ||
+ | |||
+ | 按照电灯开关示例中的说明运行电灯开关示例。 | ||
+ | |||
+ | 按照nRF5 SDK文档中的描述运行ble_app_uart示例。 | ||
+ | |||
+ | 编写与UART RX特性中的数字之一(1、2、3或4)等效的十六进制ASCII码,以模拟按钮按下。 | ||
+ | |||
+ | === 实验现象 === | ||
=== 源码详解 === | === 源码详解 === | ||
[[分类:NRF52832DK]] | [[分类:NRF52832DK]] | ||
[[分类:实验手册]] | [[分类:实验手册]] |
2019年10月17日 (四) 16:51的版本
蓝牙Mesh和BLE是并行发展的一个独立分支,虽然底层共用Physical Layer和Link Layer,但是上层协议并不相同。因此,nRF52832的Mesh例程,并不在BLE协议栈sdk中,而是安装一个扩展包。
本文介绍蓝牙Mesh相关的环境搭建和实验介绍。
1 Mesh开发环境
1.1 蓝牙Mesh SDK
SDK位置:归档资料/2-协议栈SDK/nRF5_SDK_Mesh_v310.zip
,注意文件名中的Mesh字样。
和BLE协议栈一样,将该压缩包直接解压到BLE协议栈同级目录即可使用,解压后的SDK路径如下:E:\project-nordic\nRF5_SDK_Mesh_v310
1.2 集成开发软件SES
SES时是Segger Embedded Studio编译器的缩写,用来编译蓝牙Mesh代码,SES功能与IAR或Keil类似。
备注:Nordic为何使用SES而不是IAR,原因不得而知。
1.2.1 SES安装
SES软件位置:归档资料/7-编译器SES/Setup_EmbeddedStudio_ARM_v410_win_x64.exe
。
我们双击打开安装界面,按照如下动图所示方式进行安装(可以全部默认安装)。
1.2.2 SES许可证激活
我们双击打开安装好的SES,选择编译自带测试例程,此时弹出需要激活的界面。
由于我们准备使用SES编译nordic的NRF52832的SDK,所以这里我们选择Activate Your Free License。这里因为nordic公司已经帮客户想SEGGER公司买下了使用的版权,所以是免费的许可证。
我们按照要求填写好信息,主要是邮箱地址(用于接收SEGGER公司发给我们的许可证),填写完成之后点击Request License。下面是我们接收的邮件信息,我们将红色框内的内容复制下来。
打开SES,选择Tools\License Manager...,我们选择Activate Embedded Studio,打开如下界面,并将我们的许可证粘贴进去,然后点击Install License。
安装好许可证之后,跳转到如下的界面。
此时我们的许可证激活完毕(有时候需要等待一段时间,才会显示激活成功)。
2 Light_switch
2.1 实验简介
此示例演示了包含充当两个角色的设备的网状生态系统:配置角色(Provisioner role)和节点角色(Node role、provisionee role)。 它还通过在应用程序中使用[Generic OnOff model]来演示了如何使用Mesh模型。
该示例由三个较小的示例组成:
Light switch server:一个实现了[Generic OnOff server model]的简约服务器,用于接收状态数据并控制板上LED 1的状态。
Light switch client:一个实现了[Generic OnOff client model]的简约客户端。当用户按下任意按钮时,OnOff Set消息将发送到配置的目标地址。
Mesh Provisioner:一个简单的静态配置设备应用,用于建立演示网络,该配置设备在一个网状网络中配置所有节点。 此外,配置设备还可以在这些节点上配置网格模型[Generic OnOff model]实例的绑定以及发布和订阅设置,以使它们能够相互通信。
[Generic OnOff Client/Server]模型用于操纵打开/关闭状态。请注意,当服务器设置了发布地址(如本例所示)时,服务器会将其状态更改的任何操作披露到其发布地址。
下图给出了将由静态供应商设置的网状网络的整体视图, 括号中的数字表示预配置程序分配给这些节点的地址。
灯开关服务器和灯开关客户端示例均具有预配方角色。它们支持通过广告承载(PB-ADV)和GATT承载(PB-GATT)进行配置,并且还支持网状代理服务器(Proxy Service),但是不支持代理客户端(Proxy Client)。
2.2 硬件说明
完成这个实验,我们最少需要两个开发板硬件用做我们的节点设备(Node):
●一个开发板用做client
●一个或者多个开发板用做server
此外,我们还需要以下之一作为我们的配置设备(Provisioner):
●如果您决定使用静态预配器示例,则多准备一个开发板
●如果您决定使用app程序进行设置,则需要安装手机app@link_nrf_mesh_app(@link_nrf_mesh_app_ios或@link_nrf_mesh_app_android)。
2.3 软件说明
1、我们使用NrfGo上位机,依次对三个开发板进行擦除及softdevice的烧写
2、使用SEGGER Embedded Studio for ARM编译器分别打开我们`<InstallFolder>/examples/light_switch`路径下的3个实验,并完成编译
●\client\light_switch_client_nrf52832_xxAA_s132_6_1_0.emProject
●\server\light_switch_server_nrf52832_xxAA_s132_6_1_0.emProject
●\provisioner\light_switch_provisioner_nrf52832_xxAA_s132_6_1_0.emProject
3、此时我们对3个开发板分别进行固件的烧写,分别烧写client、server、provisioner(建议大家给3个开发板贴上标签,方便后续区分)
2.4 实验现象
注意:保证我们的3个设备都是刚按照软件说明部分的步骤配置完成,并且没有进行过任何硬件控制(按键操作)。目的是保证所有设备均未被我们人为配置过,没有进行过网络配置,否则可能有任意异常(不同网络配置,导致的不同现象) |
1、首先我们分别给client和provisioner供电,然后我们按下provisioner的按键S1:
●provisoner:LED灯点亮,代表正在配置查找设备,配置组网
●client:首先LED3和LED4闪烁,代表正在组网;LED1-LED4四个灯一起闪烁,代表组网完成
我们如果打开RTT检测log打印,可以看到如下的信息,这个时候我们已经给client设备分配了Node Address为0x0100。provisioner信息(上),client信息(下)。
2、使用provisioner配置好client之后,我们给server开发板上电,这个时候provisioner将会配置server入网:
●provisoner:LED1点亮代表正在配置网络,LED2点亮代表网络配置完成
●server:首先LED3和LED4闪烁,代表正在组网;LED1-LED4四个灯一起闪烁,代表组网完成
我们打开RTT检测log打印,可以看到server已经配置入网,并且被分配了地址Node Address为0x0104。provisioner信息(上),server信息(下)。
3、此时整个网络的配置已经完成,这个时候我们可以按下client上的按键来控制server上的LED点亮或者熄灭。
由于我们的server被provisioner分配的Node Address是0x0104(偶数),所以我们通过client的S3控制server的LED1点亮,通过client的S4控制server的LED1熄灭。
client设备对于server设备的控制,通过Node Address的奇偶位不同,分成了两个组。
client的S1和S2分别控制Node Address为奇数的server设备的LED1点亮和熄灭。 client的S3和S4分别控制Node Address为偶数的server设备的LED1点亮和熄灭。 |
我们打开RTT检测log打印,可以看到client分别按下button2(S3)以及button3(S4),分别会设置server的GPIO输出高低电平。client信息(上),server信息(下)。
4、至此我们的mesh组网的lightswitch实验测试完成。
2.5 源码详解
3 Beaconing example
3.1 实验简介
3.2 硬件说明
3.3 软件说明
3.4 实验现象
3.5 源码详解
4 Coexistence example
4.1 实验简介
4.2 硬件说明
4.3 软件说明
4.3.1 将Mesh集成到nRF5 SDK示例中
用于网格的nRF5 SDK与Nordic的nRF5 SDK兼容。 这使您可以将nRF5 SDK中的资源包括在现有的Mesh项目中,也可以将nRF5 SDK中的Mesh功能包括在nRF5 SDK示例中。
请参阅构建网格堆栈和示例,以获取有关如何下载和安装nRF5 SDK的信息。 查看共存示例,以了解如何将nRF5 SDK功能与用于网格的nRF5 SDK同时使用。
4.3.1.1 动态记忆
在将nRF5 SDK功能与nRF5 Mesh SDK功能一起使用时(如并存示例所示),您可能会遇到以下情况:应用程序注意事项可能需要更改动态内存的分配方式和可分配的动态内存量。 网格堆栈使用网格内存管理器界面进行动态内存分配。 默认的后端mesh_mem_stdlib.c使用标准库malloc(),该库需要定义足够大的堆大小。 可以通过用另一个内存管理器替换后端来更改此行为。
如果使用Segger Embedded Studio构建应用程序,请在“项目选项”>“代码”>“运行时内存区域”设置中将“堆大小”设置为8192字节。
4.3.1.2 并发的SoftDevice和Mesh活动
同时运行SoftDevice和Mesh时,最大的性能问题通常来自无线电时间争用。虽然SoftDevice通常在预定的短脉冲中运行,但Mesh会尝试尽可能多地使用无线电。只要SoftDevice没有无线电活动,Mesh就会连续扫描和通告。 SoftDevice活动将减少Mesh广播的时间,并且为了保持一致的Mesh性能,必须在不影响用户体验的情况下尽可能保守地设置SoftDevice无线电参数。
在使用SoftDevice进行广告时,请尝试使用您的使用情况可以容许的最大广告间隔。如果可能,请在不需要时关闭SoftDevice广告商,仅在您希望收到连接请求时才激活它。如果您只需要发送不可连接的,不可扫描的广告(例如,针对第三方信标协议),请使用Mesh Advertiser API,因为它与Mesh一起使用时可以进行最少的上下文切换。
当SoftDevice在连接中运行时:
尝试协商应用程序可以允许的最大连接间隔。如果需要通过连接的高吞吐量,则在每个连接事件中发送更多的数据要比减少连接间隔更好,因为大部分开销来自上下文切换。
如果网状设备在其SoftDevice连接中充当外围设备(从设备),则还可以增加“从设备等待时间”,这应使SoftDevice跳过连接事件,而不会增加通过链接的任何传出数据传输的等待时间。
与广告一样,建议仅在需要时才保持连接活动。空闲的软设备连接对网状网性能的影响几乎与具有大量流量的连接一样多,特别是在从属延迟较低的情况下。
基于SoftDevice的扫描对所有SoftDevice活动的Mesh性能影响最大。当SoftDevice正在扫描时,Mesh无法接收数据包,因此每个SoftDevice扫描窗口都会替换Mesh扫描。仅在尝试建立连接或需要活动扫描时才应使用SoftDevice扫描。如果需要常规的被动BLE扫描(用于侦听信标或其他第三方活动),请通过使用nrf_mesh_rx_cb_set函数设置RX回调来挂接到Mesh扫描器。如果您的应用程序需要主动扫描或需要启动连接,则应尽可能保守地设置扫描参数。较长的扫描间隔和较短的扫描窗口将使Mesh拥有更多的时间进行自身的无线电活动。类似地,建立上下文时在短时间内执行连续扫描可能比执行长时间运行的占空比扫描有利,因为上下文切换会导致很多不必要的开销。最后,强烈建议为SoftDevice连接启动调用设置超时,以避免长时间的空闲扫描。
由于Mesh无法主动阻止SoftDevice无线电活动,因此减少同时运行SoftDevice活动的设备上的Mesh活动不会直接影响SoftDevice的性能。但是,附近的其他Mesh设备会干扰广告渠道中的SoftDevice活动,这可能会使连接启动花费更长的时间。
通常,Mesh必须在SoftDevice活动之间执行其所有无线电操作,因此,如果设备在执行SoftDevice无线电操作时正在发送大量Mesh数据包,则它将在此上花费大部分Mesh时间,而不是接收传入的数据。为了解决这个问题,请根据可用的无线电时间调整输出数据包的数量,以减少Mesh数据包的发送。如果可能,请通过在CORE_TX_ROLE_RELAY角色上调用mesh_opt_core_adv_set来暂停耗时的SoftDevice操作期间的Mesh数据包中继。
4.3.1.3 在用于网格示例的nRF5 SDK中包括nRF5 SDK
根据您的工具链:
使用Segger Embedded Studio时,请添加代码文件并包括相应SES项目文件的路径。
使用CMake构建用于网格堆栈的nRF5 SDK时,添加代码文件并包括指向相应CMakeLists.txt文件的路径。 SDK_ROOT根符号用于引用nRF5 SDK安装文件夹(例如,请参阅Light Switch服务器示例中的CMakeLists.txt)。
网格示例项目已经在其include /目录中包含sdk_config.h文件。 这些文件是默认SDK配置文件的副本,并且网格示例所需的所有更改都包含在示例目录中的include / app_config.h文件中。
注意,
必须先在SDK配置文件中显式启用某些SDK功能,然后才能使用它们。 有关详细信息,请参见SDK文档页面SDK配置头文件。
4.3.1.4 在nRF5 SDK示例中包括用于网格功能的nRF5 SDK
在nRF5 SDK示例的项目文件中包括来自nRF5 SDK for Mesh的以下源文件:
- All C files in
mesh/core/src
- All C files in
mesh/bearer/src
- All C files in
mesh/prov/src
except nrf_mesh_prov_bearer_gatt.c - All C files in
mesh/access/src
- All C files in
mesh/dfu/src
- All C files in
mesh/stack/src
models/foundation/config/src/config_server.c
models/foundation/config/src/composition_data.c
models/foundation/config/src/packed_index_list.c
models/foundation/health/src/health_server.c
- Any other mesh models that are used in your application
external/micro-ecc/uECC.c
examples/common/src/assertion_handler_weak.c
examples/common/src/mesh_provisionee.c
注意
如果不需要各种网格特征(例如DFU),则可以从项目文件中省略相应的文件。但是,在其位置添加examples / nrf_mesh_weak.c以提供缺少的API函数的存根。
将以下文件夹添加到nRF5 SDK示例的项目包含路径:
mesh/core/api
mesh/core/include
mesh/bearer/api
mesh/bearer/include
mesh/prov/api
mesh/prov/include
mesh/access/api
mesh/access/include
mesh/dfu/api
mesh/dfu/include
mesh/stack/api
models/foundation/config/include
models/foundation/health/include
- Path to include folder of any other mesh models that are used in your application
external/micro-ecc
examples/common/include
- Path to any other resources in the mesh examples that are used in your application
将以下预处理器符号添加到nRF5 SDK示例的项目文件中:
NRF52_SERIES
NRF_MESH_LOG_ENABLE=NRF_LOG_USES_RTT
(because logging in the mesh stack relies on RTT)CONFIG_APP_IN_CORE
4.3.1.5 可选变更
此外,您可能需要应用以下一项或多项更改:
如果与nRF5 SDK集成在一起,则可能需要更新在网格堆栈中使用simple_hal模块的示例以使用Nordic nRF5 SDK bsp模块。可以同时使用两者,但是在这种情况下,必须从其中之一删除GPIOTE_IRQHandler,并且只有一个模块可以注册回调函数。
如果原始的Nordic nRF5 SDK示例使用了SoftDevice,请确保在启用SoftDevice之后初始化并启用了网格堆栈。在这种情况下,必须将SoftDevice事件转发到网格堆栈。将以下代码添加到您的应用程序:
#include“ nrf_sdh_soc.h”
#定义MESH_SOC_OBSERVER_PRIO 0
静态void mesh_soc_evt_handler(uint32_t evt_id,void * p_context)
{
nrf_mesh_on_sd_evt(evt_id);
}
NRF_SDH_SOC_OBSERVER(m_mesh_soc_observer,MESH_SOC_OBSERVER_PRIO,mesh_soc_evt_handler,NULL);
如果您有多个SOC观察者,请确保一次仅从其中一个观察者将SOC观察者事件转发到网格堆栈。
默认情况下,在网格堆栈以及某些Nordic nRF5 SDK应用程序中启用网络配置的闪存存储。用于此目的的闪光区域可能会重叠并导致错误。为了使闪存存储模块Flash管理器与网状堆栈中的闪存管理器以及Nordic nRF5 SDK中的闪存存储模块安全地共存,请在nrf_mesh_config_app.h中添加以下代码块:
#include“ fds.h”
#include“ fds_internal_defs.h”
#define FLASH_MANAGER_RECOVERY_PAGE_OFFSET_PAGES FDS_PHY_PAGES
如果要添加自己的网格功能,而不是使用现有的网格示例,则还需要添加文件nrf_mesh_config_app.h。将其从网格堆栈存储库中的examples / templates文件夹复制到您的项目文件夹中,并删除文件顶部的#error消息。对文件内容进行其他适当的更改,例如将ACCESS_ELEMENT_COUNT和ACCESS_MODEL_COUNT调整为所需数量的元素和模型。
4.3.1.6 Flash放置项目文件
Segger Embedded Studio项目旁边都有一个flash_placement.xml文件,该文件充当链接器的输入。在flash_placement.xml文件中,nRF5 SDK配置了一组ProgramSection列表,用于放置某些变量。除了nRF5 SDK组件所需的所有ProgramSections外,网格还需要另外两个部分,即nrf_mesh_flash和nrf_mesh_ram。
必须将其他与网格相关的部分添加到flash_placement.xml文件中:
将以下行添加到标记为<MemorySegment name =“ FLASH” ...>的内存段中:
<ProgramSection alignment =“ 4” keep =“是” load =“是” name =“。nrf_mesh_flash”输入节=“ *(SORT(.nrf_mesh_flash。*))”“ address_symbol =” __ start_nrf_mesh_flash“ end_symbol =” __ stop_nrf_mesh_flash“ />
将以下行添加到标记为<MemorySegment name =“ RAM” ...>的内存段中:
<ProgramSection alignment =“ 4” keep =“是” load =“否” name =“。nrf_mesh_ram” inputsections =“ *(SORT(.nrf_mesh_ram。*))”“ address_symbol =” __ start_nrf_mesh_ram“ end_symbol =” __ stop_nrf_mesh_ram“ />
注意
对于共存示例已经进行了此更改。在编辑任何现有nRF5 SDK示例的Flash放置文件时,可以在这些示例中使用flash_placement.xml文件作为参考。
4.4 实验现象
4.5 源码详解
5 Coexistence Uart example
5.1 实验简介
5.2 硬件说明
5.3 软件说明
5.3.1 SDK UART共存示例
本示例演示了如何同时使用适用于Mesh的nRF5 SDK和nRF5 SDK示例。它围绕两个示例构建,分为两个部分:
此示例的网格部分从nRF5 SDK for Mesh实现了灯开关客户端示例。
该示例的BLE部分实现了nRF5 SDK的ble_app_uart示例,但以下更改除外:
- BSP事件SLEEP,DISCONNECT和WHITELIST_OFF被忽略。这使得板子按钮仅控制应用程序的网格部分
- 增加广告间隔以为网格堆栈留出更多时间
- 可以通过发送要模拟的灯光开关客户端按钮编号,通过BLE UART来控制灯光开关服务器
运行此示例的结果是,您将能够使用网状网络,该示例中的网状网络可以代替电灯开关客户端示例。
在开始测试此共存示例之前,请参阅以下页面:
将Mesh集成到nRF5 SDK示例中
灯光开关示例和灯光开关客户端详细信息以及Mesh API
5.3.1.1 测试示例
将ble_app_uart_coexist文件夹复制到nRF5 SDK安装路径下的examples / ble_peripheral文件夹中。
在ble_app_uart_coexist / pca10040 / s132 / ses / ble_app_uart_pca10040_s132.emProject中打开Segger Embedded Studio项目。
将MESH_ROOT添加到您的Segger Embedded Studio全局宏列表:
在SES菜单栏中,单击工具>选项...。
在左列中,单击建筑物。
在右列中,双击“全局宏”。
在新行中添加网格根目录:MESH_ROOT = <网格安装路径>。
如灯光开关示例中所述对灯光开关示例设备进行编程,但以下情况除外:
用examples / ble_peripheral / ble_app_uart_coexist / pca10040 / s132 / ses / Output / Release / Exe / ble_app_uart_pca10040_s132.hex替换电灯开关客户端。
现在,您可以并行或顺序运行两个并存的示例:
按照电灯开关示例中的说明运行电灯开关示例。
按照nRF5 SDK文档中的描述运行ble_app_uart示例。
编写与UART RX特性中的数字之一(1、2、3或4)等效的十六进制ASCII码,以模拟按钮按下。