21天入门低功耗蓝牙5.x开发
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.3 nRF5 SDK介绍和目录结构解读

nRF5 SDK(Software Development Kit,软件开发工具包)是Nordic nRF51/52系列芯片的软件开发环境,当前nRF5 SDK的最新版本为17.1.0。

nRF5 SDK需要使用Softdevice协议栈,Softdevice协议栈与SDK版本是相对应的。为了方便开发者使用,每一个版本的nRF5 SDK都包含了该版本支持的所有Softdevice协议栈,可在nRF5 SDK的“\components\softdevice”目录中查看具体支持的Softdevice协议栈类别和版本。

注意:nRF5 SDK9/10只支持nRF51系列芯片,nRF5 SDK11/12同时支持nRF51和nRF52系列芯片,而nRF5 SDK13/14/15/16/17只支持nRF52系列芯片。

对于新项目的开发,推荐使用最新版本的nRF5 SDK,因为功能更强大,提供更多的新特性和新功能,可靠性与兼容性也更好。对于较早的nRF51系列芯片,推荐使用nRF5 SDK12.3.0(12.3.0已经是nRF51系列芯片能支持的最高版本nRF5 SDK了),而对于nRF52系列芯片,推荐使用nRF5 SDK17.1.0(当前的最新版本)。通常最新版的nRF5 SDK会占用较多的Flash和RAM资源,而且新版本的nRF5 SDK为了兼容各种情况通常也会设计得较为复杂。在特定情况下,为了节省资源考虑,开发者原则上也可以使用某些老版本的nRF5 SDK。

对于开发者来说,关于是否需要升级nRF5 SDK,通常的建议是:对于已开发的项目,只要应用测试没有任何问题,所用nRF5 SDK就是稳定和可靠的,不需要升级nRF5 SDK。如果要使用新版本nRF5 SDK的新功能和新特性或者原有nRF5 SDK的问题需要修复,那么就需要升级nRF5 SDK。查看nRF5 SDK的“\documentation\release_notes.txt”文件可以了解最新版本nRF5 SDK的新功能和新特性。

注意:nRF5 SDK自有API的说明一般都放在头文件中,而不是c文件中,头文件中有相关API的详细说明和使用注意事项。

除了nRF5 SDK,Nordic还针对某些特殊应用领域推出了一些专门的SDK,用于开发特定的应用及产品。这些SDK和nRF5 SDK采用了相同的软件架构、相同的驱动和库,以及相同的编码风格。对开发者来说,只要熟悉了nRF5 SDK,就可以快速上手。例如,nRF5 SDK for Mesh用于开发蓝牙Mesh应用,nRF5 SDK for Thread and ZigBee用于开发Thread和ZigBee多无线协议应用,nRF5 SDK for Homekit用于开发苹果的外设产品(开发苹果外设产品的专门SDK需要获得苹果的授权才可下载及使用)。

从形式上来说,nRF5 SDK其实就是一个软件压缩包,下载并解压缩后可以直接使用,这里介绍一下nRF5 SDK解压缩后的主目录结构,有助于开发者加深对nRF5 SDK的理解。主目录结构如图1-32所示,其说明如表1-1所示。

图1-32

表1-1

主目录中的components目录结构如图1-33所示,该目录包含了Nordic提供的nRF5 SDK配套应用的源代码,其中的softdevice目录中保存的是Nordic开发的低功耗蓝牙协议栈。在开发过程中,如非必要,不要修改components目录下的文件,因为该目录下的文件夹会被nRF5 SDK中的很多例程所引用,如修改则可能会影响到整个nRF5 SDK的运行。components目录的说明如表1-2所示。

图1-33

表1-2

主目录中的examples目录结构如图1-34所示。该目录包含了丰富的典型应用示例,不仅包含BLE应用示例,也包含每个外设的使用示例,还包含Bootloader示例代码(在“\examples\DFU”目录下),以及一些开发完成但尚未经过大规模验证的新例程(在“\examples\ble_peripheral\experimental”目录下)。一般来说,开发过程中遇到的大部分需求,都可以在examples目录找到相应的示例。examples目录的说明如表1-3所示。

图1-34

表1-3

