Secure DFU环境搭建

升级原理,加密原理在此不做描述,详情参考http://www.cnblogs.com/iini/p/9314246.html


1.工具一览

  • gcc-arm-none-eabi编译环境:GCC编译环境

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

  • mingw 平台(win版的Linux命令行)

https://sourceforge.net/projects/mingw/files/latest/download?source

  • micro-ecc-master源码

https://github.com/kmackay/micro-ecc

  • python 安装文件

https://www.python.org/downloads/

  • pc-nrfutil

https://github.com/NordicSemiconductor/pc-nrfutil/

  • nrfgo-studio
  • nrf connect app

2.安装指导

Secure DFU需要micro-ecc库进行签名验证,需要micro_ecc_lib_nrf52.lib,需要使用GCC编译器生成。

2.1 gcc-arm-none-eabi安装

gcc-arm-none-eabi-4_9-2015q3-20150921-win32.exe,直接双击安装,注意使用默认安装路径,不要修改

安装完成


2.2 mingw 平台安装

双击mingw-get-setup.exe,点击install进行安装,选择默认路径

安装好后弹出package包安装界面MinGW Installation Manager,按下图所示进行选择

选择后,点击InstallationàApply Changes


2.3 mingw 环境变量配置

安装好MinGW,需要在系统环境变量Path添加路径

平台安装验证:

修改好系统环境变量后,重启电脑,运行命令提示符,如下所示则安装成功


2.4 micro-ecc库生成

需要生成micro_ecc_lib_nrf52.lib,也可直接使用已经编译好的文件micro-ecc_sdk14_15_newer.rar解压后替换micro-ecc文件夹。

1.将micro-ecc-master源码复制到SDK目录下的external\micro-ecc中,并重命名为micro-ecc

2.打开MinGW的命令行msys.bat

在批处理框里输入要生成库的gcc算法路径

cd E:/keil_workspace/NORDIC/nRF5_SDK_15.0.0_a53641a/external/micro-ecc/nrf52hf_keil/armgcc

之后输入make

出现错误后,按照提示修改gcc的Makefile.windows文件如下

将gcc编译器路径更换为实际路径

#GNU_INSTALL_ROOT := C:/Program Files (x86)/GNU Tools ARM Embedded/6 2017-q2-update/bin/

GNU_INSTALL_ROOT := C:/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q3/bin/

#GNU_VERSION := 6.3.1

GNU_VERSION := 6.3.0

GNU_PREFIX := arm-none-eabi

修改之后,编译OK


2.5 python 安装

1.双击python-2.7.14.amd64.msi安装,注意使用默认路径,安装过程使用默认插件配置直接一直next。

2.系统环境变量添加

3.安装验证

修改环境变量后重启电脑,命令行输入python -V


2.6 nrfutil工具安装

需要联网

打开命令行,输入pip install nrfutil安装nrfutil

安装完成后,输入nrfutil version,如下则表示安装成功


3.升级文件制作

为便于调试与生产上的烧录,编写一些 bat 文件来操作nrfutil工具指令

工程在sdk中的目录 E:\keil_workspace\NORDIC\nRF52832_htwh_sdk15.0\examples\ble_peripheral\ble_app_gnt_freertos-release

脚本文件目录 E:\keil_workspace\NORDIC\nRF52832_htwh_sdk15.0\examples\ble_peripheral\ble_app_gnt_freertos-release\wh_Script_SDK15_S132_nRF52832_GNT

3.1 密钥生成文件

key_generate.bat

生成的 dfu_public_key.c 文件会拷贝到 dfu 文件夹下供 secure_bootloader 使用

  1. @echo off
  2.  
  3. pause
  4. echo "执行之前需要确认文件路径,修改完成后可注释..."
  5. pause
  6.  
  7. ::1)通过nrfutil生产私钥和公钥文件
  8. ::generate private key
  9. nrfutil keys generate priv.pem
  10. ::generate public key related with private key: priv.pem
  11. nrfutil keys display --key pk --format code priv.pem --out_file dfu_public_key.c
  12.  
  13. ::2)复制dfu_public_key.c文件到dfu工程
  14. ::修改指定文件夹或文件自己修改ObjPath源文件位置,HexDestPath目标文件或文件夹位置
  15. set ObjPath=dfu_public_key.c
  16.  
  17. set HexDestPath=E:\keil_workspace\NORDIC\nRF52832_htwh_sdk15.0\examples\dfu
  18.  
  19. ::复制指定路径指定文件或文件夹,至HexDestPath路径文件夹
  20. echo y | xcopy "%ObjPath%" /e /r /k "%HexDestPath%"
  21. ::xcopy /e/c/h/z "%~pd0*.*" "%out%"
  22.  
  23. pause

3.2 升级包制作bat文件

zip_generate.bat

