nRF5 SDK软件架构及softdevice工作原理
本文将介绍Nordic nRF5 SDK软件架构以及softdevice工作原理,以加深大家对Nordic产品开发的理解,这样开发过程中碰到问题时,大家也知道如何去调试。
如果你刚开始接触nRF5 SDK,建议先看一下这篇文章“Nordic nRF5 SDK和softdevice介绍”,以建立Nordic nRF5 SDK的一些基本知识。
首先说明一下,Nordic nRF5系列产品都是使用Flash存储器的,确切说,是嵌入式可执行代码的Flash存储器,也就是说,代码是可以直接在上面运行的,这个跟很多其他BLE厂商是不一样的(他们使用的是nand Flash,代码是不能直接在nand Flash中运行的,必须先装载到RAM中才能跑,所以你会发现这些厂商的RAM都非常大)。Nordic Flash是带cache机制的,以保证大部分代码执行速度可以达到64MHz,在cache失败的时候,等待周期也只有1个cycle,可以说Flash的执行速度和效率都是非常不错的。另外,Nordic芯片是纯Flash产品,里面没有其他NVM,所有非易失性数据都放在Flash中,包括蓝牙协议栈,这也是为什么Nordic蓝牙协议栈也可以OTA的根本原因所在。
Nordic nRF5 SDK将芯片的存储器划分成如下格局:

Flash结构图 RAM结构图
从上图可知,Flash存储器最下面放的是softdevice(softdevice就是蓝牙协议栈,图中的MBR也属于softdevice的一部分),中间是application,最上面是bootloader(可选,只有需要OTA的时候,才需要下载bootloader)。这里需要特别指出的是,softdevice是以二进制形式提供给大家的,它占据了Flash的一块固定空间,起始地址为0,结束地址为APP_CODE_BASE。softdevice同时占用了RAM的一块固定空间,起始地址为0x20000000,结束地址为APP_RAM_BASE。Softdevice占用的Flash空间是固定不变的,运行时不可调节,也就是说APP_CODE_BASE是一个固定值,而softdevice占用的RAM空间是动态可调的,跟softdevice配置和蓝牙服务的多少有直接关联,所以APP_RAM_BASE一定要根据应用的实际情况进行调整。
这里说明一下, Softdevice不是以库的形式提供给大家,而是以二进制文件(hex文件)的形式提供给大家,这种方式可以带来很多好处。首先二进制形式可以保证蓝牙BQB认证的版本和发布给客户的版本一模一样(因为库形式的版本每次编译都会产生少许差异!)。其次softdevice不需要跟你的应用一起编译或者链接,大大节省调试时间,更主要的是,Softdevice运行在固定的Flash空间中,使用固定的RAM空间,从而与你的应用完全隔离开,实现了真正的模块分离,从而出现问题时,可以迅速定位是协议栈的问题还是应用的问题。再次二进制形式的 Softdevice开启了保护机制,应用代码是不能对其进行访问的,以保证Softdevice的安全性,防止应用代码误访问或者误擦除某些softdevice区域。最后这种多bin形式使得OTA变得非常灵活,你可以只OTA应用,也可以OTA协议栈和bootloader,或者三者同时OTA。
上面是站在芯片存储器角度来看nRF5 SDK的结构划分。如果站在软件架构角度,nRF5 SDK可以划分成如下结构图:

由上图可知,最下面是芯片本身,然后是ARM公司的CMSIS库,再往上就是协议栈softdevice和设备驱动,最后就是application和标准的蓝牙service了。softdevice是以二进制文件形式提供给大家的,除此之外,其他所有的SDK代码都是开源的,以方便大家开发。应用程序,包括SDK代码,都是通过softdevice API来与softdevice进行交互的,所有softdevice API都是以sd_打头的,比如:
- sd_softdevice_enable(…);
- sd_ble_gap_adv_start(…);
- sd_flash_write(…);
- sd_ppi_channel_assign(…);
Softdevice API有两种类型:
1) 与BLE协议有关的API,比如sd_ble_gap_connect(),sd_ble_gatts_hvx()等。
2) 外设操作API,比如sd_flash_write(),sd_power_gpregret_set()等。由于softdevice会使用到某些外设,应用程序也需要访问这些外设时,不能通过普通的外设驱动API去访问,必须通过softdevice API去访问。
如前所述,softdevice是以二进制文件形式提供给大家的,那么应用是如何做到可以成功调用softdevice API的?其实,softdevice是通过SVC中断和软中断来实现与应用程序交互的。每一个softdevice API对应一个SVC异常号(softdevice API是非阻塞的),也就是说,每当应用程序调用softdevice API,其实是产生一个SVC异常,然后进入到softdevice协议栈,由softdevice的SVC handler进行相应处理。示例代码如下所示:

