Nordic nRF5x SoC在开发BLE应用时,需要使用蓝牙协议栈。SoC的软件框架如下图所示,其中蓝牙协议栈以二进制文件(hex文件)形式提供给用户。协议栈软件架构本身是不带OS的,应用层的开发用户可以选择是否使用OS,SDK提供的绝大部分例程都是不带OS的(仅带几个FreeRTOS的例程)。软件部分本文以SDK15.3为基础做简要介绍。

应用层与协议栈的互动依靠SVC中断和SW中断实现。

应用层通过调用API访问协议栈,协议栈在SVC中断里获得应用层的访问数据并进行处理;当协议栈需要发送事件或者数据的时候,会通过SW中断传送给应用层,用户会在应用层收到对应的事件与数据。协议栈API有两种,一种操作BLE,一种操作SoC外设如PPI、Flash等等。它们命名方式为 sd_xxx_xxxx(),函数名都以sd打头,例如下图中例举的分别是获取本设备MAC地址的API和操作PPI的API。注意调用API时注意检查返回值,返回值的含义在API的什么处都有介绍,获得非正常的返回值后需要根据应用场景处理,具体处理方式根据用户应用而异。

由于有些外设协议栈会使用,所以用户在操作这些外设的时候,需要先向协议栈申请。例如S132 v6.1 协议栈中对外设的开放权限如下图列举,删除了部分Open的外设,图完整表格及注释说明请翻看协议栈说明文档。红框中圈出了被协议栈使用的硬件,这些硬件应用层禁止访问(必须访问的情况下可以使用timeslot方式申请);Restricted标注的外设不能直接操作寄存器,需要用SDK中的API申请访问;Open标注的外设,用户可以自由访问寄存器,但也推荐使用SDK中的驱动。

除了占用一部分外设,协议栈还会占用Flash和RAM资源,各个版本的协议功能不尽相同,所以它们栈消耗的Flash和RAM大小也不同。下图是整理的协议栈功能与消耗资源的参考表格。需要说明的是,各个版本协议栈对nRF52芯片的适配性数据参考于Nordic infocenter。

从上图可以知道,S112,S113是专门给BLE从机使用的协议栈,消耗资源比较少,因此非常适合用于nRF52810和nRF52811等资源较少的SoC上。广播拓展、2Mbps(高速率)、长距离 这3项都是BLE5.0的新增功能;而MTU拓展和DLE是BLE4.2的功能,它们可以有效提高BLE的传输速度。

下图是以nRF52832-QFAA 和S132 v6.1.1为例的Flash资源分配情况。

 

下图是以nRF52832-QFAA 和S132 v6.1.1为例的RAM资源分配情况。其中APP_RAM_BASE是应用层的RAM起始地址,一般在编译器中设置,它的具体大小根据协议栈功能设定而变化。协议栈使用的call stack空间并未计算到协议栈的RAM范围中,协议栈消耗的call stack一般需要1536字节(FPU disable),通常SDK中S132工程默认call stack为8KB,无特殊情况可以保持默认。另外协议栈不会用到heap。

APP_RAM_BASE的大小取决于ATT tables ize,BLE角色,安全等级,私有UUID个数等等参数。APP_RAM_BASE的值计算起来比较复杂,通常根据应用需求在sdk_config.h中配置,再编译下载应用程序,通过log或者仿真的方式查看协议栈初始化时反馈的RAM需求。下图是sdk_config.h的界面截图,协议栈的配置在nRF_SoftDevice栏目下。红色框中的是协议栈基本功能的配置,他们会影响APP_RAM_BASE的值。

黄色框中是协议栈低频时钟源的配置(根据上面的内容可以知道协议栈占用了外设RTC0),SDK中例程默认使用外部低频晶体,用户可以根据需要将其切换为内部低频RC,nRF52832内部低频RC的精度为+-250ppm(不同型号有差异,具体参考数据手册),并增加1uA左右功耗。若使用内部低频RC,可以参考上图方式切换。

APP_RAM_BASE值的获取:在运行完nrf_sdh_ble_enable()之后,变量ram_start的值就是。同时,nrf_sdh_ble_enable中会将APP_RAM_BASE的建议值通过log(waring等级)打印出来。

获得APP_RAM_BASE的值后,在编译器中填入即可。KEIL用户参考下图将APP_RAM_BASE的值填入IRAM1 的Start项,将(RAM SIZE-APP_RAM_BASE)的值填入Size项。Embedded studio用户参考NORDIC BLE SOC开发环境 – 编译器中的操作修改。

修改完成之后,重新编译下载,协议栈配置部分就完成了,协议栈初始化就能正常运行了。

 

发表评论