nRF5 SDK 入门(三、理解 nRF5 SDK 应用与协议栈分开烧录)

说明一下 Nordic nRF5 SDK 软件 应用程序 和 协议栈分开烧录的理解

前言

上一篇文章我们了解了 Nordic nRF5 SDK 目录结构,在那之前我们也已经搭建好了开发环境,实际上我们就已经可以进入我们的开发之旅了,但是如果刚接触 Nordic 蓝牙开发的小伙伴总是会有一些
疑问:

1、Nordic 蓝牙开发应用程序和协议栈分开是什么意思?
2、分开了那工程开发,烧录岂不是相当复杂?

带着这些问题,本文我们就来了了解 nRF5 SDK 应用与协议栈分开烧录是怎么一回事。

Nordic nRF5 SDK 入门系列博文:
GCC + Vscode 搭建 nRF52xxx 开发环境
nRF5 SDK 入门(二、了解 nRF5 SDK 目录结构)
.
我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!

目录

  • 前言
  • 一、 ARM 内核启动过程
    • 1.1 启动过程
    • 1.2 程序存放位置
  • 二、nRF5 SDK 程序存储方式
    • 2.1 nRF5 SDK 的区分存储
    • 2.2 分开处理的好处
  • 三、 烧录说明
  • 结语

一、 ARM 内核启动过程

我们的使用的 nRF52xxx 芯片是 M4 内核,在讨论本文标题的问题之前,我们得复习一下 M4 内核启动相关的知识点。

1.1 启动过程

CPU 复位后会从 0x00000000 处取得第一条指令开始运行 ,ARM Cortex-M/R 内核在复位后,也会从 0x0000 0000 处开始执行:它是从地址 0x0000_0000 处取出 MSP 的初始值;从地址 0x0000_0004 处取出 PC 的初始值,然后从这个值对应的地址处取指。事实上,地址 0x00000004 开始存放的就是默认中断向量表。

在这里插入图片描述

上图是 M3 内核,这一点和 M4 内核是一样的。所以我们想要程序正常运行,就得从 0x0000 0000 这个地址开始存放程序。

1.2 程序存放位置

STM32 的程序存放位置:

这里回忆一下熟悉的 STM32 ,我们一般而言,程序存放的位置为 0X0800 0000,那是因为 STM32 为了方便不同的方式启动,所以 把前面 0x0000 0000 开始的空间让出来了,为了实现存储重映射的功能。可以使得芯片从内部 Flash, 系统存储器,内部 SRAM 启动,不同的启动方式只需要把不同的地址重映射到 0x0000 0000 即可。

在 STM32 的工程中,在很多地方都能够直接体现程序存放的这个地址:

在这里插入图片描述

但是和大多数芯片一样的是 ,STM32 的程序也只需要烧录一次 。

Nordic 的芯片没有用到类似 STM32 的存储重映射的功能,所以因为 内核 需要从0x0000 0000 开始执行程序,所以它必然需要把程序从 0 地址开始存放。(官方的例程是这样,如果个人测试采用其他方式不算。)

到这里我们只是确定了 Nordic 的芯片的程序必须要从 0 开始存放 ,但是 Nordic 还做了另外的一种事情,就是把程序分成了两部分!

二、nRF5 SDK 程序存储方式

我们在上一篇文章说明了一个问题:

在这里插入图片描述
一个裸机程序,单独烧录至 0x26000 处程序不会运行,如果烧录至 0x0 位置处,可以正常运行,也正是说明 Nordic 的芯片是从 0x0 地址开始运行程序的,那么为什么官方的示例会把位置放在 0x26000 处,而不是 0x0 处,这就是 Nordic 与其他厂商处理不一样的地方。

2.1 nRF5 SDK 的区分存储

实际上,我们通常的思维会是:

反正都是程序,协议栈也是程序,都在一个工程里面,编译过后生成一个 hex ,直接放到 0x0 的地址上直接运行即可。

对于 nRF5 SDK 而言,它们是把 协议栈 和 应用程序 分开处理,对于这一点,有位 Nordic 中国区的 FAE 在某园上写过一篇文章:《 nRF5 SDK软件架构及softdevice工作原理 》(文章大家可以直接度娘搜索,因为涉及到外站竞争链接,所以这里就不放了)里面很好的说明了这个问题,以下说明取自这篇文章:

