nRF5 SDK Bootloader and DFU moudles(1)
在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。
在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader程序。
启动过程
Bootloader启动大多数都分为两个阶段。
第一阶段主要包含依赖于CPU的体系结构硬件初始化的代码,通常都用汇编语言来实现。这个阶段的任务有:基本的硬件设备初始化(屏蔽所有的中断、关闭处理器内部指令/数据Cache等)。为第二阶段准备RAM空间。
如果是从某个固态存储媒质中,则复制Bootloader的第二阶段代码到RAM。
设置堆栈。
在第一阶段中为什么要关闭Cache?通常使用Cache以及写缓冲是为了提高系统性能,但由于Cache的使用可能改变访问主存的数量、类型和时间,因此Bootloader通常是不需要的。
跳转到第二阶段的C程序入口点。
第二阶段通常用C语言完成,以便实现更复杂的功能,也使程序有更好的可读性和可移植性。这个阶段的任务有:
初始化本阶段要使用到的硬件设备。
检测系统内存映射。
将内核映像和根文件系统映像从Flash读到RAM。
为内核设置启动参数。
调用内核。
引导加载程序是系统加电后运行的第一段软件代码,称之为Bootloader。BootLoader是Booter和Loader的合写:前者意味着要初始化嵌入式系统硬件使之运行起来,至少是部分运行起来,与PC机中的BIOS作用相似;后者意味着将嵌入式操作系统映像加载到内存中,并跳转过去运行。
将硬盘MBR中的BootLoader读到系统的RAM中,然后将控制权交给OS BootLoader。BootLoader的主要运行任务就是将内核映象从硬盘上读到 RAM 中,然后跳转到内核的入口点去运行,也即开始启动操作系统。
看门狗,又叫watchdog timer,是一个定时器电路,一般有一个输入,叫喂狗(kicking the dog/service the dog),一个输出到MCU的RST端,MCU正常工作的时候,每隔一段时间输出一个信号到喂狗端,给 WDT清零,如果超过规定的时间不喂狗(一般在程序跑飞时),WDT定时超过,就会给出一个复位信号到MCU,使MCU复位。防止MCU死机. 看门狗的作用就是防止程序发生死循环,或者说程序跑飞。
主引导记录(MBR,Master Boot Record)是位于磁盘最前边的一段引导(Loader)代码。它负责磁盘操作系统(DOS)对磁盘进行读写时分区合法性的判别、分区引导信息的定位,它由磁盘操作系统(DOS)在对硬盘进行初始化时产生的。
固件(firmware)一般存储于设备中的电可擦除只读存储器EEPROM(Electrically Erasable Programmable ROM)或FLASH芯片中,一般可由用户通过特定的刷新程序进行升级的程序。一般来说,担任着一个数码产品最基础、最底层工作的软件才可以称之为固件,比如计算机主板上的基本输入/输出系统BIOS(Basic Input/output System),在以前其实更多的专业人士叫它固件。
Nordic文档总结
基本引导加载程序将启动位于内存中特定位置的应用程序,因此您可以使用此类引导加载程序,例如,在启动应用程序之前在多个应用程序之间切换或初始化设备。
引导加载程序模块提供的最重要功能是设备固件更新(DFU)功能。 DFU的主要特点是:
- 更新应用程序,SoftDevice和bootloader,
- 来自经过身份验证的来源(签名更新)的更新
- 降级预防,
- 硬件兼容性验证,
- 各种运输:(BLE,UART,USBD),
- 支持使用和不使用SoftDevice进行应用程序更新,
- 支持使用SoftDevice独立固件替换SoftDevice相关固件,
- 支持使用SoftDevice相关固件替换SoftDevice独立固件。
下图显示了引导加载程序模块的层架构:、
(BootLoader)引导加载程序模块负责:
- 启动到应用程序,
- 激活新固件,
- 可选地,进入DFU模式,激活DFU传输并传送新固件,
- 喂养看门狗定时器
Bootloader Settings页面
非易失性存储器中的页面(请参阅存储器布局)用于保存引导加载程序和DFU信息。 设置页面包含以下信息:
- 当前固件 - 大小,CRC-32,
- 待定固件 - 尺寸,CRC-32,
- 固件更新的进度,
- 固件激活的进度,
- 当前固件版本(应用程序和引导程序),
- 运输特定的数据。
固件激活
固件激活是固件更新过程的最后一步。 根据启动期间读取的设置页面中的信息触发激活。 固件激活涉及复制新固件以代替退出的固件,并更新设置页面以允许新固件启动。 引导加载程序可确保复制是电源故障安全的。 在更新引导加载程序的情况下,MBR功能用于执行电源故障安全复制(SD_MBR_COMMAND_COPY_BL)。
DFU模式(Device Firmware Upgrade)
在DFU模式下,引导加载程序激活DFU传输,设备已准备好接收新固件。引导加载程序在以下条件下进入DFU模式:
- 没有有效的应用程序。
- SoftDevice已激活,并且存在有效的应用程序。在这种情况下,引导加载程序期望主机可以请求应用程序更新。
- 进入DFU模式由其中一个可选来源触发:
- 按钮(NRF_BL_DFU_ENTER_METHOD_BUTTON)
- 引脚复位(NRF_BL_DFU_ENTER_METHOD_PINRESET)
- GPREGRET寄存器中的特殊值(NRF_BL_DFU_ENTER_METHOD_GPREGRET),
- 从写入设置页面的应用程序请求(NRF_BL_DFU_ENTER_METHOD_BUTTONLESS)。
进入DFU模式后,将启动不活动计时器。在计时器到期时,引导加载程序将重置。在任何DFU活动上重新启动不活动计时器。默认情况下,不活动超时设置为NRF_BL_DFU_INACTIVITY_TIMEOUT_MS。如果在SoftDevice激活后进入DFU模式,则超时设置为NRF_BL_DFU_CONTINUATION_TIMEOUT_MS。
启动应用程序
根据设置页面中的信息,引导加载程序确定应用程序是否存在以及它位于何处。 引导加载程序在启动之前检查应用程序的完整性。 可选地,在某些情况下可以跳过完整性检查以减少启动时间(NRF_BL_APP_CRC_CHECK_SKIPPED_ON_GPREGRET2,NRF_BL_APP_CRC_CHECK_SKIPPED_ON_SYSTEMOFF_RESET)。 如果出现下列情况之一,则引导加载程序进入DFU模式:
- 没有安装应用程序,
- 完整性检查失败,
- 没有设置页面。
编程引导加载程序
在系统启动期间,如果安装了引导加载程序,则主引导记录(MBR)负责启动引导加载程序。 为此,MBR必须知道引导加载程序的起始地址。 此起始地址在MBR本身或UICR.BOOTLOADERADDR中定义。 编程引导加载程序时,必须将其设置为正确的值。 有关更多详细信息,请参阅S132 SoftDevice规范。
对引导加载程序进行编程需要执行以下步骤:
- 擦除设备。
- 编写SoftDevice。 有关说明,请参阅编程SoftDevices。
- 编译引导加载程序。
- 编程引导加载程序并写入UICR.BOOTLOADERADDR。 有关Segger Embedded Studio,Keil,IAR和nrfjprog的说明,请参阅以下部分(如果您使用的是GCC)。
设备固件更新过程
执行设备固件更新需要两个设备:DFU目标和DFU控制器。 DFU目标是使用新固件映像更新的设备,该固件映像可以包含新应用程序,SoftDevice,引导加载程序或SoftDevice和引导加载程序的组合。 DFU控制器是传输镜像的设备。 例如,DFU控制器可以是运行app的移动电话,也可以是与nrfutil一起使用的nRF5开发套件。
DFU目标是运行具有至少一个活动DFU传输的DFU的设备。 它可以是DFU模式下的引导加载程序,也可以是后台运行DFU的应用程序(DFU over TFTP示例)。 然后,DFU控制器可以启动固件映像的传输,该固件映像由DFU目标接收和验证。 如果映像有效,则设备将重置,引导加载程序将激活映像以替换现有固件。 根据映像的类型,它可能会替换应用程序,SoftDevice,甚至是接收更新的当前引导加载程序。 有关图像存储位置及其复制方式的详细信息,请参阅双库和单库更新。
作为DFU控制器,您可以使用以下Nordic工具:
- nrfutil (version 2.2.0 or later)
- nRF Connect for Desktop
- Nordic's mobile apps, such as nRF Connect for Mobile.
以下流程图显示了必须在DFU目标中实现的固件更新所需的步骤:
固件更新过程的事件和过程与所使用的传输协议无关。 DFU模块包含BLE,UART和USB CDC的实现(请参阅DFU协议)。 DFU控制器可以通过在DFU传输上发送相应的消息来触发事件。
DFU程序
nrfutil工具生成一个包含一个或两个更新的zip文件(请参阅使用nrfutil创建固件包)。 单个更新包含具有新固件详细信息和二进制数据的init数据包。 DFU控制器发送init数据包并等待DFU目标的确认。 DFU目标验证init数据包并以结果响应。 成功验证后,DFU控制器发送二进制数据。 一旦DFU目标接收到二进制数据,就会执行后验证。 成功验证后,DFU目标将重置,引导加载程序将激活新固件。 如果zip文件包含两个更新,则DFU控制器期望DFU目标进入DFU模式并尝试通过建立连接并发送第二个init数据包来执行第二次更新。 从DFU控制器应用程序的用户的角度来看,即使以两个步骤执行,这种更新也被视为单个更新。
单个更新可能包含以下元素:
- 应用程序,
- 一个SoftDevice,
- 引导程序,
- 引导程序和SoftDevice。
如果update必须包含应用程序和SoftDevice(以及引导加载程序),则zip包中包含两个更新。 如果引导加载程序依赖于Softdevice(请参阅Bootloader依赖项),则包含Softdevice update的软件包可能包含引导加载程序。
完成第一步后,激活新的SoftDevice(和引导加载程序),应用程序可能仍然有效但由于SoftDevice依赖性损坏而无法运行。 必须在第二步中更新它。 使用SoftDevice激活软件包后,引导加载程序将进入期望应用程序更新的DFU模式。 由于应用程序更新是可选的(在SoftDevice次要版本更新后不需要),因此引导加载程序中的不活动超时设置为与默认值(NRF_BL_DFU_CONTINUATION_TIMEOUT_MS)不同(更短)的值。
nRF5 SDK Bootloader and DFU moudles(1)的更多相关文章
- nRF5 SDK Bootloader and DFU moudles(2)
镜像的验证 在执行设备固件更新之前,应验证新映像. 在传输实际固件(预验证)之前,可以检查某些信息(例如,兼容性). 其他信息,例如图像的散列,应在传输(验证后)后进行验证. Init packet ...
- nRF5 SDK Bootloader and DFU moudles(3)
DFU控制点特性用于控制DFU过程的状态. 通过写入该特征来请求所有DFU程序. 标记过程结束的响应将作为通知收到. BLE传输 Transfer of an init packet DFU控制器首先 ...
- nRF5 SDK for Mesh(三) Installing the mesh toolchain 安装编译工具链
Installing the mesh toolchain To build the example applications, a toolchain based on either CMake o ...
- nRF5 SDK for Mesh(二) Getting started 快速开始
Getting started To get started, take a look at the Light switch demo. It shows how a simple applicat ...
- nRF5 SDK软件架构及softdevice工作原理
本文将介绍Nordic nRF5 SDK软件架构以及softdevice工作原理,以加深大家对Nordic产品开发的理解,这样开发过程中碰到问题时,大家也知道如何去调试. 如果你刚开始接触nRF5 S ...
- Nordic nRF5 SDK和softdevice介绍
SDK和Softdevice的区别是什么?怎么选择SDK和softdevice版本?芯片,SDK和softdevice有没有版本兼容问题?怎么理解SDK目录结构?SDK帮助文档在哪里?Softdevi ...
- nRF5 SDK for Mesh(四) 源码编译
官方文档教程编译源码: http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk%2Fdita%2Fs ...
- nRF5 SDK for Mesh(一) 介绍和下载源码
一: 官网介绍地址:http://www.nordicsemi.com/Products/Bluetooth-low-energy/nRF5-SDK-for-Mesh Nordic offers a ...
- 如何调试nRF5 SDK
本文将讲述Nordic nRF5 SDK的主要调试手段,以帮助大家快速定位问题,并解决问题.一般来说,你可以通过打log方式,IDE的debug模式,SDK自带的app_error_check函数,以 ...
随机推荐
- SQL基础练习03---牛客网
目录 1 创建一个actor表 2 批量插入数据 3 批量插入数据不用replace 4 创建一个actor_name表 5 对first_name创建唯一索引 6 针对actor表创建视图actor ...
- Luogu P5018 对称二叉树 瞎搞树&哈希
我的天..普及组这么$hard$... 然后好像没有人用我的垃圾做法,,,好像是$O(n)$,但十分的慢,并且极其暴力$qwq$ 具体来说,就是直接$dfs$求出树高,然后想像出把原来的树补成满二叉树 ...
- element-ui做表单验证 v-for遍历表单 自动生成校验规则 pc移动双适配
整体思路: 1:利用element-ui的栅格实现小分辨率和大分辨率的适配 2:模拟一组数据,从中筛选出 绑定各个表单值的对象 以及生成验证规则对象 3:在script标签内 .data()外,自 ...
- 栈的数组和链表实现(Java实现)
我以前用JavaScript写过栈和队列,这里初学Java,于是想来实现栈,基于数组和链表. 下面上代码: import java.io.*; //用接口来存放需要的所有操作 interface st ...
- 记一次maxwell报错:Couldn't find table 'violation_info' in database och_evcard_data
往常maxwell是正常跑的,但是突然今天报错: Couldn't find table 'violation_info' in database och_evcard_data 而且这个库和这个表, ...
- python性能测试值timeit的使用示例
from timeit import Timer def t1(): li = [] for i in range(10000): li.append(i) def t2(): li = [] for ...
- ANDROID_ID
在设备首次启动时,系统会随机生成一个64位的数字,并把这个数字以16进制字符串的形式保存下来,这个16进制的字符串就是ANDROID_ID,当设备被wipe后该值会被重置.可以通过下面的方法获取: i ...
- gradle添加阿里云maven库
用gradle构建spring项目,才发现gradle要添加阿里云maven库和maven不太一样 链接:https://www.cnblogs.com/SiriYang/p/10638365.htm ...
- 面试题:this指针的指向,以及call、apply应用
var a = 2; function test(){ var a = 4; console.log(this.a); this.a = 1; } test();//2 //这里为什么是2?因为调用t ...
- LeetCode 132. 分割回文串 II(Palindrome Partitioning II)
题目描述 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回符合要求的最少分割次数. 示例: 输入: "aab" 输出: 1 解释: 进行一次分割就可将 s ...