文件中的工程目录请根据实际路径修改

  1. @echo off
  2.  
  3. ::1)复制工程hex文件到指定文件夹, 需设置文件地址
  4. ::修改指定文件夹或文件自己修改ObjPath源文件位置,HexDestPath目标文件或文件夹位置
  5. set ObjPath=E:\keil_workspace\NORDIC\nRF52832_htwh_sdk15.0\examples\ble_peripheral\ble_app_gnt_freertos-release\pca10040\s132\arm5_no_packs\_build\gnt_app.hex
  6.  
  7. set HexDestPath=E:\keil_workspace\NORDIC\nRF52832_htwh_sdk15.0\examples\ble_peripheral\ble_app_gnt_freertos-release\wh_Script_SDK15_S132_nRF52832_GNT
  8.  
  9. ::复制指定路径指定文件或文件夹,至HexDestPath路径文件夹
  10. echo y | xcopy "%ObjPath%" /e /r /k "%HexDestPath%"
  11. ::xcopy /e/c/h/z "%~pd0*.*" "%out%"
  12.  
  13. ::2)生成升级用zip文件
  14. ::nrfutil.exe pkg generate --hw-version 52 --application-version 1 --application gnt_app.hex --sd-req 0xA8 --key-file private.key gnt_app_Dfu15.zip
  15.  
  16. nrfutil pkg generate --hw-version 52 --application-version 1 --application gnt_app.hex --sd-req 0xA8 --key-file private.key gnt_app_Dfu15.zip
  17.  
  18. ::pause

3.2 生产烧录文件制作bat文件

会将应用gnt_app.hex、bootloader.hex、settings.hex、s132_nrf52_6.0.0_softdevice.hex这四个程序合为whole.hex,用于生产烧录;

mergehex.bat

  1. @echo off
  2.  
  3. ::1)生成 settings page for current image: gnt_app.hex
  4. ::Bootloader settings存储在Flash最后一个page,它将决定复位后芯片的行为,比如是进入DFU模式还是应用模式,同时它还包含imageCRC值和版本等信息。如果要求芯片复位后进入application,必须正确生成该bootloader settings hex
  5.  
  6. nrfutil settings generate --family NRF52 --application gnt_app.hex --application-version 1 --bootloader-version 1 --bl-settings-version 1 settings.hex
  7.  
  8. ::2)合成一个hex用于生产烧录
  9. ::merge bootloader and settings
  10. mergehex.exe --merge bootloader.hex settings.hex --output bl_temp.hex
  11. ::merge bootloader, app and softdevice
  12. mergehex.exe --merge bl_temp.hex gnt_app.hex s132_nrf52_6.0.0_softdevice.hex --output whole.hex
  13.  
  14. ::pause
  15.  
  16. ::merge bootloader and settings

4.工程添加DFU服务

1.工程文件

工程文件添加

头文件路径包含

2.工程内容修改