Nordic nRF5 SDK将芯片的存储器划分成如下格局:
在这里插入图片描述
上面推荐文章中,有详细的说明:

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)形式提供给大家的, 这一点我们通过 SDK 文件夹下的内容也能知道,如图:

在这里插入图片描述

所以我们开发中比较关心的问题,听起来分开处理感觉会变得麻烦很多,实际上协议栈我们并不需要编程,编译,直接有现成的,只需要知道如何烧录到对应位置即可。

2.2 分开处理的好处

Nordic 这样分开处理好处,在上面大佬的文章也有详细的说明:

  1. 首先二进制形式可以保证蓝牙BQB认证的版本和发布给客户的版本一模一样(因为库形式的版本每次编译都会产生少许差异!)。
  2. 其次softdevice不需要跟你的应用一起编译或者链接,大大节省调试时间。
  3. 更主要的是,Softdevice运行在固定的Flash空间中,使用固定的RAM空间,从而与你的应用完全隔离开,实现了真正的模块分离,从而出现问题时,可以迅速定位是协议栈的问题还是应用的问题。
  4. 再次二进制形式的 Softdevice开启了保护机制,应用代码是不能对其进行访问的,以保证Softdevice的安全性,防止应用代码误访问或者误擦除某些softdevice区域。
  5. 最后这种多bin形式使得OTA变得非常灵活,你可以只OTA应用,也可以OTA协议栈和bootloader,或者三者同时OTA。

对于具体的 协议栈与应用 的细节大家可以自己查看上面推荐的文章《 nRF5 SDK软件架构及softdevice工作原理 》,或者等到后期随着我们的开发到了那一步,我也会详细的分析一下,在上面文章的结尾,有下面一段话,可以让大家对使用 Nordic nRF5 SDK 不那么刚到害怕:

从上面nRF5 SDK软件架构的讲解过程中,我们可以看到,当我们开发Nordic平台的BLE应用时,主要需要做两件事:
.
第1件事:初始化。为了简化初始化工作,Nordic SDK所有模块初始化时,只需要将相应API输入结构体参数清0即可完成初始化工作,也就是说,只要你保证初始化参数为0,蓝牙协议栈就可以工作起来,这对很多Nordic初学者来说,大大减轻了开发工作量。
.
第2件事:写蓝牙事件回调处理函数。一般来说,你的应用逻辑都是放在蓝牙事件回调处理函数中,所以写好回调处理函数代码,你的开发工作就完成了大半了。

三、 烧录说明

到这里,大家应该都能够理解与接受 Nordic nRF5 SDK 对于应用于协议栈分开处理的方式了,那么回到文章最开头的两个问题:

1、Nordic 蓝牙开发应用程序和协议栈分开是什么意思?
2、分开了那工程开发,烧录岂不是相当复杂?

第一个问题,我们在上文已经得到了答案,第二个问题其实我们也已经解决了一半,并不会更加复杂,因为我们还是只需要注重我们的应用程序即可。

本小节来讲一下烧录问题,首先我们的示例编译过后会生成一个 hex 文件,加上协议栈的 hex 文件,一共是两个 hex 文件。

这里我再次再次再次复习一个知识点:对于 .hex 文件来说,他包含了存放地址信息,可以直接烧录会根据链接文件存放至对应的地址。

就用我们的 J-Flash 工具来说,我们已经知道,示例编译过后拖动至 J-Flash ,它自动会显示需要存放在 flash 中的位置,应用程序如下图:

在这里插入图片描述

那同样的,我们也可以把协议栈 hex 文件用同样的方式烧录,我们拖动至 J-Flash ,如下图:

在这里插入图片描述

他们两个 hex 的存放位置是不一样的,我们可以直接按照正常步骤连接然后烧录 :

在这里插入图片描述

这样就好了! 并没有什么特别需要你注意的,不会存在什么覆盖啊,搞错之类的问题。

同样的,即便我们不用 J-Flash ,我们在我们搭建好的开发环境下面,使用命令烧录,大家可以查看一下 Makefile 最后的伪指令:

在这里插入图片描述

也只是需要我们敲两下命令即可,并没有过多的工作。

当然,大家用官方的 nRFgo Studo ,原理也是一样的,只要搞清楚程序存放的形式,就没那么难了。

但是这里有一点,对于使用 Keil 开发来说, 他的 hex 存放位置也是可以设置的:

在这里插入图片描述

上面是外设的裸机测试,如果是带协议栈的,那么在 keil 中是需要把上面地址修修改的,如下图:

