EFR32如何在应用程序中通过BLE 进行OTA升级

Bluetooth SDK里的soc-empty例程里面包含了一个AppLoader,可以用OTA_DFU(Over The Air -Device Firmware Upgrade)的方式升级应用程序。但是这个方式需要主机端(手机APP)也按照Silabs定义的OTA profile(包括服务和特性的UUID,以及升级过程中的主从设备之间的交互流程)来做。

实际应用中,通常需要按照生态系统(如腾讯连连)定义的OTA协议来对设备的软件进行升级,因此需要使用Gecko Bootloader配合应用程序来实现。Gecko Bootloader有standalone和application两种模式,这里要用后者,升级的流程如下图:

主机端仍可使用AN1086所述的方法:

  1. 把一块开发板连接到电脑,给它烧写Bluetooth SDK中的例程NCP–Empty Target。
  2. 在电脑上安装MinGW开发工具,然后在命令行窗口cd到目录SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\<version>\app\bluetooth\examples_ncp_host\ota_dfu 中,执行mingw32-make,就可以编译出ota-dfu.exe可执行文件。

设备端使用另一块开发板,需要制作BootLoader和应用程序两个工程:

  1. 创建BootLoader工程时,使用Gecko Bootloader的Internal Storage Bootloader(single image on 512kB device)例程,完全按缺省配置Generate代码就可以了。编译后用“Debug”或“Flash Programmer”把它烧写到开发板中。
  2. 使用Bluetooth SDK里的soc-empty例程创建应用程序,
  • 把SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v2.4\platform\bootloader\api文件夹中的所有文件复制到工程目录下的\platform\bootloader\api文件夹里;
  • 在工程目录下新建\platform\bootloader\core文件夹,并把SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v2.4\platform\bootloader\core\btl_util.h复制到里面。
  • 在应用程序的工程设置中,把apploader从链接的目标中删掉,如下面一行:

${workspace_loc:/${ProjName}/protocol/bluetooth/lib/EFR32MG13P/GCC/binapploader.o}

设置完了如下图:

  • 修改main.c文件,如下:

#define OTA_DEMO 1

#if OTA_DEMO

#include "btl_interface.h"

#include "btl_interface_storage.h"

int ota_image_position, ota_in_progress, ota_image_finished;

uint32_t connection, characteristic;

BootloaderStorageSlot_t slot;

uint32_t flash_page_erased;

#else

// Flag for indicating DFU Reset must be performed

uint8_t boot_to_dfu = 0;

#endif

在主循环中:

      case gecko_evt_le_connection_closed_id:

#if OTA_DEMO

    if(ota_image_finished)

    {

        bootloader_setImageToBootload(0);

        bootloader_rebootAndInstall();

    }

#else

        /* Check if need to boot to dfu mode */

        if (boot_to_dfu) {

          /* Enter to DFU OTA mode */

          gecko_cmd_system_reset(2);

        } else {

          /* Restart advertising after client has disconnected */

          gecko_cmd_le_gap_start_advertising(0, le_gap_general_discoverable, le_gap_connectable_scannable);

        }

#endif

        break;

      case gecko_evt_gatt_server_user_write_request_id:

#if OTA_DEMO

       /*OTA support*/

        connection = evt->data.evt_gatt_server_user_write_request.connection;

        characteristic = evt->data.evt_gatt_server_user_write_request.characteristic;

        if (characteristic == gattdb_ota_control)

       {

           switch (evt->data.evt_gatt_server_user_write_request.value.data[0])

           {

           case 0://Erase and use slot 0

              bootloader_init();

              //bootloader_eraseStorageSlot(0);

              bootloader_getStorageSlotInfo(0, &slot);

              bootloader_eraseRawStorage(slot.address, FLASH_PAGE_SIZE);

              flash_page_erased = slot.address;

              ota_image_position = 0;

              ota_in_progress = 1;

              break;

           case 3://END OTA process

              //wait for connection close and then reboot

              ota_in_progress = 0;

              ota_image_finished = 1;

              break;

           default:

              UARTDRV_Transmit(handle, "unknown OTA command\n", 20, callback);

              break;

           }

       } else if (characteristic == gattdb_ota_data)

       {

           if(ota_in_progress)

           {

              bootloader_writeStorage(0,//use slot 0

                  ota_image_position,

                  evt->data .evt_gatt_server_user_write_request.value.data,

                  evt->data.evt_gatt_server_user_write_request.value.len);

              ota_image_position += evt->data.evt_gatt_server_user_write_request.value.len;

              if((slot.address + ota_image_position) > flash_page_erased)

              {

                  flash_page_erased += FLASH_PAGE_SIZE;

                  if(flash_page_erased < (slot.address + slot.length))

                     bootloader_eraseRawStorage(flash_page_erased, FLASH_PAGE_SIZE);

              }

           }

       } else

       {

           UARTDRV_Transmit(handle, "unknown characteristic\n", 23, callback);

       }

       gecko_cmd_gatt_server_send_user_write_response(connection, characteristic, 0);

#else

        if (evt->data.evt_gatt_server_user_write_request.characteristic == gattdb_ota_control) {

          /* Set flag to enter to OTA mode */

          boot_to_dfu = 1;

          /* Send response to Write Request */

          gecko_cmd_gatt_server_send_user_write_response(

            evt->data.evt_gatt_server_user_write_request.connection,

            gattdb_ota_control,

            bg_err_success);

          /* Close connection to enter to DFU OTA mode */

          gecko_cmd_le_connection_close(evt->data.evt_gatt_server_user_write_request.connection);

        }

