本文将介绍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. 第1件事:初始化。为了简化初始化工作,Nordic SDK所有模块初始化时,只需要将相应API输入结构体参数清0即可完成初始化工作,也就是说,只要你保证初始化参数为0,蓝牙协议栈就可以工作起来,这对很多Nordic初学者来说,大大减轻了开发工作量。
  2. 第2件事:写蓝牙事件回调处理函数。一般来说,你的应用逻辑都是放在蓝牙事件回调处理函数中,所以写好回调处理函数代码,你的开发工作就完成了大半了。

 

nRF5 SDK软件架构就写在这里,如果你对如何调试nRF5 SDK感到困惑的话,请参考下一篇文章:

如何调试nRF5 SDK

nRF5 SDK软件架构及softdevice工作原理的更多相关文章

  1. Nordic nRF5 SDK和softdevice介绍

    SDK和Softdevice的区别是什么?怎么选择SDK和softdevice版本?芯片,SDK和softdevice有没有版本兼容问题?怎么理解SDK目录结构?SDK帮助文档在哪里?Softdevi ...

  2. 如何调试nRF5 SDK

    本文将讲述Nordic nRF5 SDK的主要调试手段,以帮助大家快速定位问题,并解决问题.一般来说,你可以通过打log方式,IDE的debug模式,SDK自带的app_error_check函数,以 ...

  3. Web服务器的工作原理

    Web服务器的工作原理 Web服务器工作原理概述 很多时候我们都想知道,web容器或web服务器(比如Tomcat或者jboss)是怎样工作的?它们是怎样处理来自全世界的http请求的?它们在幕后做了 ...

  4. keepalived工作原理和配置说明 腾讯云VPC内通过keepalived搭建高可用主备集群

    keepalived工作原理和配置说明 腾讯云VPC内通过keepalived搭建高可用主备集群 内网路由都用mac地址 一个mac地址绑定多个ip一个网卡只能一个mac地址,而且mac地址无法改,但 ...

  5. web服务器工作原理

    Web服务器工作原理概述 转载自http://www.importnew.com/15020.html 很多时候我们都想知道,web容器或web服务器(比如Tomcat或者jboss)是怎样工作的?它 ...

  6. Android系统Recovery工作原理之使用update.zip升级过程分析(一)

    通过分析update.zip包在具体Android系统升级的过程,来理解Android系统中Recovery模式服务的工作原理.我们先从update.zip包的制作开始,然后是Android系统的启动 ...

  7. Linux Kbuild工作原理分析(以DVSDK生成PowerVR显卡内核模块为例)

    一.引文 前篇博文<Makefile之Linux内核模块的Makefile写法分析>,介绍了Linux编译生成内核驱动模块的Makefile的写法,但最近在DVSDK下使用Linux2.6 ...

  8. 初涉IPC,了解AIDL的工作原理及使用方法

    初涉IPC,了解AIDL的工作原理及使用方法 今天来讲讲AIDL,这个神秘的AIDL,也是最近在学习的,看了某课大神的讲解写下的blog,希望结合自己的看法给各位同价通俗易懂的讲解 官方文档:http ...

  9. Appium简介及工作原理

    一.什么是Appium Appium是一个开源.跨平台的测试框架,可以用来测试原生及混合的移动端应用.Appium支持IOS.Android及FirefoxOS平台.Appium使用WebDriver ...

随机推荐

  1. LightOJ1003---Drunk(拓扑排序判环)

    One of my friends is always drunk. So, sometimes I get a bit confused whether he is drunk or not. So ...

  2. 18.出现Description Resource Path Location Type Unknown error merging manifest

    原因是,依赖工程和主工程的manifest中的 <uses-sdk android:minSdkVersion="9" android:targetSdkVersion=&q ...

  3. 【spring学习】中文乱码问题

    问题: 在这样的一个控制器中: 返回字符串中文部分全是问号. 解决方案: 在spring-mvc.xml文件中加入以下代码: <!-- 支持spring3.0新的mvc注解 ,解决json中的中 ...

  4. odoo学习记录1

    1. odoo通过ORM(对象关系映射)实现底层数据与上层逻辑到关联,保证数据存储的安全性和使用上到便利性. 2. odoo由模块组成,每个模块包含:Bussiness Object, Data, W ...

  5. beego——发行部署

    开发模式 通过bee创建的项目,beego默认情况下是开发模式. 我们可以通过如下的方式改变我们的模式: beego.RunMode = "prod" 或者我们在conf/app. ...

  6. 2.MySQL简介

    MySQL是一种DBMS,即它是一种数据库软件.   1.连接   为了连接到MyAQL,需要一下信息: ➡️主机名(计算机名)---如果连接到本地MySQL服务器,为localhost ➡️duan ...

  7. 5-es6的模块化开发与其它的不同

    1.加载机制不同es是静态加载,其它是动态加载.Es6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量.CommonJS 和 AMD.CMD 模块,都只能在运行 ...

  8. ionic 配置打包环境

    配置java环境就不说了,太简单 下载AndroidSdkAndroid SDK Tools翻过墙的朋友可以去Google Android的官网上下载:http://developer.android ...

  9. Winter-2-STL-F Ananagrams 解题报告及测试数据

    Time Limit:3000MS     Memory Limit:0KB  Description Most crossword puzzle fans are used to anagrams- ...

  10. git 移除某个文件的版本管理

    1:最简单的,在项目刚创建的时候,在根目录的.gitignore,加入该文件的相对路径 2:已经被纳入到了版本控制,使用在当前目录下,打开cmd窗口 输入rm命令,加上文件的绝对路径(相对路径没试过) ...