在这里插入图片描述

但是对于 Keil 开发来说,他协议栈的烧录直接通过 Keil 我倒是不知道如何操作,都是需要借助第三方工具 nRFgo Studo 或者直接使用 J-Flash 单独烧录一次协议栈。

结语

本文我们主要了解了一下 Nordic nRF5 SDK 应用与协议栈分开处理的方式,通过文章我们应该明白了分开处理的是什么意思,分开的好处,以及对我们实际应用开发的影响。

详细大家都能够感受到,这种方式不仅不会让我们开发变得更加复杂,反而能够让我们专心与自己的应用程序,同时也跟让我们更好的定位开发过程中遇到的问题,相应付出的代价只不过是我们需要多烧录一次 hex而已。

好了,本文就到这里,谢谢大家!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/136701.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux中字符设备的打开、写入

一个内核模块应该由以下几部分组成。 第一部分&#xff0c;头文件部分。一般的内核模块&#xff0c;都需要 include 下面两个头文件&#xff1a; #include <linux/module.h> #include <linux/init.h> 第二部分&#xff0c;定义一些函数&#xff0c;用于处理内核…

改进YOLO系列 | YOLOv5/v7 引入Super Token Sampling ViT | 《CVPR 2023 最新论文》

论文地址:https://arxiv.org/abs/2211.11167 代码地址:https://github.com/hhb072/STViT 视觉变换器已经在许多视觉任务中取得了令人印象深刻的性能。然而,它在捕捉浅层的局部特征时可能会受到高度冗余的影响。因此,引入了局部自注意力或早期卷积,这些方法牺牲了捕捉长距…

Nacos热更新

Nacos热更新 相比其他注册中心&#xff0c;Nacos的优势之一在于热更新。 热更新&#xff0c;就是不需要重启服务&#xff0c;就能够更新配置。 nacos配置中心 首先&#xff0c;需要搭建 Nacos&#xff0c;详情见&#xff1a; https://www.cnblogs.com/expiator/p/17392549.h…

K8S知识点(十)

&#xff08;1&#xff09;Pod详解-启动命令 创建Pod&#xff0c;里面的两个容器都正常运行 &#xff08;2&#xff09;Pod详解-环境变量 &#xff08;3&#xff09;Pod详解-端口设置 &#xff08;4&#xff09;Pod详解-资源配额 修改&#xff1a;memory 不满足条件是不能正常…

第27章_事务原理之MVCC与锁机制

文章目录 MVCCread view聚集索引的隐藏列事务的可见性问题快照读当前读 redologundolog锁机制锁类型共享锁&#xff08;S&#xff09;排他锁&#xff08;X&#xff09;意向共享锁&#xff08;IS&#xff09;意向排他锁&#xff08;IX&#xff09;锁的兼容性 锁算法锁兼容关于锁…

Linux MMC子系统 - 4.eMMC 5.1常用命令说明(2)

By: Ailson Jack Date: 2023.11.12 个人博客&#xff1a;http://www.only2fire.com/ 本文在我博客的地址是&#xff1a;http://www.only2fire.com/archives/163.html&#xff0c;排版更好&#xff0c;便于学习&#xff0c;也可以去我博客逛逛&#xff0c;兴许有你想要的内容呢。…

小程序中如何设置门店信息

小程序是商家转型升级的利器&#xff0c;小程序中门店信息的准确性和完整性对于用户的体验和信任度都有很大的影响。下面具体介绍门店信息怎么在小程序中进行设置。 在小程序管理员后台->门店设置处&#xff0c;可以门店设置相关。主要分为2个模块&#xff0c;一个是门店级…

AD教程 (十三)常见CHIP封装的创建

AD教程 &#xff08;十三&#xff09;常见CHIP&#xff08;贴片&#xff09;封装的创建 PCB封装是电子设计图纸和实物之间的映射体&#xff0c;具有精准数据的要求&#xff0c;在实际设计中需要通过规格书获取创建封装的数据参数。 PCB封装和实物的大小一致。PCB封装是承载实物…

Linux进程的认识与了解[上]

