NRF52810 DFU 成功空中升级

一、使用到的工具

1、GCC交叉编译工具链

https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads

2、Make工具

https://www.gnu.org/software/make/

3、NRF命令行工具

nRF-Command-Line-Tools_10_8_0_Installer_64.exe

4、命令行烧录,需要先安装Python解释器以便安装nrfutil

python-3.8.3

二、工具安装使用

依次安装上面的软件,如果需要什么安装不了的问题可以自行google,这些软件会打包在一起以供下载。

1、安装完NRF命令行工具后,就可以在命令行使用如下 相关命令主要用到的就是如下几个:
(1)擦除
nrfjprog.exe -f NRF52 -e
(2)烧录、复位、确认等
nrfjprog.exe -f NRF52 --program xx.hex --verify --reset --chiperase
(3)固件合并
 mergehex.exe -m  A.hex B.hex C.hex -o D.hex

把A、B、C三个固件合并成一个D固件。

2、安装完Make工具和gcc交叉编译工具链,就可以编译生成后续DFU 升级需要使用到的micro_ecc_lib_nrf52.lib

具体步骤如下:
(1)先进入到SDK下C:\Users\EDZ\Desktop\nRF5_SDK_16.0.0_98a08e2\external\micro-ecc的目录,双击执行build_all.bat,执行完后该目录会多一个micro-ecc文件夹。这个脚本的作用是从github下载micro-ecc工程,然后分别编译各个平台下使用到的micro_ecc_lib_nrf52.lib库文件。这个时候会发现报错闪退,找不到交叉编译工具链.
解决方法:到C:\Users\EDZ\Desktop\nRF5_SDK_16.0.0_98a08e2\components\toolchain\gcc下修改Makefile.windows里面的内容把GNU_INSTALL_ROOT := xxx
交叉编译工具链的路径改成你安装的交叉编译工具链的路径,我的配置如下:

GNU_INSTALL_ROOT := C:/Program Files (x86)/GNU Arm Embedded Toolchain/9 2020-q2-update/bin/
GNU_VERSION := 7.3.1
GNU_PREFIX := arm-none-eabi

(2)重新配置ok后,再执行一次build_all.bat脚本,就可以在相应的目录生成相关平台使用到的库文件micro_ecc_lib_nrf52.lib

三、工程编译

(1)bootloader工程
C:\Users\EDZ\Desktop\example\examples\dfu\secure_bootloader\pca10040e_s112_ble

编译该工程会出现以下报错信息:

..\..\..\dfu_public_key.c(20): error:  #35: #error directive: "Debug public key not valid for production. Please see https://github.com/NordicSemiconductor/pc-nrfutil/blob/master/README.md to generate it"
  #error "Debug public key not valid for production. Please see https://github.com/NordicSemiconductor/pc-nrfutil/blob/master/README.md to generate it"
..\..\..\dfu_public_key.c: 0 warnings, 1 error

解决方法:
这个时候之前安装好的python解释器就派上用场了,进入cmd命令行执行pip install nrfutil,安装成功后,接下来生成我们工程使用的公钥。
命令行执行:

nrfutil keys generate private.pem
nrfutil keys display --key pk --format code private.pem --out_file dfu_public_key.c

把生成的dfu_public_key.c替换C:\Users\EDZ\Desktop\example\examples\dfu下的dfu_public_key.c,重新编译一次就没有错误了,这时候我们的bootloader就有了,我们把这个固件重命名成boot.hex。

(2)带DFU的工程
C:\Users\EDZ\Desktop\example\examples\ble_peripheral\ble_app_buttonless_dfu\pca10040e\s112

编译完这个工程这个时候我们就有了带dfu的工程,接下来就可以用这个dfu的固件制作升级包,同样把这个固重命名成app.hex。

四、制作升级包

命令行执行:

nrfutil pkg generate --hw-version 52 --sd-req 0xCD --application-version 1 --application app.hex  --key-file private.pem app_dfu_package.zip

a. --hw-version:硬件版本,如果是52系列设置为52,51系列设置为51
b. --sd-req 0xCD:协议栈(SoftDevice)ID,应输入使用的协议栈版本对应的ID,该ID可以在命令行直接使用nrfutil.exe pkg generate --help查到,由于我使用的是协议栈是s112_nrf52_7.0.1,它对应的ID就是0xCD。

五、固件合并,生成带DUF的bootloader

命令行:

mergehex.exe -m  .\boot.hex .\s112_nrf52_7.0.1_softdevice.hex  -o bootsd.hex

把boot.hex和协议栈.hex固件合并成bootsd.hex.

六、固件烧录

命令行:

nrfjprog.exe -f NRF52 --program .\bootsd.hex --verify --reset --chiperase

到此芯片复位重启,用nrfconnect就可以扫描到dfuTarg广播的设备,这个设备就是我们带DFU的bootloader.

七、固件升级

连接到这个名称为dfuTargDE设备,到连接界面选择DFU按钮(在DISCONNECT旁边),在弹出的界面选择类型为.zip的升级包,即到手机内选择之前制作好的升级包app_dfu_package.zip,之后就可以成功升级到app.hex固件了。重新扫描设备,发现设备的广播名称变成了Nordic_Buttonless,这时升级成功了。
到此升级算是完成了,但是。。。

八、直接跳转到App.hex运行,不需要进行一次DFU

