Nordic BLE SOC 软件入门-OTA升级的使用
Nordic BLE SOC从出道至现在,所有型号都支持OTA升级功能,只不过使用上可能有些限制。随着SDK的不断升级(当前最新版本为16.0),OTA升级方式也经过了几个阶段发展,直到SDK13之后OTA的原理和方法总算是固定下来。下面的介绍基于当前最新的SDK16.0进行。
OTA升级原理简介
OTA是over the air的缩写,OTA升级可以理解为无线升级。使用官方OTA升级时,SDK13至SDK16的Flash的分部都如下图所示。
bootloader占用24KB,bootloader settings和MBR paramter storage共存储占用8KB,它们是用来存储校验等相关信息的。
也就是说只要使用官方的OTA升级功能,就会多消耗32KB的Flash。由于bootloader相当于一个单独的应用程序,所以不会额外消耗RAM。
上图中各个区域对应不同的协议栈版本和芯片地址如下表所列。区域四是用户数据存储区域,由于nRF52系列的Flash是4kB一页,所以用4XkB表示用户使用的大小。
当未烧录bootloader,仅烧录了协议栈和应用的时候,芯片复位运行时序是:区域7→区域5。
当烧录了对应的bootloader和协议栈的时候,芯片复位运行时序是:区域7→区域3,然后在bootloader中判断:
- 应用程序是否存在,其校验是否通过。
- OTA标志是否打开。
若判断无需留在bootloader中则会跳转到应用程序中运行,运行顺序是区域7→区域3→区域5。若需要留在bootloader中则会开启OTA的BLE广播。
需要留在bootloader中的情况一般有:应用程序未烧录、应用程序校验不通过、OTA标志被置位等。OTA标志可以使用Flash、RAM、寄存器、IO状态等等非常多的方式;官方SDK默认是使用GPREGRET寄存器和 IO状态判断两种方式,用户最常用的是GPREGRET寄存器方式。
进入应用程序后若想要OTA更新应用程序,需要在应用程序中将OTA标志置位,然后跳转(重启)到bootloader中,在bootloader中开启OTA的BLE广播。
下图描述了烧录协议栈与bootloader的时,芯片成功OTA的主要流程(单区域)。若OTA失败,芯片将重启。
实际传输和更新应用固件的操作都是在bootloader中完成的,而应用程序负责的是:接收升级指令,应用程序准备(根据应用内容可选),OTA标志置位,跳转(复位)到bootloader。
官方APP中简化了一些操作,用户只需要连接待升级的设备,选择OTA文件,启动升级三个步骤。操作过程中蓝牙断开应用程序,再扫描连接bootloader,向bootloader发送升级指令等过程都是APP自动完成的。
升级文件的传送和更新过程,SDK中都已经做好了,用户不必做任何修改,下面是具体流程图。
此图仅做了解,可以不看。
单区域方式指的是升级过程中,没有对原先的固件进行备份。Bootloader会先将区域5擦除,然后一边接收新固件一边更新区域5。
双区域方式指的是升级过程中,将原先的固件进行备份,新固件接收完成之后再擦除旧固件。Bootloader会先将新的固件接收到Bank1区域并校验,再擦除区域5,之后再将新的固件搬入区域5。
这种方式安全性高于单区域方式,但需要足够的Bank1的区域大小。
当前的SDK中,单双区域的切换和选择一般由bootloader自己完成,它通过判Free区域的大小来选择,用户也可以强行选择。一般让bootloader自行选择即可。
OTA升级操作流程
下文使用nRF52832开发板 PCA10040 和 SDK16.0 进行说明。
1.在应用程序中添加Nordic DFU蓝牙服务和相关处理代码。
SDK中的ble_app_buttonless_dfu例程是OTA升级功能的演示应用程序。
实际开发中,可以将ble_app_buttonless_dfu 例程的服务和相关代码挪到自己的工程中。
此例程在SDK路径 examples\ble_peripheral\ble_app_buttonless_dfu 下。
2.制作bootloader。
SDK中有现成的bootloader例程,在路径examples\dfu\secure_bootloader 下。
目录下有非常多的文件夹,BLE开发请根据所开发的芯片和协议栈,选择带不带DEBUG后缀的文件夹。
例如开发nRF52832 BLE OTA升级功能,使用pca10040_s132_ble文件夹下的工程。工程目录:examples\dfu\secure_bootloader\pca10040_s132_ble\arm5_no_packs
mirco ecc库文件制作
bootloader工程需要使用到mirco ecc的lib,版权原因SDK中并没有提供,需要用户自己下载micro-ecc的源文件并编译出lib文件。
每个SDK版本使用的micro ecc lib文件可能不一样。
制作lib的方法在Nordic infocenter上有介绍,需要下载micro-ecc的源文件,安装gnu,安装交叉编译器。
方法参考infocenter或SDK帮助文档:nRF5_SDK_16.0.0_offline_doc/nrf5/lib_crypto_backend_micro_ecc.html#lib_crypto_backend_micro_ecc_install
_______________________________________
或者可以使用网盘中编译好的,仅供学习使用。
关注公众号 LazycatRadio ,发送 “ECC” 获取参考代码!
解压覆盖到external\mirco-ecc ,如下图
micro-ecc文件夹中包含了3种编译器和 带浮点/不带浮点的几种lib,用户根据项目情况选择。例如使用KEIL开发nRF52810/811等时使用nrf52nf_keil中的lib,使用KEIL开发nRF52832/840/833等时选择nrf52hf_keil中的lib。
________________________________________
key文件制作
bootloader和升级包之间需要签名认证,这个过程在传送升级固件之前,目的是防止其他人往SoC中升级其他的固件。
在bootloader代码中,我们需要放入公钥(public key),升级包中需要放入私钥(private key)。这两个key文件是成对的,升级包中如果没有对应的私钥将无法成功升级。
制作key文件需要使用nrfutil,安装步骤参考:nordic-ble-soc开发环境-安装。
在命令行中输入如下命令,也可以制作批处理bat文件来执行。
nrfutil keys generate priv.pem
nrfutil keys display –key pk –format code –out_file dfu_public_key.c priv.pem
如下图运行上述命令之后会产生2个文件:
dfu_public_key.c 用于制作bootloader的固件。需要替换掉SDK中原本的这个文件(或在编译器中重新选择文件)。
priv.pem 用于制作OTA升级包。
制作bootloader固件
若上述两个步骤完成,打开工程后可以正常编译,产生bootloader的固件。若编译错误,请先检查key文件和micro-ecc库文件路径是否正确。
项目路径:nRF5_SDK_16.0.0_98a08e2\examples\dfu\secure_bootloader\pca10040_s132_ble\arm5_no_packs
前面的介绍中有提到一些芯片是否需要停留在bootloader中的判断条件,这些判断条件的使能在sdk_config.h中,根据需要选择。
区域4用于存储应用中的数据,如果需要保留也请输入区域4的大小,需要注意整体的Flash空间是否够用,因为如果区域4过大,新的固件也过大,这很可能导致空间不够无法升级。
如果没有特殊要求其他关于OTA的选项可以保持默认。
如果应用中开启了看门狗bootloader将帮你喂狗.
另外若硬件上没有低频晶振,需要切换为内部低频时钟源,方法参考链接:nordic-ble-soc-软件入门-协议栈 。
制作应用固件
应用固件千差万别,这里用ble_app_buttonless_dfu 例程说明。
路径:\examples\ble_peripheral\ble_app_buttonless_dfu\pca10040\s132
编译之后,得到应用的固件。
制作settings文件
此处要制作区域1和区域2的两个部分的hex,总共8kB。
Settings文件是根据应用固件产生的,它存储了应用的信息,不同的应用固件产生的settings文件不同。并且它将在bootloader中用于校验应用固件,校验不通过将不会启动应用程序。
将上面步骤中生成的应用hex文件,通过nrfutil的命令生成这个settings文件。同样可以在命令行下输入命令,或者使用批处理。
nrfutil settings generate –family NRF52 –application nrf52832_xxaa_S132_app.hex –application-version 3 –bootloader-version 2 –bl-settings-version 1 settings.hex
注意“–family”的参数需要根据芯片选择,它决定了settings文件在Flash中的位置。可选的参数有NRF52,NRF52840,NRF52810 等等,具体的可以输入–help来查询。
下图中可以看到settings文件的其实地址为0x0007F000,与前文例举的地址相同。
合并固件
此步骤需要将四个hex文件:协议栈、应用固件、bootloader固件、settings文件 合并为一个hex ,方便烧录。
合并它们的工具使用mergehex,安装步骤参考:nordic-ble-soc开发环境-安装。
(为了方便区分,将应用固件和bootloader固件的文件名修改了)
将四个hex文件放入同一个文件夹中,用下面命令制作批处理合成。一次合成2个,用三个步骤。
mergehex.exe -m nrf52832_xxaa_S132_app.hex s132_nrf52_7.0.1_softdevice.hex -o sd_and_app.hex
mergehex.exe -m sd_and_app.hex nrf52832_xxaa_s132_boot.hex -o sd_and_app_and_boot.hex
mergehex.exe -m sd_and_app_and_boot.hex settings.hex -o sd_app_boot_setting_complete.hex
运行批处理之后,我们将得到最终的完整固件(蓝色)。这个过程中产生了2个中间固件(红色和黄色),可以删除。
烧录
烧录完整固件可以使用nRFgoStudio,nRF Connect等等方式,这里使用nrfjprog通过批处理烧录,方便快捷。
nrfjprog的安装步骤参考:nordic-ble-soc开发环境-安装。
使用下面的命令制作批处理文件,电脑连接开发板后,烧录完整固件。
nrfjprog.exe –family NRF52 –eraseall
nrfjprog.exe –family NRF52 –program sd_app_boot_setting_complete.hex –verify –reset
正确完成烧录步骤之后,可以看到开发板LED1闪烁,并能用手机APP (nRF connect) 搜索到广播:Nordic_Buttonless 。
制作升级包
为了演示效果,首先修改ble_app_buttonless_dfu工程的广播名字为 Nordic_Buttonless_2,编译后得到hex文件nrf52832_xxaa_S132_app2.hex 。
将前文得到的私钥文件与新的应用固件放在一个文件夹,并用下面批处理制作升级包。
文件nrf52832_xxaa_S132_app2.zip 就是新固件的升级包。
nrfutil pkg generate –application nrf52832_xxaa_S132_app2.hex –application-version 0xFF –hw-version 52 –sd-req 0xCB –key-file priv.pem nrf52832_xxaa_S132_app2.zip
需要注意“–sd-req”的参数是当前使用的协议栈版本代号,s132 v7.0.1的代号为0xCB。其他版本协议栈的代号可以在命令行中使用下面命令查询。
nrfutil pkg generate –help
查询到的结果如下图:
使用手机升级
手机上需要安装APP nRF connect,安装参考:nordic-ble-soc开发环境-安装。
1.将前文制作的升级包nrf52832_xxaa_S132_app2.zip 发送到手机上
2.打开nRF connect,连接开发板的广播 Nordic_Buttonless。
3.点击顶部DFU按钮(若应用程序无DFU服务,则无此DFU按钮),选择升级文件。
4.正确选择文件后,APP自动开始升级过程。如果华为手机选择文件后没有开始升级,出现文件错误的提示,请安装第三方文件系统,通过第三方文件系统选择文件。可以参考:nordic-ble-soc开发环境-安装 。若一直停留在“DFUTARG”选项卡,可能是APP卡在“DFUTARG”选项卡中没有跳转到“NORDIC_BUTTONLESS”选项卡,用户可以手动切换过去。升级完成之后APP下方会给出提示,并自动连接开发板。到此OTA升级就成功了!
5.断开APP的蓝牙连接,切换到扫描界面。可以看到广播名字已经更新为“Nordic_Buttonless2”。蓝牙地址与步骤1中相同。若想重新体验升级过程,可以继续点击“CONNECT”升级。
拓展
Nordic BLE SoC 不仅支持升级应用程序,还支持升级bootloader 和 协议栈!
官方例程中的升级方式也不仅仅有OTA,还有串口升级!
有兴趣的朋友可以继续探究!