文章目录 1.何为进程?1.1对进程的认识1.2基本概念 2.OS如何管理大量进程?2.1图解2.2进程的形成 3.何为PCB?3.1对PCB的认识3.2task_ struct内容分类3.2对进程表的认识 4.查看进程4.1基础指令4.2获取某进程的PID(process id)4.3杀死进程4.4获取当前进程的父进程的ppid(parent …

Vant 移动端UI

Vue项目中安装Vant # Vue 3 项目&#xff0c;安装最新版 Vant npm i vant 组件按需引入配置 Vant按需引入- - -安装&#xff1a;unplugin-vue-components 插件 unplugin-vue-components 插件可以在Vue文件中自动引入组件&#xff08;包括项目自身的组件和各种组件库中的组件&…

RK3568平台开发系列讲解(Linux系统篇)Linux 目录结构

🚀返回专栏总目录 文章目录 一、VFS二、分区结构三、挂载 mount四、目录结构沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们从目录管理入手,会更直观的理解 linux 的目录结构。 一、VFS Linux 所有的文件都建立在虚拟文件系统(Virtual File System ,VFS…

事件循环Eventloop

事件循环 浏览器的进程模型 何为进程&#xff1f; 程序运行需要有它自己专属的内存空间&#xff0c;可以把这块内存空间简单的理解为进程 每个应用至少有一个进程&#xff0c;进程之间相互独立&#xff0c;即使要通信&#xff0c;也需要双方同意。 何为线程&#xff1f; 有…

【Devchat 插件】创建一个GUI应用程序,使用Python进行加密和解密

VSCode 插件 DevChat——国内开源的 AI 编程&#xff01; 写在最前面DevChat是什么&#xff1f;什么是以提示为中心的软件开发 &#xff08;PCSD&#xff09;&#xff1f;为什么选择DevChat&#xff1f;功能概述情境构建添加到上下文生成提交消息提示扩展 KOL粉丝专属福利介绍D…

【原创课设】java+swing+mysql选课管理系统设计与实现

摘要&#xff1a; 随着学校规模的扩大和课程设置的多样化&#xff0c;传统的手工选课管理方式已经无法满足现代教育的需求。因此&#xff0c;开发一款高效、便捷的选课管理系统变得尤为重要。该系统可以提高选课工作的效率&#xff0c;减少人为错误&#xff0c;同时也能为学生…

linux循环继续fordodone数值处理和脚本的追踪调试

格式 for &#xff08;&#xff08;初始值&#xff1a;限制值&#xff1b;步长&#xff09;&#xff09; do 程序段 done 注意点&#xff1a;$(()) 数值运算 $()命令 ${}取值 sh [-nvx] *.sh -n 不执行脚本&#xff0c;检查语法错误-常用 -v 执行之前&#xff0c;将…

Windows server 2008 R2 IIS搭建ASP网站教程

一、安装应用程序服务器 提示安装成功 二、添加角色服务asp 三、asp网站配置 放入源码 设置网站首页为index.asp: 设置应用程序池 四、设置网站目录属性 五、access数据库连接配置 Cd c:\Windows\System32\inetsrv appcmd list apppool /xml | appcmd set apppool /…

华为防火墙基本原理工作方法总结(包含源进源出)

两台防火墙在规划接口时一般2台防火墙的业务口相同&#xff0c;心跳口相同&#xff0c;这个上是基础&#xff0c;例如&#xff1a;第一台防火墙业务口用了g1/0/1口&#xff0c;那第二台防火墙业务口也得是这个g1/0/1口。 防火墙只会对tcp首包syn建立会话表&#xff0c;其它丢掉…

【Redis系列】Redis上设置key,value的时候出现NOAUTH Authentication required提示如何解决?

哈喽&#xff0c;大家好&#xff0c;我是小浪。相信大家在初学一门新的知识点的时候都会遇到各种各样的问题&#xff0c;在网上找了一大堆的解决方案&#xff0c;最后还是无功而返&#xff0c;那么今天博主就记录一下在进行Redis的一些操作中遇到的问题~ 当我们好不容易安装好R…

js案例:打地鼠游戏(打灰太狼)

效果预览图 游戏规则 当灰太狼出现的时候鼠标左键点击灰太狼加10分&#xff0c;小灰灰出现的时候鼠标左键点小灰灰击减10分&#xff0c;不点击不减分不加分。 整体思路 1.把获取背景图片中每个地洞的位置&#xff0c;把所有位置放到一个数组中。 2.封装随机数函数&#xff0c;随…

Tomcat学习

一、入门 在webapp里面必须先创建一个文件夹&#xff0c;文件夹里面放的内容&#xff0c;才会被访问到。 创建一个javaweb项目后