Softdevice API调用流程如下所示:

每当softdevice完成相关重要操作,都会以事件形式通知应用程序的,比如与手机连接成功,softdevice就会把BLE_GAP_EVT_CONNECTED事件告知应用程序,那softdevice是如何把相关事件告知给应用程序的?这个是通过软中断来实现的。每当softdevice完成相关操作,就会把对应的事件放入一个队列中,然后触发一个软中断,以重新回到应用程序环境中,应用程序在相关软中断handler中查询该队列,一旦发现有事件在里面,就回调相关函数,比如ble_evt_handler,从而达到通知应用程序相关事件的目的。事件通知流程如下所示:

为了达到各个软件模块松耦合的目的,每个软件模块,比如广播模块,可以单独注册自己的BLE事件回调处理函数,然后在自己的事件回调处理函数里面只处理跟本模块有关的事件,与本模块无关的事件不进行处理而直接返回。这里需要注意两点:一虽然每个BLE事件回调处理函数只处理跟本模块有关的事件,但是它是可以捕获所有BLE事件的,你可以让整个应用程序只有一个BLE事件回调处理函数,但这样会让各个模块紧密地耦合在一起,因此Nordic SDK没有这么做,尤其是SDK14以后,各个模块都自己注册自己的蓝牙事件回调处理函数,完全跟用户代码切割开,同样如果用户代码需要捕获BLE事件的话,只需注册自己的BLE事件回调处理函数即可。二BLE事件是异步的,所以有时BLE事件回调处理函数会同时收到多个BLE事件,也就是BLE事件回调处理函数有可能在很短的时间内被调用多次(BLE事件回调处理函数每次只处理一个事件case,然后返回,所以短时间内会被调用多次),这个在开发的时候需要注意一下。
从上面nRF5 SDK软件架构的讲解过程中,我们可以看到,当我们开发Nordic平台的BLE应用时,主要需要做两件事:
- 第1件事:初始化。为了简化初始化工作,Nordic SDK所有模块初始化时,只需要将相应API输入结构体参数清0即可完成初始化工作,也就是说,只要你保证初始化参数为0,蓝牙协议栈就可以工作起来,这对很多Nordic初学者来说,大大减轻了开发工作量。
- 第2件事:写蓝牙事件回调处理函数。一般来说,你的应用逻辑都是放在蓝牙事件回调处理函数中,所以写好回调处理函数代码,你的开发工作就完成了大半了。
nRF5 SDK软件架构就写在这里,如果你对如何调试nRF5 SDK感到困惑的话,请参考下一篇文章:
如何调试nRF5 SDK
nRF5 SDK软件架构及softdevice工作原理的更多相关文章
- Nordic nRF5 SDK和softdevice介绍
SDK和Softdevice的区别是什么?怎么选择SDK和softdevice版本?芯片,SDK和softdevice有没有版本兼容问题?怎么理解SDK目录结构?SDK帮助文档在哪里?Softdevi ...
- 如何调试nRF5 SDK
本文将讲述Nordic nRF5 SDK的主要调试手段,以帮助大家快速定位问题,并解决问题.一般来说,你可以通过打log方式,IDE的debug模式,SDK自带的app_error_check函数,以 ...
- Web服务器的工作原理
Web服务器的工作原理 Web服务器工作原理概述 很多时候我们都想知道,web容器或web服务器(比如Tomcat或者jboss)是怎样工作的?它们是怎样处理来自全世界的http请求的?它们在幕后做了 ...
- keepalived工作原理和配置说明 腾讯云VPC内通过keepalived搭建高可用主备集群
keepalived工作原理和配置说明 腾讯云VPC内通过keepalived搭建高可用主备集群 内网路由都用mac地址 一个mac地址绑定多个ip一个网卡只能一个mac地址,而且mac地址无法改,但 ...
- web服务器工作原理
Web服务器工作原理概述 转载自http://www.importnew.com/15020.html 很多时候我们都想知道,web容器或web服务器(比如Tomcat或者jboss)是怎样工作的?它 ...
- Android系统Recovery工作原理之使用update.zip升级过程分析(一)
通过分析update.zip包在具体Android系统升级的过程,来理解Android系统中Recovery模式服务的工作原理.我们先从update.zip包的制作开始,然后是Android系统的启动 ...
- Linux Kbuild工作原理分析(以DVSDK生成PowerVR显卡内核模块为例)
一.引文 前篇博文<Makefile之Linux内核模块的Makefile写法分析>,介绍了Linux编译生成内核驱动模块的Makefile的写法,但最近在DVSDK下使用Linux2.6 ...
- 初涉IPC,了解AIDL的工作原理及使用方法
初涉IPC,了解AIDL的工作原理及使用方法 今天来讲讲AIDL,这个神秘的AIDL,也是最近在学习的,看了某课大神的讲解写下的blog,希望结合自己的看法给各位同价通俗易懂的讲解 官方文档:http ...
- Appium简介及工作原理
一.什么是Appium Appium是一个开源.跨平台的测试框架,可以用来测试原生及混合的移动端应用.Appium支持IOS.Android及FirefoxOS平台.Appium使用WebDriver ...
随机推荐
- vim 设置字体和解决乱码
在 C:\Program Files (x86)\Vim 目录中的 _vimrc 文件中加入下面两行 set fileencodings=utf-8,gb2312,gb18030,gbk,ucs-bo ...
- 磁钉导航差速式AGV控制实验
磁钉导航AGV实验 2016-03 本机器是采用RFID电子地标配合磁钉传感器的定位导航AGV.本AGV已初步实现里程计精确解算,磁钉数据融合,AGV定点精准停车.原地旋转换向.远程无线调度的功能,初 ...
- Spark 2.2 DataFrame的一些算子操作
Spark Session中的DataFrame类似于一张关系型数据表.在关系型数据库中对单表或进行的查询操作,在DataFrame中都可以通过调用其API接口来实现. 可以参考,Scala提供的Da ...
- Apache Spark 2.0三种API的传说:RDD、DataFrame和Dataset
Apache Spark吸引广大社区开发者的一个重要原因是:Apache Spark提供极其简单.易用的APIs,支持跨多种语言(比如:Scala.Java.Python和R)来操作大数据. 本文主要 ...
- mutex_lock
多核处理器下,会存在多个进程处于内核态的情况,而在内核态下,进程是可以访问所有内核数据的,因此要对共享数据进行保护,即互斥处理. mutex_lock(struct mutex *lock)和mute ...
- Oracle 修改trace 文件路径
修改trace 文件路径命令 适用于oracle 11G以后的版本 在集群环境中的2个节点都生效SQL> ALTER SYSTEM SET diagnostic_dest='/tmp' SCOP ...
- 百度NLP三面
首先,面试官根据项目经验进行提问,主要是自然语言处理相关的问题:然后写代码题,字符串处理和数字运算居多:再者是一些语言基础知识,百度用的linux平台,C++和python居多.下面列出我面试中的一些 ...
- (转)VC串口小程序(用SerialPort类)
××××××××××××××××××××××××××××××××××××××××××××××××××××× 在MFC里面实现串口通讯有很多方式: 方案一:使用微软公司提供的 串口类,SerialPor ...
- Myeclipse中is missing required source folder问题的解决
最近在开发中,有好几次遇到is missing required source folder的问题,但是有些同事机器上却没有该问题,把整个工程删掉,重新从SVN上拿下来,问题依旧存在. 该问题出现后, ...
- modelform 使用
modelForm (1) model的知识点: class UserInfo(AbstractUser): tel = models.CharField(max_length=32) gender ...