这个时候我们需要制作bootloader的setting固件,命令行执行:

(1)生成bootloader_setting.hex
nrfutil settings generate --family NRF52 --application app.hex --application-version 0 --bootloader-version 0 --bl-settings-version 1 bootloader_setting.hex

这时生成的bootloader_setting.hex就可以用来“骗过”bootloader直接跳转到app.hex运行。。。

(2)合并固件
mergehex.exe -m .\bootloader_setting.hex .\bootsd.hex .\app.hex -o burn.hex

这里生成我们最终需要的burn.hex固件,然后开心的可以去烧录固件了。。。

(3)烧录固件
nrfjprog.exe -f NRF52 --program .\burn.hex --verify --reset --chiperase

发现卧槽居然烧录失败。。。我明显是参考官网的步骤做的,怎么会出错了,于是乎又重头来了一遍,卧槽、卧槽、卧槽还是一样的不能烧录报错

Parsing hex file.
ERROR: The file specified is not a valid hex file, has data outside valid areas
ERROR: or does not have data in valid areas.

这里的意思是说你的固件有问题,有数据超过了Flash的地址范围,怎么办呢,接线来就是翻遍官方的论坛https://devzone.nordicsemi.com/,搞了一天没有任何进展,不管怎么烧录还是上面的“暴搓”,算了不搞了下班(2020.07.31.21:30)。。。
第二天来了继续查资料翻论坛,耶,最后发现有个地方说了一段话:

The error you are getting indicates that some part of the hex file has data outside of the flash. The first step is to check each hex file before they are merged to see if there are regions outside the range 0x00000000 - 0x00040000 (you may still have data in the UICR region). This online tool can be a suitable way to do this with.
In addition to the steps you have described I noticed that you need to update the value of BOOTLOADER_START_ADDR and BOOTLOADER_SETTINGS_ADDRESS in the bootloader source code. These defines are used runtime by the MBR and bootloader and have to match the project settings.

看到最后一句BOOTLOADER_SETTINGS_ADDRESS的地址要和工程里设置的地址相同,突然灵光闪现。
我之前制作的bootloader_setting.hex信息如下:

Bootloader DFU Settings:
* File:                     setting.hex
* Family:                   nRF52
* Start Address:            0x0007F000
* CRC:                      0xB3F6314D
* Settings Version:         0x00000001 (1)
* App Version:              0x00000000 (0)
* Bootloader Version:       0x00000000 (0)
* Bank Layout:              0x00000000
* Current Bank:             0x00000000
* Application Size:         0x0000B9D0 (47568 bytes)
* Application CRC:          0x15413590
* Bank0 Bank Code:          0x00000001
* Softdevice Size:          0x00000000 (0 bytes)
* Boot Validation CRC:      0x00000000
* SD Boot Validation Type:  0x00000000 (0)
* App Boot Validation Type: 0x00000000 (0)

看到那个Start Address 怎么是0x0007F000,居然不是

C:\Users\EDZ\Desktop\example\components\libraries\bootloader\dfu\nrf_dfu_types.h

line 97行定义的那个地址,那里的地址NRF52810_XXAA对应的是0x0002F000UL,我的居然是0x0007F000,这不是NRF52832_XXAA对应的么?看下面的宏定义

/** @brief  Page location of the bootloader settings address.
 */
#if defined  (NRF51)
    #define BOOTLOADER_SETTINGS_ADDRESS     (0x0003FC00UL)
#elif defined( NRF52810_XXAA )
    #define BOOTLOADER_SETTINGS_ADDRESS     (0x0002F000UL)
#elif defined( NRF52811_XXAA )
    #define BOOTLOADER_SETTINGS_ADDRESS     (0x0002F000UL)
#elif defined( NRF52832_XXAA )
    #define BOOTLOADER_SETTINGS_ADDRESS     (0x0007F000UL)
#elif defined( NRF52833_XXAA )
    #define BOOTLOADER_SETTINGS_ADDRESS     (0x0007F000UL)
#elif defined(NRF52840_XXAA)
    #define BOOTLOADER_SETTINGS_ADDRESS     (0x000FF000UL)
#else
    #error No valid target set for BOOTLOADER_SETTINGS_ADDRESS.
#endif

于是乎把之前制作的bootloader_setting.hex改成如下:

原来:
nrfutil settings generate --family NRF52 --application app.hex --application-version 0 --bootloader-version 0 --bl-settings-version 1 bootloader_setting.hex
更新:
nrfutil settings generate --family NRF52810 --application app.hex --application-version 0 --bootloader-version 0 --bl-settings-version 1 bootloader_setting.hex

重新按照之前的步骤,合成burn.hex执行

nrfjprog.exe -f NRF52 --program .\burn.hex --verify --reset --chiperase

突然看到命令行输出:

nrfjprog.exe -f NRF52 --program .\burn.hex --verify --reset --chiperase
Parsing hex file.
Erasing user available code and UICR flash areas.
Applying system reset.
Checking that the area to write is not protected.
Programming device.
Verifying programming.
Verified OK.
Applying system reset.
Run.

板子上的灯也亮起来了。。。也可以正常DFU了。哈哈。。。。激动的泪水。。。。夸张了。不带DFU的工程移植留到下一遍再更新了。。。
2020.08.01.16:24

你可能感兴趣的:(NRF52,物联网,嵌入式,蓝牙)