51822 SDK10-DFU功能增加密码认证功能

在51822中增加buttonless DFU功能是必不可少的过程。但是很多教程中都只是简单介绍了如何在APP中增加DFU的service;如何利用BOOTLOADER加载新的app,其实这些都是现成的实例程序。但是对于一个产品来讲,不能让所有的代码都可以轻松的对你的产品做升级,这样的产品很容易被攻击成一个无用的转头。所以我把这两天看到的资料做个整理,记录一下。
下面介绍之前,有些概念内容需要先了解的,否则这些内容是看不明白的;

  1. 环境介绍:
    1.1 KEIL5
    1.2 SDK10 SD8.0.0
    1.3 nrf51822qfaa
  2. 首先使用了现成bootloader例子程序;并且使用了HRM例子,含有DFU的service;
  3. 使用手机端nrftoolbox 作为控制端
  4. 首先需要了解DFU 的profile http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk51.v10.0.0%2Fbledfu_transport.html&cp=4_0_10_4_3_1_4 文章中详细讲解了control端和target端,如何触发DFU功能,触发后如何进入bootloader并开始交互数据的。
  5. 需要了解官方文档介绍的safety-checking 的功能和含义 http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk51.v10.0.0%2Fbledfu_example_init.html
  6. 对上面的文章大致内容做个基本介绍;
    在升级NRF51IC的应用程序时,需要一个混合有初始包的镜像文件(固件文件),在使用工具对设备升级时,将对初始包的内容做判断,检测内容是否有效,并确定是否开始做升级功能。
    初始化包包含有以下内容:
    ·Device type: 设备类型,有两个字节数据组成,用于制定开发这的设备类型,可以自定义。
    ·Device revision: 设备修订,有两个字节数据组成,用于限制只能有修订的设备用于升级服务。
    ·Supported SoftDevices: 支持的SD版本类型,有个固定的SD列表对应SD的版本。
    SoftDevice FWID
    S110 v7.0.0 0x004F
    S110 v7.1.0 0x005A
    S110 v8.0.0 0x0064
    S120 v2.0.0 0x0060
    S130 v1.0.0 0x0067
    S310 v2.0.0 0x005D
    Development/any 0xFFFE
    ·Checksum 两个字节的CRC-16-CCITT校验。

下图是一个初始包包含的内容:


DFU init packet.png

这篇文章后面介绍了上面对应的数组是在UICR的寄存器中存储;但是没有介绍如何将固定的数据写入到UICR中。也没有提到这个机制是如何工作的。例如到今后的批量生产,如何快速将这些UICR初始化为需要的值等等。
在网上也找过一些资料,但是很少。基本没有提到这类功能的说明,只看到一篇国内转载过来的文章吧(因为全是E文),however,我根据这篇文章得到一个新的思路,抛弃之前使用UICR寄存器的想法,直接用宏定义的方式定义固定值,并判断这些值是否符合要求,从而确定是否启动升级。

修改位置: 在自己bootloader的工程下找到 dfu_init_template.c, 目录可以根据下面提示查找

The nRF51 SDK provides a template, dfu_init_template.c,
 to perform safety checks of the init packet. 
The template is located in the \bootloader_dfu folder.
 If you are using Keil packs, the default 
 is C:\Keil\ARM\Pack\NordicSemiconductor\nRF_Libraries\.
 If you are using the repository distribution variant of the SDK, 
 is \components\libraries.

在 dfu_init_template.c中增加或者修改

   #define  APP_VERSION_PASSWORD    ((uint32_t)0x03734301)
   #define  DEV_REVISION            ((uint16_t)0x1234)
   #define  DEV_TYEP                ((uint16_t)0x2345)
     /*agatha: set application version check*/ 
  if (p_init_packet->app_version!= APP_VERSION_PASSWORD)
    {
        return NRF_ERROR_INVALID_DATA;
    }/*app_version check*/ 
  if (DFU_DEVICE_INFO->device_rev!= DEV_REVISION)
    {
        return NRF_ERROR_INVALID_DATA;
    }/*dev_revision check*/  
  if (DFU_DEVICE_INFO->device_type!= DEV_REVISION)
    {
        return NRF_ERROR_INVALID_DATA;
    }/*dev_type check*/

重新对BOOTLOAD编译,然后使用NRFGO工具对设备重新烧写,SD,BOOTLOAD和APP;

然后使用nrfutil 工具在打包时将对应的密码或者初始包信息写入

cd C:\Program Files (x86)\Nordic Semiconductor\Master Control Panel\3.10.0.14\nrf\
nrfutil.exe dfu genpkg --nRF51422_xxac_s110.bin --application-version 0x03734301 --dev-revision 0xFFFF --dev-type 0x1618 --sd-req 100 app_version_password.zip

生成的ZIP文件可以解压后观察内部初始包信息是否正确


DFU init packet 内容.png

遗留问题:

  1. 根据官方文档,我还没有搞明白,如何将初始包信息写到UICR寄存器中。如何使用方便简洁的方法用于批量生产;
  2. 和这片文章关系不大的问题。在Hrm例子中, dfu_start()函数中,对使用函数重启芯片,并将启动地址指向了bootloader的地址,但是我在整个工程文件中没有找到bootloader的地址是多少?是如何赋值的?在哪里?
    bootloader_util_app_start(NRF_UICR->BOOTLOADERADDR);
  3. 引用文章内容地址:https://blog.csdn.net/agathakuan/article/details/54572470

你可能感兴趣的:(51822 SDK10-DFU功能增加密码认证功能)