• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

nrf52——DFU升级OTA升级模式(基于SDK开发例程)


Recommended Posts

密钥生成

开发环境构建完成后,创建一个新文件夹DFU(任意命名),并在DFU生成密钥。打开新文件夹后,按住Shift键2s右键选择powershell窗口,运行以下两个命令生成私钥和秘钥(一定要保存好,以备后期升级使用)。

Generate private key命令:nrutil keys生成priv.pem (priv.pem是私钥)

生成公钥的命令:nrfutil keys display-key PK-format code priv . PEM-out _ filedfu _ public _ key . c(dfu _ public _ key . c为公钥)

运行后,将生成以下两个密钥文件:

in3emugybce6134.png

二、算法库生成(微ecc算法库)3354这个算法库只需要生成一次。

官方sdk从12.0开始,bootloader升级会先验证固件的签名,后续升级前应用和bootloader的验证签名一致;否则,它会失败。要添加官方密钥验证,需要添加算法验证库,生成相应的密钥。

2.1.算法库生成环境请参考以下连接:详细讲解蓝牙空中升级(BLE OTA)的原理和步骤-iini-Blog Park (cnblogs.com)。在环境正确的前提下,我们打开SDK的以下目录:external\micro-ecc,可以看到以下文件和一个. bat文件。我们只需要双击运行它。算法库文件lib文件将自动生成。

1qsohjk0v0t6135.png

2.2.打开build_all.bat文件,如下所示:

5dqx2hya1rp6136.png

如你所见,这个文件需要去github获取一个算法文件,所以你需要确保你的网络是好的。

(当然如果你有这个文件,就不需要加载了,但是要放在external\micro-ecc目录下,然后可以在下面的红框里注释掉几条指令)

fuwgcxkmpau6137.png

然后就可以运行build_all.bat脚本了。

特别说明:有时候,如果你本来用的是SDK17,但是需要用SDK15版本制作DFU,那么在前面的流程执行过程中,你发现你无法制作。对应工具链目录中的lib文件;如下图所示选择keil以生成。nrf52的lib文件。在目录中查看:external \ micro-ECC \ NRF 52 nf _ Keil \ arm gcc。运行build_all.bat不会生成。lib文件如图所示。

qiizp0fa5wi6138.png

此时,您可以进行以下操作,只需选择其中一项:

在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中也没有这个版本,可以在那里查看相关的错误提示。

" height="143" loading="lazy" src="https://www.icode9.com/i/l/?n=22&i=blog/2623060/202204/2623060-20220429170815803-1070053705.png" width="932"/>

这个时候我可以去下载提示缺少的GCC编译文件,如果找不到,那么我们可以选择原本有的进行使用,那这种方式怎么做呢?

解决方式:

第一步:在编译生成.lib文件失败的SDK中的components\toolchain\gcc 目录下,有下面几个文件,由于我PC机是windows,所以我打开Makefile.windows。

e5kfpsixnzq6139.png

 第二步:更改,可以看到,这个文件确定生成.lib库时使用的gcc版本,我只要更改了和我原本SDK使用相同的版本就行,可以在相同的目录下去查看版本号,或者直接根据你的安装的版本去更改,

rkwnvpjqsmq6140.png

 完成以上步骤,后直接运行build_all.bat 后在打开external\micro-ecc\nrf52nf_keil\armgcc  可以看到已经生成了.lib的库文件。

3atxymqzudr6141.png

三、bootloade程序生成

 3.1、把第一步生成的dfu_public_key.c替换SDK包examples\dfu路径下的自带公钥,然后打开examples\dfu\secure_bootloader目录,选择你的芯片和想要的升级方式,以及是否包括debug功能的BootLoader程序,并编译运行。芯片和SDK包对照如下表:

rxpq45pwsdn6142.png 

3.2、编译

在打开的工程中如果编译后有下列错误出现说明你SDK中没有算法库存在(继续去确定第二点SDK中的算法库是否有生成并存在):

gorptoe0wyn6143.png

 关于这问题,上面的第二点说过算法库值需要生成一次,但是为什么你以前有升级成功,后面在经过一次时间后想要再次跑升级包生成流程还是出现这个问题呢,原因可能是你上使用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目录下。

snc3w3hh4cz6144.png

 这时我们的DFU目录下有了一下这些文件:

wzce3t4trj46145.png

开始合并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为例):

命令行方式:数据位域有效区域外,或者有效区域没有数据。

ievgijby2jr6146.png

 

 

 J-flash方式:不符合所选闪存扇区或不符合程序目标

oosgypfrv406147.png

 

 

 然后查看生成的whole.hex文件,发现BootLoader的数据在地址0007 F000开始的地址,如下图所示,但是对于有些芯片(如nrf52810)flash只到60000,显然对于该芯片这个地址已经超过了FLASH的是存储容量,所以在烧写的时候会报错那是因为合成的最终HEX固件已经超过了flash的容量

3qcbopp1e3q6148.png

 

 

 问题解决:

在生成settings.hex文件时,更改一下生成命令:

原来的生成命令如下(执行后,默认开始地址为nrf52832的地址),也就是0x0007F000:

nrfutil settings generate --family NRF52 --application app.hex --application-version 1 --bootloader-version 1 --bl-settings-version 2 settings.hex

0r0geyhlgt56149.png

 

 

 但是我们工程中BootLoader的地址为0x0002F000(对于nrf52810)

hv0cypaaro56150.png

 

 

 针对于这个问题,只要修改一下生成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的地址,然后在去下载就不会报错了。

z25blghrum56151.png

 

 

 针对以上这类问题,如你发现在下载时使用6.2所列出的烧写命令居然不能进行烧写,那么你可以尝试把nrf52改为nrf52xxx(对应的芯片型号)进行测试。

 下载固件到芯片后可以用nRF connect手机版搜索到我们的设备,连接后有如图所示的界面,可以看到右上角有一个DFU的图标,说明我们的原始固件具有了DUF功能。

irarztghobg6152.png

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文档,我们打开该文档,可以看到如图所示的协议栈版本号:

vvo2x2wj3pr6153.png

 

 

 所以在如下命令中我使用的协议栈版本号,要设置为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发给我们设备的升级包

oeydjucep1j6154.png

 

 7.2、升级

先把7.1步骤生成的固件包上传个手机,然后打开手机APP,我使用的是nordic官方APP(nrf connect),然后连接好设备然后点击DFU的升级标识。

irarztghobg6152.png

然后在接下来的界面选择ZIP升级方式,然后点击OK。

gqm0v1ab2s06155.png

 

 然后在手机中找到发个手机的ZIP升级压缩包并确定:

dysejf3ojqw6156.png

 

 接下来你会看到我们的升级界面:

vqfr1s4suj46157.png

 

 升级完成后,复位一下设备,我们重新在手机APP上搜索一下,可以发现蓝牙广播名已经变为我们新固件的名字了:

ox25l2hzoni6158.png

 

 到此,升级完毕!

 

Link to comment
Share on other sites