#endif

        break;

  • 在GATT配置器中添加Silicon Labs OTA Data特性,并把它设置为可变长度和可写,如下图:

记得点“Generate”生成代码,然后编译并用“Debug”或“Flash Programmer”把它烧写到开发板中。至此,设备端的初始软件就准备好了。

测试OTA升级软件功能:

  • 稍微修改应用程序,如把串口打印的“BLE OTA APP V1”改为“BLE OTA APP V2”,重新编译生成目标文件。
  • 然后,执行工程目录里的create_bl_files.bat脚本,它会在工程目录里创建output_gbl\application.gbl文件。
  • 把前面做好的ota-dfu.exe文件复制到output_gbl文件夹里,在命令行窗口执行它(COM8是主机端开发板的JLINK CDC UART串口,波特率必须用115200,00:0B:57:93:31:A2是设备端的蓝牙MAC地址),结果如下:

PS E:\Temp\workspace\soc-empty_uart_test\output_gbl>  .\ota-dfu.exe COM8 115200 .\application.gbl 00:0B:57:93:31:A2

System rebooted

Local address:00:0b:57:31:5a:e1

Bytes to send:141588

Scanning...OK

Device address found, connecting.

Connecting...OK

Discovering services...ATT MTU exchanged: 247

OK

Discovering characteristics...OK

    Control handle:19

    Data handle:21

    OTA Data characteristic properties:0x0c

DFU mode...OK

OTA DFU - write with response

100% 39.06kbit/s

time: 29.00s

Finishing DFU block...OK

Closing connection...OK

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: EFR32MG21A020F768是一种芯片型号,其OTA存储起始偏移量需要根据具体的系统设计和需求进行设置。 OTA存储是一种用于实现设备无线升级的技术,通常在芯片内部的闪存划分出一个特定的区域用于存储OTA固件。在实际应用OTA存储的起始偏移量需要考虑多个因素,例如OTA固件大小、设备的存储空间、存储分区的布局等。 因此,具体如何设置EFR32MG21A020F768的OTA存储起始偏移量需要根据实际情况进行确定。一般情况下,可以参考芯片厂商提供的文档或者开发板的设计来进行设置。如果您是在特定应用使用EFR32MG21A020F768芯片,请参考相关的开发文档或者咨询芯片厂商或技术支持人员,以获取更准确的建议。 ### 回答2: EFR32MG21A020F768是一款由Silicon Labs开发的无线微控制器。对于OTA存储的起始偏移量的设置,需要根据具体的应用需求和系统设计来确定。 OTA(Over-the-Air)存储是一种无线技术,允许设备通过空方式进行软件更新。在EFR32MG21A020F768OTA存储的起始偏移量设置决定了存储更新镜像的开始位置。 根据系统设计的不同,OTA存储的起始偏移量可以根据以下几个因素进行设置: 1. 存储空间要求:OTA存储通常需要足够的存储空间来容纳更新镜像的数据。根据升级固件的大小,确定起始偏移量的位置,以确保存储空间的充足。 2. 存储分区:系统可能会有多个存储分区,根据应用的需求和设计,可以将OTA存储分配到特定的分区。在设置起始偏移量时,需要考虑到所选分区的起始地址。 3. 兼容性和固件更新:考虑到固件的兼容性和未来的更新需求,起始偏移量的设置应该保留足够的余地,以容纳未来版本的固件更新。 综上所述,EFR32MG21A020F768的OTA存储的起始偏移量的设置需要根据具体的系统设计和应用需求来确定。 在对存储空间要求、存储分区和固件更新进行合理考虑的基础上,可以确定合适的起始偏移量位置。 ### 回答3: EFR32MG21A020F768是一款无线芯片,支持OTA(Over-The-Air)升级功能。OTA存储的起始偏移量(OTA storage start offset)是指固件升级文件在芯片存储的开始位置。正确设置OTA存储的起始偏移量非常重要,否则可能导致固件升级失败或者损坏设备。 对于EFR32MG21A020F768芯片来说,OTA存储的起始偏移量是由开发人员根据具体的系统需求和硬件设计来确定的。一般来说,起始偏移量要与存储芯片的物理地址对应,确保固件升级文件被正确地写入存储芯片。具体设置起始偏移量的方法如下: 1. 首先,了解EFR32MG21A020F768芯片的存储器类型和容量。该芯片通常使用闪存存储固件,可以根据所选用的存储器类型来确定起始偏移量。 2. 根据系统设计需求,确定起始偏移量所处的存储器扇区或页的位置。闪存存储器通常以扇区或页为单位进行擦除和编程,因此起始偏移量需要与所选用的存储器的扇区或页对齐。 3. 使用相关开发工具,如开发环境或烧录工具,设置起始偏移量。具体的设置方法可能因开发工具而异,通常可以通过修改配置文件或者相关参数来实现。 需要注意的是,设置起始偏移量时应遵守芯片厂商的建议和文档推荐,确保操作的正确性和稳定性。如果需要进一步了解具体的设置方法和注意事项,建议参考EFR32MG21A020F768的技术文档或咨询芯片厂商的技术支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值