[分享] 如何实现蓝牙空中升级BLE OTA(一)
1531 查看
5 回复
 楼主 | 发布于 2019-04-29 | 只看楼主
分享到:

如何实现BLE OTA?什么叫DFU?如何通过UART实现固件升级?又如何通过USB实现固件升级?怎么保证升级的安全性?什么叫双备份(dual bank)DFU?什么叫单备份(single bank)DFU?什么叫后台式(background)DFU?本文将对上述问题进行探讨。

1.概述

所谓DFU(Device Firmware Update),就是设备固件升级的意思,而OTA是DFU的一种类型,准确说,OTA的全称应该是OTA DFU,只不过大家为了方便起见,直接用OTA来指代固件空中升级(有时候大家也将OTA称为FOTA)。DFU除了可以通过无线方式(OTA)进行升级,也可以通过有线方式进行升级,比如通过UART,USB或者SPI通信接口来升级设备固件。

不管采用OTA方式还是有线通信方式,DFU包括后台式(background)和非后台式两种模式,目前的智能手机升级Android或者iOS系统都是采用background DFU方式,即新固件在后台悄悄下载,下载成功后,再提示用户升级,整个升级过程中对用户手机使用没有任何影响。而早先的功能机就是采用非后台式 DFU来升级操作系统的,即用户需要先长按某些按键进入bootloader模式,然后再进行升级,在升级过程中,手机的正常功能无法使用。Background DFU必须采用双备份(dual bank)模式进行升级,即老系统(老固件)和新系统(新固件)各占一块存储区,只有当新系统下载完成并校验成功后才会去升级老系统。而非后台式DFU可以采用dual bank或者single bank模式,dual bank的做法是升级时系统先进入bootloader,然后把新系统(新固件)下载下来并校验成功,然后再擦除老系统(老固件)并升级新系统,dual bank方式虽然牺牲了很多存储空间,但是换来了更好的升级体验。Single bank的做法是升级时系统也是先进入bootloader,然后立马把老系统擦除,然后直接把新系统下载到老系统区域,跟dual bank相比,single bank将大大节省Flash存储区域,在系统资源比较紧张的时候,推荐使用single bank方式。不管是single bank还是dual bank,升级过程出现问题后,都可以进行二次升级,都不会出现“变砖”情况。不过dual bank有一个好处,如果升级过程中出现问题或者新固件有问题,它还可以选择之前的老系统继续执行而不受其影响。而single bank碰到这种情况就只能一直待在bootloader中,然后等待二次或者多次升级,此时设备的正常功能就无法使用了,从用户使用这个角度来说,你也可以认为此时设备已经“变砖”了。可参考下面三个图来理解上述过程。

  

 

如果你是第一次接触Nordic nRF5 SDK,那么建议你先看一下这篇文章:开发你的第一个BLE应用程序—Blinky,或者看一下这一篇文章:手把手教你开发BLE数据透传应用程序,以建立Nordic nRF5 SDK的一些基本知识,然后再往下看以下章节。

2. Nordic nRF5 SDK DFU例程

Nordic 原生态SDK就提供了OTA(BLE)DFU,UART DFU,以及USB DFU例程,大家可以直接参考Nordic例程来实现自己的DFU。由于Nordic SDK版本很多,而且每个版本之间都或多或少有些差异,下面将分SDK版本来阐述Nordic每个版本SDK中如何实现OTA,至于UART DFU和USB DFU,这里就不再阐述了。感兴趣的同学可以参考Nordic nRF5 SDK v15.0.0如下目录:

UART serial DFU目录(nRF52832):nRF5_SDK_15.0.0_a53641a\examples\dfu\secure_bootloader\pca10040_uart\arm5_no_packs

USB serial DFU目录(nRF52840):

nRF5_SDK_15.0.0_a53641a\examples\dfu\secure_bootloader\pca10056_usb\arm5_no_packs

这里说明一下,目前Nordic只提供非后台式DFU例子,SDK中还没有后台式DFU例子(不过这个实现起来并不难,只要大家搞明白了里面的原理,自己开发起来会很快的),所以下面的论述都是基于非后台式DFU。另外,SDK9/10/11,Nordic只有明文DFU。从SDK12开始,Nordic 开始支持安全DFU(secure DFU)。所谓secure DFU,不是指升级时固件是加密的,而是指升级之前bootloader会先验证新固件的签名,只有验签通过后,才允许后续升级,此时的升级方式仍然是明文;验签失败,则拒绝后续升级。Secure DFU将杜绝黑客的恶意攻击,大大提高系统的安全性。