在main.c中添加 DFU 服务支持

  1. // 头文件包含
  2. #if (DFU_SUPPORT == 1)
  3. #include "nrf_dfu_ble_svci_bond_sharing.h"
  4. #include "nrf_svci_async_function.h"
  5. #include "nrf_svci_async_handler.h"
  6. #include "ble_dfu.h"
  7. #include "nrf_power.h"
  8. #include "nrf_bootloader_info.h"
  9. #endif
  10.  
  11. #if (DFU_SUPPORT == 1)
  12.  
  13. // 进入DFU,应用关机之前的一些操作,注册到power manager电源管理中
  14. static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event)
  15. {
  16. switch (event)
  17. {
  18. case NRF_PWR_MGMT_EVT_PREPARE_DFU:
  19. NRF_LOG_INFO("Power management wants to reset to DFU mode.");
  20. #if (GNT_WDT_EN == 1)
  21. my_wdt_feed();
  22. #endif
  23.  
  24. break;
  25.  
  26. default:
  27. // YOUR_JOB: Implement any of the other events available from the power management module:
  28. // -NRF_PWR_MGMT_EVT_PREPARE_SYSOFF
  29. // -NRF_PWR_MGMT_EVT_PREPARE_WAKEUP
  30. // -NRF_PWR_MGMT_EVT_PREPARE_RESET
  31. return true;
  32. }
  33.  
  34. NRF_LOG_INFO("Power management allowed to reset to DFU mode.");
  35. return true;
  36. }
  37.  
  38. // 注册应用关机事件处理函数(常用于关机前需要进行的一些操作:如flash操作,控制模块的关闭等)
  39. NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);
  40.  
  41. static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context)
  42. {
  43. if (state == NRF_SDH_EVT_STATE_DISABLED)
  44. {
  45. NRF_LOG_INFO("NRF_SDH_EVT_STATE_DISABLED to DFU mode.");
  46. // Softdevice was disabled before going into reset. Inform bootloader to skip CRC on next boot.
  47. nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);
  48.  
  49. //Go to system off.
  50. nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
  51. }
  52. }
  53.  
  54. /* nrf_sdh state observer. */
  55. NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) =
  56. {
  57. .handler = buttonless_dfu_sdh_state_observer,
  58. };
  59.  
  60. #endif
  61.  
  62. #if (DFU_SUPPORT == 1)
  63. /**@brief Function for handling dfu events from the Buttonless Secure DFU service
  64. *
  65. * @param[in] event Event from the Buttonless Secure DFU service.
  66. */
  67. static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)
  68. {
  69. switch (event)
  70. {
  71. case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
  72. NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
  73. // YOUR_JOB: Disconnect all bonded devices that currently are connected.
  74. // This is required to receive a service changed indication
  75. // on bootup after a successful (or aborted) Device Firmware Update.
  76. break;
  77.  
  78. case BLE_DFU_EVT_BOOTLOADER_ENTER:
  79. // YOUR_JOB: Write app-specific unwritten data to FLASH, control finalization of this
  80. // by delaying reset by reporting false in app_shutdown_handler
  81. NRF_LOG_INFO("Device will enter bootloader mode.");
  82. break;
  83.  
  84. case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
  85. NRF_LOG_ERROR("Request to enter bootloader mode failed asynchroneously.");
  86. // YOUR_JOB: Take corrective measures to resolve the issue
  87. // like calling APP_ERROR_CHECK to reset the device.
  88. break;
  89.  
  90. case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
  91. NRF_LOG_ERROR("Request to send a response to client failed.");
  92. // YOUR_JOB: Take corrective measures to resolve the issue
  93. // like calling APP_ERROR_CHECK to reset the device.
  94. APP_ERROR_CHECK(false);
  95. break;
  96.  
  97. default:
  98. NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
  99. break;
  100. }
  101. }
  102. #endif
  103.  
  104. static void services_init(void)
  105. {
  106. ret_code_t err_code;
  107. nrf_ble_qwr_init_t qwr_init = {0};
  108.  
  109. // Initialize Queued Write Module.
  110. qwr_init.error_handler = nrf_qwr_error_handler;
  111.  
  112. err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
  113. APP_ERROR_CHECK(err_code);
  114.  
  115. // 添加GPS_NB_TAG服务
  116. ble_gnts_init_t gnts_init;
  117.  
  118. memset(&gnts_init, 0, sizeof(gnts_init));
  119. gnts_init.data_handler = gnts_data_handler;
  120.  
  121. err_code = ble_gnts_init(&m_gnts, &gnts_init);
  122. APP_ERROR_CHECK(err_code);
  123.  
  124. #if (DFU_SUPPORT == 1)
  125. ble_dfu_buttonless_init_t dfus_init = {0};
  126. // Initialize the async SVCI interface to bootloader.
  127. err_code = ble_dfu_buttonless_async_svci_init();
  128. APP_ERROR_CHECK(err_code);
  129.  
  130. dfus_init.evt_handler = ble_dfu_evt_handler;
  131.  
  132. err_code = ble_dfu_buttonless_init(&dfus_init);
  133. APP_ERROR_CHECK(err_code);
  134. #endif
  135.  
  136. }

3. sdk_config.h 文件设置


另外 bootloader 工程中需要设置进入boot方式

5. 实际测试

用keil编译工程之后,运行bat文件生成升级用 zip 包

连接设备蓝牙

1.使能Buttonless DFU的CCCD项;

2.点击按键2

点击SEND,设备进入boot模式,关闭当前连接,进入扫描项SCAN,连接DfuTrag

点击右上角的DFU小图标,选择ZIP文件(SDK12之后仅支持ZIP格式升级),点击OK,进入文件浏览器选择升级文件后自动开始升级,到100%时升级完成。

