nRF52实践:SDK的了解

·  阅读 146

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情

nRF52实践:SDK的了解。

本文结合开发的一点经验,记录一下SDK的了解情况,所用版本为 SDK 17.1。

softdevice

SDK 17 压缩包带有 softdevice,版本为 7.2。位置:components\softdevice\s132\doc

发布说明文件为:s132_nrf52_7.2.0_release-notes.pdf。

flash占用152KB,ram占用5.6KB,调用栈占用1.75KB。ID号为0x0101。

image-20220414103836863.png

注:烧写 softdevice 后会获取到 ID号。带协议栈的Keil工程中,需要设置flash地址为0x260000。

SDK

开发环境使用 keil 5。

SDK有2套。

SDK,不再加新功能,但会修复bug,最新是2021年8月发布的17版本。52系列可用之。

新的为NCS(nRF Connect SDK),官方的nRF Connect,新的SDK,会加新功能。

nRF52832 两套 SDK 都可用。

下载

芯片:Nordic 官方出品 nRF5XXX 芯片。具体为 nRF52832。

nRF5 SDK 下载:官网 S132 下载

SDK:版本越新越高,有新特性,但可能资源占用大,按需下载,按需升级。

Softdevice:Nordic蓝牙协议栈的名称,有不同版本。命名为 Sxyz。

  • x 协议栈的类型,1为BLE协议栈,2为ANT协议栈,3为同时支持两者
  • y BLE角色,1为从设备,2为主设备,3为同时支持两者
  • z 芯片类型,0 为nRF51系列,2 为nRF52系列

ANT另外下载,需授权,有试用版,但不能商用。符合预研要求的:S132(支持BLE协议主从的nRF52系列)。

默认情况,选择 SDK 后,会自动勾选 SoftDevices,一般是全部下载,可按需下载,此处用S132。下载后文件名:

s132nrf52720.zip  # nrf52的7.2.0版本
nRF5_SDK_17.1.0_ddde560.zip # sdk 17.1.0 版本
复制代码

下载截图(打勾表示要下载的):

image-20220309103040336.png

注:关于softdevice的说明,SDK中也包含有了softdevice,会有多个,是否有必要再额外下载?额外下载的只有头文件。在SDK中有hex文件,目录nRF5_SDK_17.1.0_ddde560\components\softdevice\s132\hex

经研究,如果softdevice有新的版本,则下载之,压缩包有发布说明,里面有占用大小的说明。

SDK目录介绍

例程目录有不同类别的例子。目录示例:SDK版本/ examples /协议角色/例子名称/开发板型号/协议栈型号/工具链类型/具体工程

源码文件为main.c,目录下有pca10040 pca10040e pca10056 pca10056e pca10100e不同的子目录,其下还有如s132 s112的子目录,其下再有不同编译环境的子目录,似乎是配置文件。经分析,pca10040的s132是nRF52832使用的目录。

SDK 文档

官方有完备的在线文档,地址:infocenter.nordicsemi.com/index.jsp

左侧Software Development Kit,当前最新的版本为nRF5 SDK v17.1.0,可在Previous versions of nRF5 SDK查询历史版本。

Examples中有不同类别的示例。如基本外设,和蓝牙有关的外设示例,等,按需查询。

52832芯片手册在线版:nRF52832 Product Specification 注:在线版查询会比较慢,可下载离线版备用。

离线版本在左侧可下载。

SDK不同版本变化大,看资料需看时间。

SDK 框架

内存分布

image-20220416230519367.png (来自谷雨实验文档)

memory.png

无DFU情况,Flash 包括:

  • MB

    0x00000000 - 0x00001000 为主引导程序(MBR)。

  • SoftDevice

    0x00001000 - 0x00026000 为协议栈程序。

  • APP

RAM 分配:

  • 协议栈 包括 MBR+SoftDevice。占用大小在 SoftDevice 发布文档中给出。实际中可能要添加,过小时,启动会有日志打印。

有DFU情况,Flash 包括:

  • MB

    同前

  • SoftDevice

    同前

  • APP

  • bootloader

    DFU 蓝牙空中升级boot,地址根据DFU程序大小自行设置。

  • bootloader parameter

    0x0007E000 - 0x00080000 DFU 蓝牙空中升级boot参数区,用于记录升级信息(升级过程断电的话,下次可以接着升级,相当与有断点续传功能),APP版本,BOOT版本,APP校验,参数区校验等信息。如果没有此分区,程序将无法正常运行。

启动流程

nRF52832上电后从固定位置0x0000 0000开始执行程序,flash 0x0000 0000–0x0002 6000存放Nordic的协议栈s132,协议栈s132前面4KB(0x0000-0x1000)为主引导程序(MBR),MBR根据地址0xFF8或者0x1000 1014中是否存在DFU程序起始地址决定跳转地址,如果地址0xFF8或者0x1000 1014中存在DFU程序起始地址则会跳转至DFU,DFU运行结束后程序会跳转0x0000 1000,然后协议栈根据协议栈大小跳转至协议栈结束地址也就是APP起始地址0x26000,至此开始执行APP程序。

