------------恢复内容开始------------
摘要:在前面的nrf52——DFU升级OTA升级方式详解(基于SDK开发例程)一文中我测试了基于蓝牙的OTA,本文将开始基于UART和USB(USB_CDC_)进行升级测试。
1、生成秘钥
2、生成USB或者UART的BootLoader程序(需要算法库和秘钥)
3、生成APP工程
4、合成初始的固件、并下载到相应的硬件
5、生成需要更新的APP固件
6、合成升级包固件,一般为ZIP文件。
7、利用USB或者UART连接设备并上传升级固件
特别注意:在这过程中依然会遇到各种各样的细节问题,如果你在升级时有遇到问题,可以着重看一下是否和你遇到的问题类似,每一节遇到的问题,我都会以一个小节的方式放到后面供大家参考。
还是那句话,在操作前我默认您已经安装好了相关测试环境和基础工具,如果没有请参看如下的官方中文链接去安装:Nordic nRF5 SDK开发环境搭建(nRF51/nRF52芯片平台) - iini - 博客园 (cnblogs.com),同时本文也只是对整个升级流程进行一次完整操作,并记录一些遇到的问题及解决方式,如果你想知道具体原理,请参看如下的官方链接:详解蓝牙空中升级(BLE OTA)原理与步骤 - iini - 博客园 (cnblogs.com) 原理是一样的,只是数据传输方式选择不一样了而已。那么接下我们就正式开始,有些步骤可能和蓝牙OTA篇重叠,可以选择性观看。
开始之前先把我们要用到的基础指令全部贴出来:
//私钥生成命令: nrfutil keys generate priv.pem //(priv.pem就是私钥) //公钥生成命令: nrfutil keys display --key pk --format code priv.pem --out_file dfu_public_key.c //(dfu_public_key.c就是公钥) //settings包生成命令 nrfutil settings generate --family NRF52 --application app.hex --application-version 1 --bootloader-version 1 --bl-settings-version 2 settings.hex //生成初始固件包命令 mergehex --merge bootloader.hex settings.hex --output bl_temp.hex mergehex --merge bl_temp.hex app.hex s140_nrf52_7.2.0_softdevice.hex --output whole.hex //擦除芯片命令 nrfjprog --eraseall -f NRF52 //下载命令 nrfjprog --program whole.hex --verify -f NRF52 //硬件复位命令 nrfjprog --reset -f NRF52 //生成升级包命令 nrfutil pkg generate --application app_new.hex --application-version 2 --hw-version 52 --sd-req 0x0100 --key-file priv.pem dfu.zip //USB升级触发命令 nrfutil dfu usb-serial -pkg dfu.zip -p COM14 -fc 0 -b 9600 //UART升级触发命令 nrfutil dfu serial -pkg dfu.zip -p COM14 -fc 0 -b 9600
还是熟悉的配方,先生成私钥,在任意一个位置建立一个文件夹,如DFU_USB,打开后直接在路径栏输入cmd回车打开我们命令窗口(其他方式打开也一样,但是请定位到刚刚这给文件夹)。
在命令框依此运行下面两条命令:
运行完毕后生成了如下两个文件文件priv.pem和dfu_public_key.c,具体如图所示:
如果你已经使用过蓝牙OTA凡是升级,那么你的算法库已经存在了,不需要再去生成了。如果你是第一次测试DFU升级,那么依然需要进行算法库生成:可以参考我上一篇文章的生成流程,链接如下:nrf52——DFU升级OTA升级方式详解(基于SDK开发例程) - 星辰_start - 博客园 (cnblogs.com),如果你环境没有问题,或者出现过修改,那么直接运行SDK目录:external\micro-ecc下的build_all.bat脚本即可,有问题在去参考解决。
把我们第一步我们生成的密钥替换SDK中的密钥,这一步如果你前面已经参考过蓝牙OTA例程,那么就可以用当时生成的密钥,不用在替换,如果没有是第一次进行DFU升级,那么请替换(路径:examples\dfu):
替换完成打开同目录下文件secure_bootloader,你会看到许多的例程bootloader,这些例程基本已经涵盖了nrf52系列全部的芯片和升级方式(BLE/USB/UART),在里面你会看到两种区别,有debug和无debug的,区别只是有debug的是有log打印信息的,在运行时你可以知道程序运行到哪里的,对于研发调试时很有必要的,但是相对的生成的hex文件就大,你可以自行选择。
选择芯片和你想要的升级方式打开后选择编译方式生成bootloader,但是如果没有怎么办,比如你想使用nrf52833的USB,没有怎么办,不要慌,我会在后面的章节进行讲解,先让我们走一遍正常流程。
芯片对于如下:
那我就来选择一个进行升级把,我选择nrf52840,先生成USB的选择如下工程:pca10056_usb_debug,编译生成hex文件。如果你编译时出现uECC,h的报错,说明前面算法库生成,你可能只是简单的双击了build_all.bat脚本,但是执行出错了,并没有完全生成算法库,那请去看我关于蓝牙OTA的例程进行解决。在正确生成hex文件后把这个文件复制到DFU_USB文件夹中并改名为bootloader_usb(为了一会和UART区分开),
这一步没有蓝牙OTA那样麻烦,我们直接任意找一个程序蓝牙程序即可,我选择最经典的NUS程序(透传)路径如下:examples\ble_peripheral\ble_app_uart,直接打开编译即可,获得一个蓝牙APP的HEX文件,放到DFU_USB文件中,改名为app,同时注意你工程的协议栈版本是多少,可以这样查看:
然后我们去如下目录找到对应版本的协议栈HEX文件,复制到我们的DFU_USB中,路径:components\softdevice。然后在更改一下APP中的蓝牙名称,默认为Nordic_UART,编译在获得一个APP程序,复制到DFU_USB中改名为app1,便于接下来制作升级包时使用。
采用官方博客中说的版本2方式生成settings.hex文件。命令如下:(如果文件中没有按照脚本中的方式命名,请根据自己生成的文件名进行更改)
nrfutil settings generate --family NRF52840 --application app.hex --application-version 1 --bootloader-version 1 --bl-settings-version 2 settings.hex
由于我采用的硬件芯片为52840,所以命令中标红字段为nrf52840,如果是其余系列请参考下表:
setting.hex生成命令 | 对应芯片型号 |
NRF51 | nrf51系列芯片 |
NRF52810 | nrf52810 |
NRF52QFAB | nrf52820 |
NRF52 | nrf52832、nrf52833 |
NRF52840 | nrf52840 |
在执行了命令后会有结果显示如下,可以看一下start Address是否和芯片定义的地址一致,
由以上两图对比,可以看到地址一致吗,没有问题。
然后开始合成固件,脚本命令(主意文件明要和你实际的一样不会出错):
mergehex --merge bootloader_usb.hex settings.hex --output bl_temp.hex mergehex --merge bl_temp.hex app.hex s140_nrf52_7.2.0_softdevice.hex --output whole.hex
烧写hex文件命令(以nrfjprog为例),也可以用nRF connect(如果没有nRF connect请参看中文博客开发环境搭建篇进行环境搭建):
nrfjprog --eraseall -f NRF52 nrfjprog --program whole.hex --verify -f NRF52 nrfjprog --reset -f NRF52
用手机APP搜索可以看到我们蓝牙:
nrfutil pkg generate --application app1.hex --application-version 2 --hw-version 52 --sd-req 0x0100 --key-file priv.pem dfu_usb.zip
插入USB接口,确定USB端口接入,如果你是使用的DK板,那么按住按键4,紧接着复位一下,bootloader会检测到P0.25口电平,进入DFU升级模式,如果不是DK板,那么我们需要进行程序的修改,修改方式后续进行讲解。进入DFU后,你可以通过串口助手或者电脑的设备管理中查看,看到你的USB接口,记住端口号。(我的为31)
这个时候我们运行下列指令:
nrfutil dfu usb-serial -pkg dfu_usb.zip -p COM31
-b为波特率(这是一个虚拟串口)。
可以看到升级成功
使用手机APP看一下,蓝牙名称是否改变:
USB升级完成。
在运行上一步时,你可能会遇到这样的问题,等了半天,没有升级,反而给我们报了许多错,这个在老的芯片如nrf52833,52832等UART或者USB(nrf52833、52820)时可能能经常遇到。
这个时候我们可以禁止流控,减小波特率。
运行下列指令:
nrfutil dfu usb-serial -pkg dfu_usb.zip -p COM31 -fc 0 -b 9600
其中-fc 0为禁止流控,-b为波特率(这是一个虚拟串口)。
然后就可以升级成功了。
nrfutil settings generate --family NRF52840 --application app.hex --application-version 1 --bootloader-version 1 --bl-settings-version 2 settings.hex
合成固件:
mergehex --merge bootloader_uart.hex settings.hex --output bl_temp.hex mergehex --merge bl_temp.hex app.hex s140_nrf52_7.2.0_softdevice.hex --output whole.hex
烧写:
nrfjprog --eraseall -f NRF52 nrfjprog --program whole.hex --verify -f NRF52 nrfjprog --reset -f NRF52
合成升级包:
nrfutil pkg generate --application app1.hex --application-version 2 --hw-version 52 --sd-req 0x0100 --key-file priv.pem dfu_uart.zip
查看端口号:
升级:
nrfutil dfu serial -pkg dfu_uart.zip -p COM3
等待升级成功:
一样的问题,如果遇到无法升级的问题,请加上流控禁止和波特率。
命令:
nrfutil dfu serial -fc 0 -pkg dfu_uart.zip -p COM3 -b 115200