【经验】Silicon Labs的蓝牙SoC EFR32BG22如何进行在线的OTA升级?
SILICON LABS的蓝牙SoC EFR32BG目前已经能够支持到蓝牙5.2,工艺升级后的EFR32BG22的功耗能够达到接收4.1mA,0dbm发射功耗3.6mA,休眠功耗低至1.4uA,如此低的功耗,能够大幅延长蓝牙设备的电池续航时间。
目前SiliconLabs提供的默认的OTA升级方式是In-place方式,流程为:
1、 APP发起OTA,显示连接断开,搜索OTA设备。
2、 EFR32BG22断开连接并重新启动;
3、 EFR32BG22 重启后以”OTA”广播;
4、 APP连接OTA并开始OTA升级;
5、 升级完成后EFR32BG22重启,升级成功。
这种方式占用的空间最小,但是可能在实际应用时,有些情况大家更喜欢传统的在线升级,链接不断开。本文介绍下方法。
首先需要选择一个Bootloader,本文以Internal Flash Bootloader为例,在ThunderBoard EFR32BG22的平台上进行操作:
然后,以SOC-Empty为例:
然后,复制Bootloader的API文件到工程中:
C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v2.7\platform\bootloader\api\*
使用如下代码替换工程的app.c
//////////////////////////////////分割线////////////////////////////////////////////////
/***********************************************************************************************//**
* \file app.c
* \brief This example shows how to do Bluetooth OTA update under application control.
*
* For more details about the Bluetooth OTA, refer to application note AN1086.
*
***************************************************************************************************
* <b> (C) Copyright 2018 Silicon Labs, http://www.silabs.com</b>
***************************************************************************************************
* This file is licensed under the Silabs License Agreement. See the file
* "Silabs_License_Agreement.txt" for details. Before using this software for
* any purpose, you must agree to the terms of that agreement.
**************************************************************************************************/
/* Bluetooth stack headers */
#include "bg_types.h"
#include "native_gecko.h"
#include "gatt_db.h"
#include "app.h"
#if DEBUG_LEVEL
/* printf debugging is enabled */
#include "retargetserial.h"
#include <stdio.h>
#define uart_flush RETARGET_SerialFlush
#else
/* debug prints are DISABLED - replace printf etc. with empty implementation */
#define printf(fmt, ...) (0)
#define uart_flush() (0)
#endif
#include "btl_interface.h"
#include "btl_interface_storage.h"
static void bootMessage(struct gecko_msg_system_boot_evt_t *bootevt);
static BootloaderInformation_t bldInfo;
static BootloaderStorageSlot_t slotInfo;
/* OTA variables */
static uint32 ota_image_position = 0;
static uint8 ota_in_progress = 0;
static uint8 ota_image_finished = 0;
static uint16 ota_time_elapsed = 0;
static int32_t get_slot_info()
{
int32_t err;
bootloader_getInfo(&bldInfo);
printf("Gecko bootloader version: %u.%u\r\n", (bldInfo.version & 0xFF000000) >> 24, (bldInfo.version & 0x00FF0000) >> 16);
err = bootloader_getStorageSlotInfo(0, &slotInfo);
if(err == BOOTLOADER_OK)
{
printf("Slot 0 starts @ 0x%8.8x, size %u bytes\r\n", slotInfo.address, slotInfo.length);
}
else
{
printf("Unable to get storage slot info, error %x\r\n", err);
}
return(err);
}
static void erase_slot_if_needed()
{
uint32_t offset = 0;
uint8_t buffer[256];
int i;
int dirty = 0;
int32_t err = BOOTLOADER_OK;
int num_blocks = 0;
/* check the download area content by reading it in 256-byte blocks */
num_blocks = slotInfo.length / 256;
while((dirty == 0) && (offset < 256*num_blocks) && (err == BOOTLOADER_OK))
{
err = bootloader_readStorage(0, offset, buffer, 256);
if(err == BOOTLOADER_OK)
{
i=0;
while(i<256)
{
if(buffer[i++] != 0xFF)
{
dirty = 1;
break;
}
}
offset += 256;
}
printf(".");
}
if(err != BOOTLOADER_OK)
{
printf("error reading flash! %x\r\n", err);
}
else if(dirty)
{
printf("download area is not empty, erasing...\r\n");
bootloader_eraseStorageSlot(0);
printf("done\r\n");
}
else
{
printf("download area is empty\r\n");
}
return;
}
static void print_progress()
{
// estimate transfer speed in kbps
int kbps = ota_image_position*8/(1024*ota_time_elapsed);
printf("pos: %u, time: %u, kbps: %u\r\n", ota_image_position, ota_time_elapsed, kbps);
}
void appMain(gecko_configuration_t *pconfig)
{
#if DISABLE_SLEEP > 0
pconfig->sleep.flags = 0;
#endif
#if DEBUG_LEVEL
RETARGET_SerialInit();
#endif
// Initialize stack
gecko_init(pconfig);
while (1) {
/* Event pointer for handling events */
struct gecko_cmd_packet* evt;
#if DEBUG_LEVEL
/* if there are no events pending then the next call to gecko_wait_event() may cause
* device go to deep sleep. Make sure that debug prints are flushed before going to sleep */
if (!gecko_event_pending()) {
uart_flush();
}
#endif
/* Check for stack event. */
evt = gecko_wait_event();
/* Handle events */
switch (BGLIB_MSG_ID(evt->header)) {
/* This boot event is generated when the system boots up after reset.
* Do not call any stack commands before receiving the boot event.
* Here the system is set to start advertising immediately after boot procedure. */
case gecko_evt_system_boot_id:
#if DEBUG_LEVEL
bootMessage(&(evt->data.evt_system_boot));
#endif
/* 1 second soft timer, used for performance statistics during OTA file upload */
gecko_cmd_hardware_set_soft_timer(32768, 0, 0);
/* set advertising interval to 100 ms */
gecko_cmd_le_gap_set_advertise_timing(0, 160, 160, 0, 0);
/* Start general advertising and enable connections. */
printf("boot event - starting advertising\r\n");
gecko_cmd_le_gap_start_advertising(0, le_gap_general_discoverable, le_gap_connectable_scannable);
/* bootloader init must be called before calling other bootloader_xxx API calls */
bootloader_init();
/* read slot information from bootloader */
if(get_slot_info() == BOOTLOADER_OK)
{
/* the download area is erased here (if needed), prior to any connections are opened */
erase_slot_if_needed();
}
else
{
printf("Check that you have installed correct type of Gecko bootloader!\r\n");
}
break;
case gecko_evt_le_connection_opened_id:
printf("connection opened\r\n");
break;
case gecko_evt_le_connection_closed_id:
printf("connection closed, reason: 0x%2.2x\r\n", evt->data.evt_le_connection_closed.reason);
if (ota_image_finished) {
printf("Installing new image\r\n");
#if DEBUG_LEVEL
uart_flush();
#endif
bootloader_setImageToBootload(0);
bootloader_rebootAndInstall();
} else {
/* Restart advertising after client has disconnected */
gecko_cmd_le_gap_start_advertising(0, le_gap_general_discoverable, le_gap_connectable_scannable);
}
break;
case gecko_evt_hardware_soft_timer_id:
if(ota_in_progress)
{
ota_time_elapsed++;
print_progress();
}
break;
/* write operations to ota_data, ot_control characteristics are handled here :*/
case gecko_evt_gatt_server_user_write_request_id:
{
uint32_t connection = evt->data.evt_gatt_server_user_write_request.connection;
uint32_t characteristic = evt->data.evt_gatt_server_user_write_request.characteristic;
if(characteristic == ota_control)
{
switch(evt->data.evt_gatt_server_user_write_request.value.data[0])
{
case 0://Erase and use slot 0
// NOTE: download are is NOT erased here, because the long blocking delay would result in supervision timeout
//bootloader_eraseStorageSlot(0);
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;
printf("upload finished. received file size %u bytes\r\n", ota_image_position);
uart_flush();
break;
default:
break;
}
} else if(characteristic == 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;
}
}
gecko_cmd_gatt_server_send_user_write_response(connection,characteristic,0);
}
break;
default:
break;
}
}
}
static void bootMessage(struct gecko_msg_system_boot_evt_t *bootevt)
{
bd_addr local_addr;
int i;
printf("stack version: %u.%u.%u\r\n", bootevt->major, bootevt->minor, bootevt->patch);
local_addr = gecko_cmd_system_get_bt_address()->address;
printf("local BT device address: ");
for(i=0;i<5;i++)
{
printf("%2.2x:", local_addr.addr[5-i]);
}
printf("%2.2x\r\n", local_addr.addr[0]);
}
//////////////////////////////////分割线/////////////////////////////////////////////////
使用如下替代gatt.xml
////////////////////////////////////分割线////////////////////////////////////
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--Custom BLE GATT-->
<gatt gatt_caching="false" generic_attribute_service="false" name="Custom BLE GATT" prefix="">
<!--Generic Access-->
<service advertise="false" name="Generic Access" requirement="mandatory" sourceId="org.bluetooth.service.generic_access" type="primary" uuid="1800">
<informativeText>Abstract: The generic_access service contains generic information about the device. All available Characteristics are readonly. </informativeText>
<!--Device Name-->
<characteristic name="Device Name" sourceId="org.bluetooth.characteristic.gap.device_name" uuid="2A00">
<informativeText/>
<value length="16" type="utf-8" variable_length="false">EFR32WaitForOTA</value>
<properties const="true" const_requirement="optional" read="true" read_requirement="mandatory"/>
</characteristic>
<!--Appearance-->
<characteristic name="Appearance" sourceId="org.bluetooth.characteristic.gap.appearance" uuid="2A01">
<informativeText>Abstract: The external appearance of this device. The values are composed of a category (10-bits) and sub-categories (6-bits). </informativeText>
<value length="2" type="hex" variable_length="false">0000</value>
<properties const="true" const_requirement="optional" read="true" read_requirement="mandatory"/>
</characteristic>
</service>
<!--Silicon Labs OTA-->
<service advertise="false" name="Silicon Labs OTA" requirement="mandatory" sourceId="com.silabs.service.ota" type="primary" uuid="1D14D6EE-FD63-4FA1-BFA4-8F47B42119F0">
<informativeText>Abstract: The Silicon Labs OTA Service enables over-the-air firmware update of the device. </informativeText>
<!--Silicon Labs OTA Control-->
<characteristic id="ota_control" name="Silicon Labs OTA Control" sourceId="com.silabs.characteristic.ota_control" uuid="F7BF3564-FB6D-4E53-88A4-5E37E0326063">
<informativeText>Abstract: Silicon Labs OTA Control. </informativeText>
<value length="1" type="user" variable_length="false"/>
<properties write="true" write_requirement="mandatory"/>
</characteristic>
<!--Silicon Labs OTA Data-->
<characteristic id="ota_data" name="Silicon Labs OTA Data" sourceId="com.silabs.characteristic.ota_data" uuid="984227F3-34FC-4045-A5D0-2C581F81A153">
<informativeText>Abstract: Silicon Labs OTA Data. </informativeText>
<value length="255" type="user" variable_length="true"/>
<properties write="true" write_no_response="true" write_no_response_requirement="mandatory" write_requirement="excluded"/>
</characteristic>
</service>
</gatt>
////////////////////////////////分割线/////////////////////////////////////////////
在图形界面导入gatt.xml,然后重新生成一下,如有需要可以添加一些:
重新生成后编译即可。
这样就可以按照原先的OTA方法,进行在线升级了。
- |
- +1 赞 0
- 收藏
- 评论 0
本文由Song提供,版权归世强硬创平台所有,非经授权,任何媒体、网站或个人不得转载,授权转载时须注明“来源:世强硬创平台”。
相关推荐
【经验】芯科科技EFR32BG22系列蓝牙SOC修改自定义广播包的思路与具体实例
在蓝牙的实际应用中,往往需要自定义的蓝牙广播包来适应不同的应用环境,本文主要介绍基于SILICON LABS的EFR32BG22蓝牙SOC实现自定义广播数据包的方法。
【经验】STUDIO V5中蓝牙SoC EFR32BG22添加串口LOG打印的方法
在调试Silicon Labs蓝牙SoC EFR32BG22时,一般需要添加LOG打印信息,通过串口的方式来判断代码运行是否正常。由于使用RTT功能在打印信息时无法再次在线调试和代码下载,所以直接采用串口的方式更加便捷。
Silicon Labs EFR32BG21 蓝牙SoC RCP模式测试-扫描设备
本文介绍测试EFR32BG21 蓝牙RCP模式工作在主模式,用于扫描蓝牙从设备,建立蓝牙连接和收发数据。首先需要准备一台电脑并且已经安装好了linux系统。也可以是windows系统下安装的linux虚拟机。并且已经安装好了蓝牙BlueZ协议栈。
Silicon Labs EFR32BG27蓝牙SoC用在CGM中,支持3v或1.5v电池供电,可做到21天超长续航时间
EFR32BG27蓝牙SoC由世界知名半导体厂商Silicon Labs推出,基于ARM Cortex-M33处理器内核,拥有超低功耗、超小体积和超大资源等优势,成为了CGM设备的理想选择。
CareMedi采用芯科科技BG22系列蓝牙SoC打造小型贴片式胰岛素泵,大幅提升智慧医疗照护设备的应用价值
Silicon Labs(芯科科技)为CareMedi公司提供BG22小型化蓝牙SoC,帮助其开发新一代的贴片式胰岛素泵,大幅提升智慧医疗照护设备的应用价值。芯科科技很自豪能够通过为易用、智能的胰岛素泵设备提供解决方案,来帮助提高糖尿病患者的生活质量。我们期待能够进一步推动医疗物联网向前发展。
【应用】EFR32BG22蓝牙SoC用做CGM连续血糖仪主控,单芯片集成MCU和蓝牙5.2
CGM连续血糖仪为了用户体验更好,要做到小而轻,续航时间长,可以通过手机蓝牙连接获取血糖测量数据。Silicon Labs的蓝牙SoC EFR32BG22在单芯片中集成了MCU和蓝牙5.2,可以作为CGM的主控芯片并实现蓝牙数据收发,有丰富的外设。
芯科科技EFR32BG27蓝牙SoC助力持续性血糖监测CGM设备长达21天续航时间
在当今医疗领域,持续性血糖监测(CGM)成为人们关注的焦点,特别是对于糖尿病患者而言,实时了解血糖水平变化对于治疗和生活质量的提升具有举足轻重的意义。Silicon Labs提供的极小型、超低功耗EFR32BG27(BG27)蓝牙SoC在CGM中的应用显得尤为突出。本文将详细介绍BG27蓝牙SoC在CGM中的应用及其突出特点。
【经验】EFR32BG22系列蓝牙SOC电池电压与VDD供电电压检测ADC的方法
EFR32BG22作为低功耗蓝牙SOC方案,经常应用于电池供电的方案中,一般采用内部的ADC作为采集通道,内部的输入源作为输入接口,来测试VDD供电电压。本文将讲解电池电压与VDD供电电压检测ADC的方法。
探索蓝牙新安全功能,基于证书的身份验证和配对 (CBAP)
“基于证书的身份验证和配对(CBAP)”有助于简化低功耗蓝牙(Bluetooth LE)设备的身份验证和配对过程。芯科科技是低功耗蓝牙解决方案的行业领导者,可以帮助您实施基于证书的身份验证和配对,以确保设备具有最高安全性,而无需任何用户交互。目前,Secure Vault-High 和 Secure Vault-Mid 设备上支持基于证书的身份验证和配对。
【经验】EFR32BG系列蓝牙SoC之低功耗测试操作指导
很多的蓝牙设备都是电池供电的,因此对蓝牙SoC功耗水平测试与评估就非常有必要。Silicon Labs公司提供的蓝牙评估板底板,都带有电流功耗测试功能,搭配Simplicity studio v4开发平台的energy profile功耗测试上位机,非常容易测试出EFR32BG系列蓝牙SoC的功耗水平。我们详细介绍功耗测试需要的软件和硬件以及测试操作。本文就将具体进行说明。
芯科科技提供多款无线连接和控制芯片产品及解决方案,BG2x系列蓝牙SoC成就多样医疗物联网用例,
Silicon Labs(亦称“芯科科技”)的无线SoC和MCU助力全球客户的医疗物联网应用创新,持续打造更智能、高效、安全和便捷的健康监测设备。智能和网联技术近年来一直是医疗和健康保障领域内的热门技术,许多厂商都在利用医疗物联网(IoMT)技术开发更加智能和互联的健康监测设备,以利用物联网、云计算、人工智能和可穿戴等新一代信息通信技术,来帮助用户时刻监控自己的健康状况、降低医疗费用和就医麻烦。
低功耗、高性能:探究流行蓝牙SOC的成功秘诀
随着无线技术的飞速发展,蓝牙SOC已成为当今市场上极为流行的无线通信解决方案。蓝牙SOC集成了蓝牙通信功能以及微处理器等其他功能,为现代智能设备提供了高效、稳定的连接体验。
【经验】芯科科技EFR32BG22系列蓝牙SOC低功耗优化的相关配置
本文主要介绍Silicon Labs(芯科科技)EFR32BG22系列蓝牙SOC目前所有的低功耗优化的相关配置,实现目标: VDD=3V,VSCALE0=0.9V,温度25℃,EM2模式下深度休眠为1.4μA。
【技术】蓝牙5与蓝牙MESH,增加蓝牙传输距离并将蓝牙设备进行组网通讯
Silicon Labs公司作为世界顶级的物联网芯片、软件、解决方案供应商,推出支持蓝牙5.0的SOC芯片EFR32BG系列和通过认证、集成天线、远距离传输、小封装的蓝牙模块BGM系列。Silicon Labs公公司针对蓝牙产品,提供整套完善的开发工具,蓝牙Mesh网络开发包,例程和手机APP代码。运用Silicon Labs公司提供的丰富资源,可以提高设计产品的稳定性,加快上市时间。
AIoT与蓝牙SOC:智能生活的无缝连接
未来,随着5G、云计算、边缘计算等技术的不断发展,蓝牙SOC将会在AIoT领域发挥更加重要的作用。它不仅能够实现设备之间的无缝连接和数据交换,还能够为AI算法提供更加丰富的数据源,推动人工智能技术的不断创新和发展。
电子商城
品牌:SILICON LABS
品类:Wireless Gecko SoC
价格:¥8.1764
现货: 101,879
现货市场
品牌:SILICON LABS
品类:Switch Hall Effect Magnetic Position Sensor
价格:¥2.2924
现货:126,000
服务
提供语音芯片、MP3芯片、录音芯片、音频蓝牙芯片等IC定制,语音时长:40秒~3小时(外挂flash),可以外挂TF卡或U盘扩容。
最小起订量: 1pcs 提交需求>
提供蓝牙BLE芯片协议、蓝牙模块、蓝牙成品测试认证服务;测试内容分Host主机层,Controller控制器层,Profile应用层测试。支持到场/视频直播测试,资深专家全程指导。
实验室地址: 深圳 提交需求>
登录 | 立即注册
提交评论