在examples目录下,开发者最常用的两个目录是ble_peripheral和peripheral。ble_peripheral目录包含了BLE作为从机的应用示例,基本上覆盖了市场上现有的大部分成熟BLE应用,可以直接使用,在开发低功耗蓝牙产品时,可以在ble_peripheral目录中选择与待开发产品最接近的例程,并在此例程的基础上进行修改即可使用。而ble_peripheral目录包含了所有外设应用示例。examples目录下的ble_peripheral目录结构如图1-35所示,ble_peripheral目录的说明如表1-4所示。

图1-35

表1-4

开发者如何从nRF5 SDK开始自己的开发呢?首先在SDK例程中选择最接近自己应用需求的例程,然后在此基础上添加代码。这是效率最高,也是最不容易出问题的方法。

如何选择相近的例程呢?可以在nRF5 SDK的离线文档或在线文档中找到该例子对应的帮助文档,可查看例程说明,如用了什么Profile或服务,采用什么配对方式等。如果该例程与自己的应用接近,那么就可以以该例程为基础来进行低功耗蓝牙的项目开发。

当开发者熟悉nRF5 SDK结构后,可以看到在nRF5 SDK下开发Nordic的低功耗蓝牙应用,主要的工作有以下三项:

(1)初始化软件模块。在初始化nRF5 SDK模块时,只需要将相应API的结构体参数清0即可完成初始化工作。简单地说,只要保证参数为0,低功耗蓝牙协议栈就可以工作起来,这对很多不熟悉nRF SDK结构的初学者来说,可大大减轻开发工作量。

(2)编写低功耗蓝牙事件回调处理函数。一般来说,开发的应用逻辑都放在低功耗蓝牙事件回调处理函数中,所以写好回调处理函数代码,低功耗蓝牙的开发工作就已完成了大半。

(3)编写应用功能函数,如传感器接口模块(如果有)、人机交互模块等。

这里需要特别注意,在编写各个模块时要考虑代码组织上的松耦合,要尽量减少依赖,相互之间做到独立,这样在修改模块时会简单方便,不会导致牵一发而动全身。模块间的耦合程度对系统的可维护性、可靠性有重要的影响。

什么是耦合呢?模块间的依赖性就是耦合,即两个功能函数之间的相互依赖程度。在开发多个模块时,模块间应该尽量松耦合,相互联系越小越好,当一个模块发生变动时,就无须变动其他模块。

实现松耦合的方法使用底层函数,使底层函数的功能尽量单一,为了尽量避免动辄修改底层函数,功能相近的底层函数,可以设计两个以上,不要为了减少代码量,把一个底层函数的功能设计得太多。

松耦合可以提高源代码的后期维护效率,使源代码拥有更好的性能,如何编写可维护的源代码,实际上就是如何编写松耦合的模块的过程。

如何界定松耦合与紧耦合呢?可以从这样的角度来判断两个模块的耦合程度:当修改一个模块的逻辑时,如果另外一个模块的逻辑也需要修改,这就说明这两个模块的耦合性太紧。当能够做到修改一个模块,而不需要更改其他的模块时,就做到了松耦合。

在基于nRF5 SDK例程的开发中,为了达到松耦合,每个模块,如广播模块,可以单独注册自己的BLE事件回调处理函数,然后在事件回调处理函数中只处理跟本模块有关的事件,与本模块无关的事件不进行处理而直接返回。

这里需要注意:

(1)虽然每个低功耗蓝牙事件回调处理函数只处理跟本模块有关的事件,但它可以捕获所有低功耗蓝牙事件。开发者虽然可以让整个应用程序只有一个低功耗蓝牙事件回调处理函数,但这样会让各个模块紧密地耦合在一起,形成紧耦合,对于代码的维护与移植极为不利。实际上,nRF5 SDK采用了松耦合的概念,尤其是nRF5 SDK14以后,各个模块都注册了事件回调处理函数,完全跟用户代码区隔开来。如果用户代码需要捕获低功耗蓝牙事件,只需注册自己的事件回调处理函数即可。

(2)由于低功耗蓝牙事件是异步的,所以低功耗蓝牙的事件回调处理函数可能会同时收到多个低功耗蓝牙事件,即低功耗蓝牙的事件回调处理函数有可能在很短的时间内被多次调用(低功耗蓝牙的事件回调处理函数每次只处理一个事件,然后返回,所以短时间内会被调用多次),这个情况需要开发者留意。