SDK的一些规范(约定)

nRF 的源码自有一套规范,根据示例格式编写即可,初学者不需要造轮子,也不要另立门户。总结几点:

  • SDK大版本不同,接口也不同,看资料需看所写日期或所用SDK版本。
  • sdk_config.h 里面有非常多的宏定义,不同工程设置不同。一般不能通用。
  • 模块使用宏定义编译,要使用需在sdk_config中开启宏定义。
  • 工程依赖文件多,新工程最好在已有的相近的工程基础上建立,SDK有模板工程。
  • SDK有旧外设接口、新外设接口,带BLE协议栈外设接口。
  • 带BLE协议栈和程序需烧录有softdevice,不带的不能烧有softdevice,两者不兼容的。(注:仅笔者实践若干次的结论,未深究)

开发类概述

  • 实例

    GATT分服务端、客户端,使用BLE_BAS_DEF这类的宏进行实例化。其它如定时器、队列等亦然。

  • SDK使用观察者模式设计,大量使用回调事件/函数。SDK自身源码有一套事件定义,而反应到用户级也有对应的事件。示例:

    • 空闲广播事件,SDK使用的是BLE_ADV_MODE_IDLE,用户注册的回调函数使用的是BLE_ADV_EVT_IDLE
    • NUS服务端接收数据事件,SDK根据BLE_GATTS_EVT_WRITE事件的回调函数条件,赋值BLE_NUS_EVT_RX_DATA,即为用户级可使用的事件。

sdk_config头文件说明

配置头文件为 sdk_config.h。主从机配置不同。一些模块或组件,根据sdk_config.h的宏来编译。比如NUS服务,从机设置:

#define BLE_NUS_ENABLED 1
复制代码

主机设置:

#define BLE_NUS_C_ENABLED 1
复制代码

对应的实现文件起始位置已经做了宏编译,如不添加,则无法编译相关的组件。

新旧API接口

一般地,nrf_xx是旧的API接口,nrfx_xx是新的接口。

integration\nrfx\legacy中使用宏定义来兼容旧API接口,如nrf_drv_timer.h文件:

/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_timer_init                       nrfx_timer_init
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_timer_uninit                     nrfx_timer_uninit
复制代码

目前在 SDK 17 版本中,很多示例代码还是混用新旧接口。

带BLE协议栈与否

以获取内部测试为例(仅为示意代码)。

不带 BLE 协议:

nrf_temp_init();
temp = (nrf_temp_read() / 4);
复制代码

带 BLE 协议:

sd_temp_get(&raw_temperature);
复制代码

注:带 BLE 协议需sd_xx函数。不过,有的外设没有该类接口,可使用nrfx_xx接口。原因是有的外设在协议栈情况下无法被访问(至于是哪些,暂未深究)。

模块实现

服务模块实现源码文件使用宏定义进行编译。需在 sdk_config 头文件中开启。

电池服务BAS sdk_config定义:
#define BLE_BAS_ENABLED 1
​
源码实现:
#if NRF_MODULE_ENABLED(BLE_BAS)
// 实现代码
#endif // NRF_MODULE_ENABLED(BLE_BAS)
​
客户端类似,宏为 BLE_BAS_C_ENABLED
复制代码

实例演示

以 keil 工程为例。

SDK 示例工程将源码按组分好,这是逻辑的分组。按需添加,比如外设在 nRF_Drivers,封装的外设接口在 nRF_Libraries 中,BLE 服务在 nRF_BLE_Services 中。

添加头文件:

..\..\..\..\..\..\components\libraries\uart
..\..\..\..\..\..\components\libraries\bsp
..\..\..\..\..\..\components\libraries\\timer
复制代码

添加源码文件:

components\libraries\timer
components\libraries\bsp
components\libraries\uart
modules\nrfx\drivers\src
复制代码

宏定义:

新驱动:
​
// <e> NRFX_TIMER_ENABLED - nrfx_timer - TIMER periperal driver
//==========================================================
#ifndef NRFX_TIMER_ENABLED
#define NRFX_TIMER_ENABLED 1
#endif
// <q> NRFX_TIMER0_ENABLED  - Enable TIMER0 instance
​
​
#ifndef NRFX_TIMER0_ENABLED
#define NRFX_TIMER0_ENABLED 0
#endif
​
旧驱动:
​
// <e> TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver - legacy layer
//==========================================================
#ifndef TIMER_ENABLED
#define TIMER_ENABLED 1
#endif#ifndef TIMER0_ENABLED
#define TIMER0_ENABLED 1
#endif
复制代码

类似的新旧驱动宏定义:

新:#define NRFX_SAADC_ENABLED 1
旧:#define SAADC_ENABLED 1
复制代码

参考

和开发相关的地址:

官方:

官方论坛:

分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改