nrf52——DFU升级OTA升级方式详解(基于SDK开发例程)
作者:互联网
、秘钥生成
在开发环境搭建完毕后,新建一个文件夹DFU(任意命名),在DFU中生成秘钥,打开新建文件夹后,按住Shift键2s左右单击右键选择powershell窗口,运行下面两条命令生成私钥和秘钥(必须保存好,后期升级都要用到)。
- 私钥生成命令: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就是公钥)
运行完毕后生成了如下两个秘钥文件:
二、算法库生成(micro-ecc算法库)——这算法库只需要生成一次就行。
官方的sdk从12.0开始,采取bootloader升级会先验证固件的签名,应用程序和bootloader的验证签名一致才能后续继续升级;反之失败。官方加入密匙验证的校验,需要添加算法校验lib来生成对应的key。
2.1、算法库生成环境,请参看如下连接:详解蓝牙空中升级(BLE OTA)原理与步骤 - iini - 博客园 (cnblogs.com)。在环境正确的前提下,我们打开SDK的如下目录:external\micro-ecc,可以看到如下文件和一个.bat的文件,我们只需要双击运行他就行。会自动生成算法库文件lib文件。
2.2、打开build_all.bat文件如下:
可以看到,这个文件中需要去到github上获取一个算法文件,所以需要保证你的网络良好。
(当然如果你有这个文件那么可以不用去加载,但是要把这文件放到external\micro-ecc目录下,然后可以注释掉如下图红框中的几个指令)
然后就可以运行一下build_all.bat脚本了。
特别提示:有时候如果你原本使用的是SDK17,但是有需要用到SDK15版本做DFU,这时在执行前面的过程中,发现怎么都不能在相应的工具链目录中生产.lib文件;如下图所示选择keil生成nrf52的.lib文件,在目录:external\micro-ecc\nrf52nf_keil\armgcc 下查看,运行build_all.bat并没有生如图所示.lib文件。
这个时候你可以进行如下几个操作,任选其一就行:
①、在你的cmd命令窗口中定位到external\micro-ecc目录去执行一下build_all.bat中的命令(复制粘贴运行就行),
②、或者在external\micro-ecc中按住键盘shift键后2s点击鼠标右键,在选项框中打开PowerShell窗口运行build_all.bat中的指令。
③、又或者打开build_all.bat脚本,在后面加入pause保持在运行,不要让其运行后就关闭。
运行之后,可以查看到如下报错,找不到相关工具链需要的文件,我测试的版本是缺少7 2018-q2-update文件(各位读者缺少的可能是其余文件),且查看相关报错提示的目录C:/Program Files (x86)/GNU Tools ARM Embedded下没有这个版本。
这个时候我可以去下载提示缺少的GCC编译文件,如果找不到,那么我们可以选择原本有的进行使用,那这种方式怎么做呢?
解决方式:
第一步:在编译生成.lib文件失败的SDK中的components\toolchain\gcc 目录下,有下面几个文件,由于我PC机是windows,所以我打开Makefile.windows。
第二步:更改,可以看到,这个文件确定生成.lib库时使用的gcc版本,我只要更改了和我原本SDK使用相同的版本就行,可以在相同的目录下去查看版本号,或者直接根据你的安装的版本去更改,
完成以上步骤,后直接运行build_all.bat 后在打开external\micro-ecc\nrf52nf_keil\armgcc 可以看到已经生成了.lib的库文件。
三、bootloade程序生成
3.1、把第一步生成的dfu_public_key.c替换SDK包examples\dfu路径下的自带公钥,然后打开examples\dfu\secure_bootloader目录,选择你的芯片和想要的升级方式,以及是否包括debug功能的BootLoader程序,并编译运行。芯片和SDK包对照如下表:
3.2、编译
在打开的工程中如果编译后有下列错误出现说明你SDK中没有算法库存在(继续去确定第二点SDK中的算法库是否有生成并存在):
关于这问题,上面的第二点说过算法库值需要生成一次,但是为什么你以前有升级成功,后面在经过一次时间后想要再次跑升级包生成流程还是出现这个问题呢,原因可能是你上使用SDK包和这个SDK包肯定不一样了,你下载了新版本的SDK包,或者从新解压过一个SDK包覆盖了原本那个。这时你需要从新去生成算法库文件。
如果编译没有报错,那么我们就找到生成的.hex文件,把它放到DFU文件夹中,从命名一下,可以直接复制粘贴脚本生成响应文件,也可以自己定义,记住更改名字后在执行脚本命令时要对应.
四、APP程序生成
编译application代码。请编译工程:
这一步如果仅仅是进行测试:那么我们可以直接用例程中的带有DFU的蓝牙例程进行测试,但是实际开发中如果有自己的工程,那么就需要去移植DFU功能,移植方式看官方中文博客,路径如下:详解蓝牙空中升级(BLE OTA)原理与步骤 - iini - 博客园 (cnblogs.com)
下面采用编译例程的方式进行演示:
SDK根目录 \examples\ble_peripheral\ble_app_buttonless_dfu\pca10040\s132\arm5_no_packs,将生成的hex文件改名为:app.hex ,放入DFU文件夹
五、生成BootLoader settings page
采用官方博客中说的版本2方式生成settings.hex文件。命令如下:(如果文件没有安装上面的命名,请根据自己生成的文件名进行更改)
nrfutil settings generate --family NRF52 --application app.hex --application-version 1 --bootloader-version 1 --bl-settings-version 2 settings.hex
六、原始固件烧写
这一步就是我们一个项目开发完成后,把要写到出厂产品的中固件烧写到芯片中,后期如果有需求需要去做APP升级,那么就可以通过DFU的方式升级了。
如中文博客中的方式一样运行下列命令:
6.1、将上文生成的3个hex文件和softdevice hex文件merge成一个文件,然后通过nrfjprog或者nRF Connect桌面版进行烧写,相关命令如下所示:
6.1.1、复制一个协议栈文件(softdevice hex)到DFU文件目录下,我们可以打开SDK如下目录:components\softdevice 这里有各种版本的协议栈,当然我上面编译的APP工程协议栈栈为112的6.1.1版本,如下图所示,那那么就打开找到相同名的hex文件复制大DFU目录下。
这时我们的DFU目录下有了一下这些文件:
开始合并hex文件命令:
mergehex --merge bootloader.hex settings.hex --output bl_temp.hex mergehex --merge bl_temp.hex app.hex s112_nrf52_6.1.1_softdevice.hex --output whole.hex
6.2、烧写hex文件命令(以nrfjprog为例),也可以用nRF connect(如果没有请参看中文博客开发环境搭建片):
nrfjprog --eraseall -f NRF52 nrfjprog --program whole.hex --verify -f NRF52 nrfjprog --reset -f NRF52
6.3、错误解决
错误:在使用一些版本的SDK进行DFU升级时,如果在合成安装包后,在烧写阶段出现如下错误(以nrf52810为例):
命令行方式:数据位域有效区域外,或者有效区域没有数据。
J-flash方式:不符合所选闪存扇区或不符合程序目标
然后查看生成的whole.hex文件,发现BootLoader的数据在地址0007 F000开始的地址,如下图所示,但是对于有些芯片(如nrf52810)flash只到60000,显然对于该芯片这个地址已经超过了FLASH的是存储容量,所以在烧写的时候会报错那是因为合成的最终HEX固件已经超过了flash的容量
问题解决:
在生成settings.hex文件时,更改一下生成命令:
原来的生成命令如下(执行后,默认开始地址为nrf52832的地址),也就是0x0007F000:
nrfutil settings generate --family NRF52 --application app.hex --application-version 1 --bootloader-version 1 --bl-settings-version 2 settings.hex
但是我们工程中BootLoader的地址为0x0002F000(对于nrf52810)
针对于这个问题,只要修改一下生成BootLoader文件的指令即可:如下为nrf52810的,那如果是其余系列的芯片有相关问题,解决方式一样,在生成BootLoader时把默认的NRF52,改为NRF52xxx即可。
nrfutil settings generate --family NRF52810 --application app.hex --application-version 1 --bootloader-version 1 --bl-settings-version 2 settings.hex
命令执行后可以看到执行情况如下,开始地址已经变为和工程中一样适用于nrf52810的地址,然后在去下载就不会报错了。
针对以上这类问题,如你发现在下载时使用6.2所列出的烧写命令居然不能进行烧写,那么你可以尝试把nrf52改为nrf52xxx(对应的芯片型号)进行测试。
下载固件到芯片后可以用nRF connect手机版搜索到我们的设备,连接后有如图所示的界面,可以看到右上角有一个DFU的图标,说明我们的原始固件具有了DUF功能。
7、固件升级
7.1、新固件升级包合成
如果要进行新固件的升级,那么就需要准备好一个.zip升级包,然后在利用手机APP进行升级。那这个.zip如何进行生成呢?下面我们就来一步一步的的进行,
7.1.1、生成新的APP程序
因为我这是做测试,就只改变一下设备的名字,把名字改为“Nordic_DFU_NEW”,然后编译工程,找到新生成的HEX文件复制到我们的DFU文件夹,重命名为app_new.hex;
7.1.2、确定协议栈版本号
在SDK的components\softdevice目录下,有各个版本协议栈的资料,我们根据自己使用的版本来选择确定值,我使用的是s112的版本,所以在如下目录下components\softdevice\s112\doc有一个PDF文档,我们打开该文档,可以看到如图所示的协议栈版本号:
所以在如下命令中我使用的协议栈版本号,要设置为00B8,所以在开发自己的DFU例程时,要根据使用的协议栈去确定生成.zip 升级包命令中的协助栈版本号是什么,如果出错,你 会发现,不管怎么升级,你的新固件都是无法升级成功并运行的。
7.1.3、升级包合成
升级包生成命令如下,请修改版本号为你使用的协议栈版本号:
nrfutil pkg generate --application app_new.hex --application-version 2 --hw-version 52 --sd-req 0x00B8 --key-file priv.pem app_s112_new.zip
运行命令后你会发现在DFU文件夹中生成了一个app_s112_new.zip压缩包,这就是我们要通过手机APP发给我们设备的升级包
7.2、升级
先把7.1步骤生成的固件包上传个手机,然后打开手机APP,我使用的是nordic官方APP(nrf connect),然后连接好设备然后点击DFU的升级标识。
然后在接下来的界面选择ZIP升级方式,然后点击OK。
然后在手机中找到发个手机的ZIP升级压缩包并确定:
接下来你会看到我们的升级界面:
升级完成后,复位一下设备,我们重新在手机APP上搜索一下,可以发现蓝牙广播名已经变为我们新固件的名字了:
到此,升级完毕!
标签:DFU,文件,例程,hex,生成,升级,--,SDK 来源: https://www.cnblogs.com/HW-liu/p/16207737.html