Nordic nRF5 SDK软件架构跟其他家有点不一样,程序存储区最开始部分放得不是bootloader,而是蓝牙协议栈softdevice,bootloader则被nRF5 SDK放在程序存储区的最上面,整个存储区结构图如下所示:

 

根据升级时如何跳转到Bootloader,nRF5 SDK又将DFU分为按键式DFU和非按键式(Buttonless)DFU,所谓按键式DFU,就是上电时长按某个按键以进入bootloader模式。而buttonless DFU,就是整个DFU过程中设备端无任何人工干预,通过BLE指令方式让设备进入bootloader模式。

按键式DFU比较简单,你只需将softdevice和bootloader image烧入到设备中(application可烧可不烧),按住button4然后上电,设备就会自动进入bootloader模式,然后就可以通过nRF Connect或者nRF Toolbox对设备进行OTA了。一旦buttonless DFU例子从app跳到了bootloader,后续DFU升级过程就跟按键式DFU一模一样,所以如果你对按键式DFU操作过程中有什么不明白的地方,可以参考后面的buttonless DFU的说明,这里就不单独对按键式DFU操作过程进行说明了。

下面将对buttonless DFU实现过程按照SDK版本一一进行阐述,请选择你感兴趣的SDK版本进行阅读。下文的所有操作步骤所对应的脚本都放在百度云盘上,云盘链接如下所示

建议大家先把对应的脚本下下来,然后对着操作步骤去实现自己的DFU过程。

2.1 nRF5 SDK v15.0.0 OTA

SDK15既支持明文DFU又支持安全DFU(实际上是签名DFU),而且SDK15既可以实现OTA DFU,也可以实现基于UART或者USB通信的DFU。所谓签名DFU,就是bootloader中预先装载一个公钥,升级时,主机先发一个签名给bootloader,bootloader会对这个签名进行验签,验签通过才能继续DFU,否则拒绝DFU。SDK15 OTA DFU是基于例程ble_app_buttonless_dfu来实现的,而且SDK15只支持nRF52系列产品,它不支持nRF51系列产品,下面我们以nRF52832(开发板编号:PCA10040)为例,来阐述SDK15是如何实现OTA的。

nRF52832 OTA

请大家先到百度云盘下载压缩包:DFU/SDK15_0/ Script_SDK15_S132_nRF52832.rar”并解压,然后对照以下步骤进行操作:

1)     准备。请先执行如下的“build_all.bat”脚本(Windows系统),以生成相应的micro-ecc库(micro-ecc会用来对签名进行验签等安全功能)。请注意,欲成功执行build_all.bat,大家必须先安装好git和gcc编译器。如果你嫌麻烦,可以到百度云盘下载: micro-ecc_sdk14_15_newer.rar,然后覆盖相关文件,效果也是一样的。

 

 

然后请按照http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.tools%2Fdita%2Ftools%2Fnrfutil%2Fnrfutil_installing.html&cp=5_5_1安装最新版nrfutil,nrfutil安装有两种方式,一种是直接下载exe文件,一种是以Python的方式进行安装。

nrfutil.exe直接下载链接为:(注:如果大家不熟悉Python,推荐使用这种方式)

https://github.com/NordicSemiconductor/pc-nrfutil/releases记得把nrfutil.exe所在目录放在Windows环境变量中。

或者你按照如下步骤去安装nrfutil:

注:安装完Python2.7后,需要修改Windows path变量值,如果你安装了老版本nrfutil,请先把老版本所在的目录C:\Program Files (x86)\Nordic Semiconductor\nRFgo Studio从path变量中删除,然后添加这2个目录:C:\Python27;C:\Python27\Scripts;

  • 通过pip安装最新版的nrfutil,即打开Windows命令行工具CMD,输入如下命令:pip install nrfutil,即可以完成nrfutil的安装。
  • 安装完成后,在Windows命令行工具输入:nrfutil version,其版本应该在3.2.0以上。
  • 对于Windows用户,nrfutil运行需要几个特殊的DLL库,而这几个库有些Windows机器是没有的,如此,可往:https://www.microsoft.com/en-us/download/details.aspx?id=40784下载。

2)     通过nrfutil生成公私钥对。大家可以直接双击“key_generate.bat”以生成相应的私钥(priv.pem)和公钥(dfu_public_key.c)。大家务必要保存好私钥priv.pem,以后每个新image要升级时,都会先通过这个私钥对它进行签名,一旦priv.pem丢失或者被暴露,DFU将无法进行或者变得不安全。

