nRF52832 — DFU升级

  • Post author:
  • Post category:其他





XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


XX  作       者:文化人


XX  联系方式:


(或进群:471144274)


XX  版权声明:原创文章,欢迎评论和转载~转载时能告诉我一声就最好了


XX  要说的话:作者水平有限,难免有不足之处,恳请指正!


XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


写在前面:每次跟销售或者客户做项目评估的时候,他们都会问到“能支持OTA吗?”,可见OTA升级对于一个产品而言是多么重要(~废话)。


一、OTA空中升级:


1、概念:

DFU:Device Firmware Update(设备固件更新)

OTA: Over The Air (空中升级)

两种不同布局方式的差别:

(1)single bank布局不支持softdevice及bootloader自身的升级,只支持该芯片上应用程序的升级。

(2)采用single bank布局的方式中,一旦开始升级,芯片上原有的应用程序将不能被保存。而以dual bank布局的方式中,在开始接收新的二进制程序(image)时,原有的二进制程序(image)将会被保留,如果升级失败不会影响芯片上原有的程序。目前的SDK DFU都是只支持dual bank升级,如果需要single bank需要使用6.0之前的版本sdk。还有就是采用dual bank升级的代码大小不能超过总(内存-SoftDevice size – Bootloader size)/2.

2、启动的过程:

对于单片机类的产品,要支持空中升级,通常单片机内部会烧录两段代码,一个是bootloader程序,一个是用户app程序,bootloader程序主要就是实现app升级的程序,它是单片机上电后首次运行的程序,app程序就是实现产品功能的程序。对于nRF52832来说,虽然多了Nordic官方提供的softdevice,但是原理还是一样的。芯片上电首次运行softdevice,虽然这段程序不负责程序升级,但是它也具备一点bootloader的功能,也就是说,芯片上电后,它会判断芯片内部是否有bootloader代码(bootloader代码位置固定,所以它能判断出是否有合法的bootloader程序),若有bootloader程序则会跳转到bootloader程序执行,若没有bootloader程序而只检测到了用户的app程序,那么就直接跳转到app程序运行,bootloader程序差不多只做两件事情,1:控制程序的跳转,比如跳转到app程序;2:实现app程序升级;

nRF52832程序加载顺序;

1)SoftDevice加载;

2)SoftDevice初始化蓝牙协议栈;

3)SoftDevice检查0x10001014处是否保存有有效的BootLoader地址, 如果不是跳转到0x14000处的APP执行,流程结束.

4)如果是有效bootloader地址,SoftDevice就跳转到BootLoader执行;

5)BootLoader进行他的业务处理工作;

6)BootLoader跳转到0x14000处的APP执行,流程结束.

3、OTA升级的原理:

正常启动之后,程序会运行在app程序,如果它支持OTA的话,使用 nrftoolbox(推荐使用 v2.0.0 以上)或者 nrf connect 可以进行空中升级,只要向该 DFU control point 特征值中写入 0x01,设备便断开连接,上报 BLE_DFU_EVT_ENTERING_BOOTLOADER 事件,这时程序会跳转到bootloader中,等待OTA升级指令,使用nRF connect进行空中升级,如果升级成功,程序又会自动跳转(setting文件的作用下)到app程序,正常运行;


二、小潘的分享:


1、文档链接:

首先非常感谢小潘大神的分享,详细的操作文档请点击

这个



2、遇到的问题:

根据文档进行操作,编译bootloader出现两个错误,在解决第一个问题(uecc.h)时就卡住了,执行make指令总是提示这个,以为是mingw安装有问题,重新试了好多次都不行~

搜了很多资料,最后找到了

这个

, 按照4、5的操作,解决了第一个问题;接着根据小潘的文档,一路很顺畅的完成了。


三、OTA升级实操(从零开始建立一个支持dfu服务的应用):


1、

参考文档1




参考文档2



2、sdk版本是nRF5_SDK_12.2.0,没有dfu服务的工程选择的是app_ble_uart:

1)添加ble_dfu.c、nrf_dfu_settings.c、nrf_dfu_flash.c(app_scheduler.c、crc32.c和nrf_nvmc.c选择添加)到自己的工程中,添加对应头文件的路径;

2)参考experimental_ble_app_buttonless_dfu工程,在main.c文件里找到service_init()函数,添加如下代码:

ble_dfu_init_t dfus_init;
memset(&dfus_init, 0, sizeof(dfus_init));

dfus_init.evt_handler								= ble_dfu_evt_handler;
dfus_init.ctrl_point_security_req_write_perm		= SEC_SIGNED;
dfus_init.ctrl_point_security_req_cccd_write_perm	= SEC_SIGNED;
			
err_code = ble_dfu_init(&m_dfus, &dfus_init);
APP_ERROR_CHECK(err_code);

找到ble_evt_dispatch()函数,添加如下代码:

ble_dfu_on_ble_evt(&m_dfus, p_ble_evt);

3)编译后,解决提示的错误,按照小潘的文档,烧录,可以成功进行dfu升级;

4)有一个问题:需要把ble_nus_init()屏蔽掉蓝牙才能搜索到,可能是某些属性冲突了,修改了服务的uuid还是不行,暂时先记在这里;



遗留问题收敛:2018-01-12


1、

参考文档1




参考文档2



2、如图,解决方法可以修改Vendor specific UUID的个数,或者把UUID的类型修改为非

BLE_UUID_TYPE_BLE;




PS:如果使用高版本SDK,并且程序中已经自定义基准UUID的话,这个时候添加DFU代码需要修改基准UUID允许添加的个数,因为默认是1。否则


ble_dfu_init


初始化函数里面调用


sd_ble_uuid_vs_add 函数时就会出错。






相关问题补充一:2018-03-06






1、在其他的资料中看到的解释:






相关问题补充二:2018-07-27




1、使用过程中遇到的问题:

烧录的bootloader_setting.hex一定要是对应的application.hex生成的,如果两个不对应,会卡在bootloader里面;

什么意思呢?就是说如果你已经按照softdevice–>bootloader_setting–>bootloader–>application烧录,想再去调试的话直接下载application.hex是不行的,会卡在bootloader里面,因为这个application.hex跟你烧录的bootloader_setting.hex是不对应的。

那怎么办呢?先擦除,只烧录softdevice–>application就行,这样就可以调试了。



版权声明:本文为zhanghuaishu0原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。