NRF52832空中升级DFU的更多相关文章

  1. NRF51800 空中升级DFU

    下面是基础软件的安装:[抄袭他人所得] 1.安装Python软件,建议版本2.7.9及以上,不超过3.0版本[以下安装步骤需要联网]2.安装Python的pip模块,通过命令提示符进入到Python的 ...

  2. 如何实现蓝牙空中升级BLE OTA

    如何实现BLE OTA?什么叫DFU?如何通过UART实现固件升级?又如何通过USB实现固件升级?怎么保证升级的安全性?什么叫双备份(dual bank)DFU?什么叫单备份(single bank) ...

  3. nRF Connect SDK(NCS)/Zephyr固件升级详解 – 重点讲述MCUboot和蓝牙空中升级

    如何在nRF Connect SDK(NCS)中实现蓝牙空中升级?MCUboot和B0两个Bootloader有什么区别?MCUboot升级使用的image格式是怎么样的?什么是SMP协议?CBOR编 ...

  4. BLE空中升级 谈(二)

    BLE 空中升级谈 -- CC2541 的产品开发中OAD注意事项(续) TI CC2541支持多个硬件,多个软件对它进行空中升级,可以有不同的组合,硬件有 编号 名称 Hex 用法 1 Cc2540 ...

  5. BLE空中升级 谈(一)

    BLE 空中升级谈 -- CC2541 的产品开发中OAD注意事项 现在的智能设备(可穿戴,智能家居,智能玩具等)是越来越多了,大公司的产品颜值高,功能强大而完备的应该说是比比皆是,这里不谈论它是满足 ...

  6. iOS蓝牙空中升级(固件升级)

    空中升级又叫固件升级,指你手机从服务器下载下来的包或者数据,通过蓝牙传输给你的外设升级固件.如果你能把蓝牙的基础搞懂,其实也并不是很难,我在这里只不过提供一下思路. 空中升级略难的地方在于数据处理和交 ...

  7. nRF52832 BLE_DFU空中升级OTA(三)准备升级工程(SDK14.2.0)

    准备需要加入DFU功能的工程 在工程main文件services_init函数中加入DFU服务 uint32_t err_code; // Initialize the async SVCI inte ...

  8. nRF52832 BLE_DFU空中升级OTA(二)编译下载(SDK14.2.0)

    上一篇配置好了开发环境,现在就可以试着跑一下例程了,这里需要两个例程,一个是bootloader的,一个是应用程序的,其路径分别为: bootloader:SDK_14.2.0工程\examples\ ...

  9. nRF52832 BLE_DFU空中升级OTA(一)安装软件(SDK14.2.0)

    准备工作,需要安装好几个软件,详细的过程请参考下面的文章(http://www.cnblogs.com/iini/p/9314246.html)这里说的非常详细,而且也有工具在云盘,对于初学者非常友好 ...

随机推荐

  1. GhostScript 沙箱绕过(命令执行)漏洞(CVE-2018-16509)

    影响范围: Ghostscript 9.24之前版本 poc地址 https://github.com/vulhub/vulhub/blob/master/ghostscript/CVE-2018-1 ...

  2. Drupal 远程代码执行漏洞(CVE-2019-6339)

    影响版本 Drupal core 7.62之前的7.x版本.8.6.6之前的8.6.x版本和8.5.9之前的8.5.x版本 poc https://github.com/thezdi/PoC/blob ...

  3. Java代码中,如何监控Mysql的binlog?

    最近在工作中,遇到了这样一个业务场景,我们需要关注一个业务系统数据库中某几张表的数据,当数据发生新增或修改时,将它同步到另一个业务系统数据库中的表中. 一提到数据库的同步,估计大家第一时间想到的就是基 ...

  4. 京东购物小程序 | Taro3 项目分包实践

    背景 京东购物小程序作为京东小程序业务流量的主要入口,承载着许多的活动和页面,而很多的活动在小程序开展的同时,也会在京东 APP 端进行同步的 H5 端页面的投放.这时候,一个相同的活动,需要同时开发 ...

  5. Vulnhub -- DC3靶机渗透

    @ 目录 信息收集 尝试攻击 获取shell方法1 获取shell方法2 获取shell方法3 拿到root权限 拿FLAG 总结 信息收集 kali的ip为192.168.200.4,扫描出一个IP ...

  6. PWN——ret2dl_resolve

    PWN--ret2dl_resolve ret2dl_resolve是栈溢出中,底层且高级的一种利用手段,这里特此做一篇笔记学习一下. 个人认为,要掌握这种方法,自己去写demo来多次调试分析是不二法 ...

  7. Android Jetpack 架构组件最佳实践之“网抑云”APP

    背景 近几年,Android 相关的新技术层出不穷.往往这个技术还没学完,下一个新技术又出来了.很多人都是一脸黑人问号? 不少开发者甚至开始哀嚎:"求求你们别再创造新技术了,我们学不动了!& ...

  8. 多次面试被拒,‘宅家苦修’30天,终获美团offer(含字节跳动/阿里/腾讯等大厂面试题整理)

    背景:双非渣本. 今年由于疫情,上半年一直在家里.2月份本来无忧无虑,呆在家里不给国家添乱的时候,发现身边的同学找到了大厂的offer.心里开始有点慌张.本来想在3月份如果能回到学校,就开始考研之路, ...

  9. MySQL-16-主从复制进阶

    延时从库 介绍 延时从库: 是我们人为配置的一种特殊从库,人为配置从库和主库延时N小时 为什么要有延时从库 数据库故障 物理损坏,普通的主从复制非常擅长解决物理损坏 逻辑损坏,普通主从复制没办法解决逻 ...

  10. shell 获取当前路径 和 2>&1 &的作用

    #!/bin/bash current_path=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) nohup $curren ...