3)     编译bootloader代码。将刚才的dfu_public_key.c取代目录nRF5_SDK_15.0.0_a53641a\examples\dfu下的同名文件,然后编译如下目录中的工程:

nRF5_SDK_15.0.0_a53641a\examples\dfu\secure_bootloader\pca10040_ble\arm5_no_packs,将hex改为:bootloader.hex

4)     编译application代码。请编译工程:nRF5_SDK_15.0.0_a53641a\examples\ble_peripheral\ble_app_buttonless_dfu\pca10040\s132\arm5_no_packs,将hex修改为:app.hex

5)     生成bootloader settings page。Bootloader settings存储在Flash最后一个page,它将决定复位后芯片的行为,比如是进入DFU模式还是应用模式,同时它还包含image的CRC值和版本等信息。如果要求芯片复位后进入application,必须正确生成该bootloader settings hex,生成脚本见“settings_page_generate.bat”

6)     烧写softdevice,app和bootloader。请双击“mass_program.bat”来完成整个烧写过程

7)     生成新image对应的zip包。请双击“zip_generate.bat”,以生成SDK15_app_s132.zip,升级时,该zip包将会由云端下发到手机app中。

8)     将“SDK15_app_s132.zip”拷贝到手机上。安卓和苹果手机都可以通过微信的‘文件传输助手’拷过去,非常方便。请注意,手机nRF Connect和nRF Toolbox都支持DFU功能,苹果手机拷贝的时候可以随便选择其中一个app。

9)     使用nRF Connect或者nRF Toolbox来完成DFU过程。这里以nRF Connect为例来阐述整个升级过程

  • DK广播为Nordic_Buttonless,如下

 

  • 连接该设备,使能CCCD,并选择“DFU”

 

 

 

  • 选择升级用的zip包。有些安卓系统自带的文件浏览器会有问题,建议使用ES explorer来选择zip,如下:

 

 

 

 

  • 开始升级

 

  

  • 升级成功,设备将自动启动,此时你会看到新image已经在运行,广播名字也变成Nordic_new,如下:

 

 

后面我会以SDK15.0.0 ble_app_uart为例,详细阐述如何把ble_app_buttonless_dfu的DFU功能移植到ble_app_uart上,从而让ble_app_uart也具有DFU功能,有兴趣的的读者请参考第3章。

nRF52840 OTA

nRF52840 OTA过程与nRF52832非常相似,唯一不同的是选择pca10056目录,请下载百度云盘脚本“DFU/SDK15_0/ Script_SDK15_S140_nRF52840.rar”,然后按照上述52832的步骤来实现52840的OTA DFU。

 

2.2 nRF5 SDK v14.2.0 OTA

SDK14目前只支持安全DFU(实际上是签名DFU),所谓签名DFU,就是bootloader中预先装载一个公钥,升级时,主机先发一个签名给bootloader,bootloader会对这个签名进行验签,验签通过后才能继续DFU,否则拒绝DFU。SDK14既可以实现OTA DFU,也可以实现基于UART或者USB通信的DFU。SDK14 OTA DFU是基于例程ble_app_buttonless_dfu来实现的,而且SDK14只支持nRF52系列产品,它不支持nRF51系列产品,下面我们以nRF52832(开发板编号:PCA10040)为例,来阐述SDK14是如何实现OTA的。

nRF52832 OTA

请大家先到百度云盘下载压缩包:DFU/SDK14_2/ Script_SDK14_S132_nRF52832.rar”并解压,然后对照以下步骤进行操作:

1)     准备。请先执行如下的“build_all.bat”脚本(Windows系统),以生成相应的micro-ecc库(micro-ecc会用来对签名进行验签等安全功能)。请注意,欲成功执行build_all.bat,大家必须先安装好git和gcc编译器。如果你嫌麻烦,可以到百度云盘下载: micro-ecc_sdk14_15_newer.rar,然后覆盖相关文件,效果也是一样的。

然后请按照http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.tools%2Fdita%2Ftools%2Fnrfutil%2Fnrfutil_installing.html&cp=5_5_1安装最新版nrfutil,nrfutil安装有两种方式,一种是直接下载exe文件,一种是以Python的方式进行安装。

nrfutil.exe直接下载链接为:(注:如果大家不熟悉Python,推荐使用这种方式)

https://github.com/NordicSemiconductor/pc-nrfutil/releases记得把nrfutil.exe所在目录放在Windows环境变量中。

或者你按照如下步骤去安装nrfutil:

注:安装完Python2.7后,需要修改Windows path变量值,如果你安装了老版本nrfutil,请先把老版本所在的目录C:\Program Files (x86)\Nordic Semiconductor\nRFgo Studio从path变量中删除,然后添加这2个目录:C:\Python27;C:\Python27\Scripts;

  • 通过pip安装最新版的nrfutil,即打开Windows命令行工具CMD,输入如下命令:pip install nrfutil,即可以完成nrfutil的安装。
  • 安装完成后,在Windows命令行工具输入:nrfutil version,其版本应该在3.2.0以上。
  • 对于Windows用户,nrfutil运行需要几个特殊的DLL库,而这几个库有些Windows机器是没有的,如此,可往:https://www.microsoft.com/en-us/download/details.aspx?id=40784下载。

2)     通过nrfutil生成公私钥对。大家可以直接双击“key_generate.bat”以生成相应的私钥(priv.pem)和公钥(dfu_public_key.c)。大家务必要保存好私钥priv.pem,以后每个新image要升级时,都会先通过这个私钥对它进行签名,一旦priv.pem丢失或者被暴露DFU将无法进行或者变得不安全

3)     编译bootloader代码。将刚才的dfu_public_key.c取代目录nRF5_SDK_14.2.0_17b948a\examples\dfu\dfu_req_handling下的同名文件,然后编译如下目录中的工程:

nRF5_SDK_14.2.0_17b948a\examples\dfu\bootloader_secure_ble\pca10040\arm5_no_packs,将hex改为:bootloader.hex

4)     编译application代码。请编译工程:nRF5_SDK_14.2.0_17b948a\examples\ble_peripheral\ble_app_buttonless_dfu\pca10040\s132\arm5_no_packs,将hex修改为:app.hex

5)     生成bootloader settings page。Bootloader settings存储在Flash最后一个page,它将决定复位后芯片的行为,比如是进入DFU模式还是应用模式,同时它还包含image的CRC值和版本等信息。如果要求芯片复位后进入application,必须正确生成该bootloader settings hex,生成脚本见“settings_page_generate.bat”

6)     烧写softdevice,app和bootloader。请双击“mass_program.bat”来完成整个烧写过程

7)     生成新image对应的zip包。请双击“zip_generate.bat”,以生成SDK14_app_s132.zip,升级时,该zip包将会由云端下发到手机app中。

8)     将“SDK14_app_s132.zip”拷贝到手机上。安卓和苹果手机都可以通过微信的‘文件传输助手’拷过去,非常方便。请注意,手机nRF Connect和nRF Toolbox都支持DFU功能,苹果手机拷贝的时候可以随便选择其中一个app。

9)     使用nRF Connect或者nRF Toolbox来完成DFU过程。这里以nRF Connect为例来阐述整个升级过程

  • DK广播为Nordic_Buttonless,如下

 

  • 连接该设备,使能CCCD,并选择“DFU”

 

 

 

  • 选择升级用的zip包。有些安卓系统自带的文件浏览器会有问题,建议使用ES explorer来选择zip,如下: 

 

 

 

  • 开始升级

 

 

 

  • 升级成功,设备将自动启动,此时你会看到新image已经在运行,广播名字也变成Nordic_new,如下:

 

 

后面我们会以SDK15.0.0 ble_app_uart为例,详细阐述如何把ble_app_buttonless_dfu的DFU功能移植到ble_app_uart上,从而让ble_app_uart也具有DFU功能,有兴趣的的读者请参考第3章。注意:SDK14.2.0 DFU原理跟SDK15.0.0一模一样,大家可以依葫芦画瓢,完成SDK14.2.0的DFU移植工作。

 

(1 ) (0 )
回复 举报

回复于 2019-04-29 沙发

谢谢分享
(0 )
评论 (0) 举报

回复于 2019-04-30 2#

谢谢分享!!!!
(0 )
评论 (0) 举报

回复于 2019-05-25 3#

感谢分享!
(0 )
评论 (0) 举报

回复于 2020-02-18 4#

感谢分享
(0 )
评论 (0) 举报

回复于 2020-02-18 5#

感谢分享,欢迎关注我,资料持续更新中。有需要机械臂,电源,硬件电路设计,软件编程,开发板等各种定制的可以私聊我哦,相互学习,共同进步。
(0 )
评论 (0) 举报
  • 发表回复
    0/3000





    举报

    请选择举报类别

    • 广告垃圾
    • 违规内容
    • 恶意灌水
    • 重复发帖

    全部板块

    返回顶部