silicon labs平台通过串口升级固件方案

news/2025/3/20 7:11:14/

开发环境

  • windows
  • simplicity studio 5
  • geck sdk 4.1

一 bootloader

新建BGAPI UART DFU工程
在这里插入图片描述

  1. 工程新建完成以后看一下linkerfile.ld文件的flash和ram的配置跟自己的application工程是否对应得上
    在这里插入图片描述
  2. 配置串口波特率和引脚
    在这里插入图片描述
  3. 默认使用PB0进入bootloader模式,这里改成None
    在这里插入图片描述

二 准备bt_host_uart_dfu.exe

geck sdk里面提供了bt_host_uart_dfu.exe的源码,但是需要自己编译。windows环境需要使用MinGW工具,linux使用make指令直接就可以编译出可执行文件。

2.1 安装MinGW

下载地址: https://sourceforge.net/projects/mingw-w64/files/

在这里插入图片描述
MinGW-W64-install.exe是在线安装,经常会提示错误,在这里建议直接下载x86_64-win32-seh。
下载完之后直接解压出来即可。
在这里插入图片描述

将bin的路径设置到环境变量Path中
在这里插入图片描述
在cmd界面中执行gcc -v,显示版本号说明安装成功。
在这里插入图片描述

2.2 编译

bt_host_uart_dfu的源码在gecko_sdk\app\bluetooth\example_host\bt_host_uart_dfu目录下
在该目录下使用shell power执行命令 mingw32-make 生成exe
在这里插入图片描述
不出意外在exe目录下生成了一个bt_host_uart_dfu.exe

三 升级

首先,当前固件需要能够接收串口发送过来的数据。

将bt_host_uart_dfu.exe 和 application.gbl放在同一个文件夹里面,在该文件夹下打开power shell执行如下指令

 .\bt_host_uart_dfu.exe -u COM14 -f -l 4 -b 115200 .\application.gbl
  • -u指定串口号
  • -f 表示禁止使用流控
  • -l 4 指定log日志级别
  • -b 指定波特率

特别注意:bt_host_uart_dfu.exe默认是开启流控的,如果你的bootloader没有开启流控,一定要加上-f参数,否者你会看到数据发出来了但是对方却怎么也收不到

bt_host_uart_dfu.exe 执行的最初会发送指令20 00 FF 02,固件收到这个数据之后就进入bootloader模式。


#define BOOTLOADER_RESET_REASON_BOOTLOAD      0x0202u
#define BOOTLOADER_RESET_SIGNATURE_VALID      0xF00Fu
#define SRAM_BASE                            (0x20000000UL) 
void bootloader_mode(void)
{BootloaderResetCause_t *cause = (BootloaderResetCause_t *) (SRAM_BASE);cause->reason = BOOTLOADER_RESET_REASON_BOOTLOAD;cause->signature = BOOTLOADER_RESET_SIGNATURE_VALID;CHIP_Reset();
}

之后不出意外就可以升级成功了。

四 改进bootloader

BGAPI默认是单区更新的,也就是bootloader会把收到的新固件直接覆盖掉原来的固件。如果在升级的过程中被中断了,那么设备将一直处于bootloader模式。

通过下面几步操作可以实现双区更新,并且升级过程被中断还可以启动老的固件。

在这里插入图片描述

  1. 修改btl_bootloader.c的flashData函数
static void flashData(uint32_t address,uint8_t  data[],size_t   length)
{const uint32_t pageSize = (uint32_t)FLASH_PAGE_SIZE;//ching: 默认是写到了0x4000地址,这里改成0x5C000地址处,address传过来的地址默认以0x4000为基地址address += 360448;//0x5C000 - 0x4000 = 360448, 加360448偏移到0x5C000地址处// Erase the page if write starts at a page boundaryif (address % pageSize == 0UL) {flash_erasePage(address);}// Erase all pages that start inside the write rangefor (uint32_t pageAddress = (address + pageSize) & ~(pageSize - 1UL);pageAddress < (address + length);pageAddress += pageSize) {flash_erasePage(pageAddress);}flash_writeBuffer_dma(address, data, length, SL_GBL_MSC_LDMA_CHANNEL);
}
  1. 修改btl_bootloader.c的bootload_applicationCallback函数
#define PACK_LEN  1024
/*** @ching:* @brief 将0x5C000地址处的固件全部搬运到0x4000地址处* @param length 已经接收到的新固件长度*/
static void install_application(uint32_t length)
{const uint32_t pageSize = (uint32_t)FLASH_PAGE_SIZE;uint32_t bak_address = 0x5C000;uint32_t write_address = 0x4000;uint8_t buffer[PACK_LEN];uint16_t seg = length / PACK_LEN;if(length % PACK_LEN){seg += 1;}LOGD("seg: %d\n", seg);for(int i = 0; i < seg; i++){LOGD("write_address: %08x\n", write_address);if(write_address % pageSize == 0){flash_erasePage(write_address);}memset(buffer, 0, PACK_LEN);memcpy(buffer, (uint32_t *)(bak_address + i * PACK_LEN), PACK_LEN);flash_writeBuffer(write_address, buffer, PACK_LEN);write_address += PACK_LEN;}
}
void bootload_applicationCallback(uint32_t address,uint8_t  data[],size_t   length,void     *context)
{static uint32_t app_length = 0;(void)context;//ching: 使用一个特殊的长度值来判断是否进行搬运工作if(length == 0xA5A5A5A5){//copy 0x5C000内容到0x4000 长度 app_lengthLOGD("all length: %d\n", app_length);install_application(app_length);app_length = 0;return;}// Check if addresses to write to are within writeable spaceif ((address < (uint32_t)(mainBootloaderTable->startOfAppSpace))|| ((address + length)> (uint32_t)(mainBootloaderTable->endOfAppSpace))) {BTL_DEBUG_PRINT("OOB 0x");BTL_DEBUG_PRINT_WORD_HEX(address);BTL_DEBUG_PRINT_LF();return;}//ching: 记录新固件的长度app_length += length;flashData(address, data, length);
}
  1. 修改btl_comm_bgapi_common.c的bootloader_bgapi_communication_main函数
    当收到更新完成指令后调用applicationCallback回调并传入len = 0xA5A5A5A5
else if (command.header.class == BGAPI_PACKET_CLASS_SYSTEM) {// BGAPI System commandswitch (command.header.command) {case SYSTEM_RESET:LOGD("Reset request\n");//ching: 长度传0xA5A5A5A5,新固件已经接收完成,开始搬运工作parseCb->applicationCallback(0, NULL, 0xA5A5A5A5, NULL);break;

完成以上步骤之后,bootloader就实现了双区更新的功能。


http://www.ppmy.cn/news/25818.html

相关文章

程序人生 - 学习和分享

文章目录记于 230217学习安排泛学AI 和 未来记于 230217 刚入行时&#xff0c;经常看到技术博客中&#xff0c;博主们分享生活&#xff0c;比如相亲、上班生活&#xff0c;甚至还有人发结婚照。这个栏目通常被称为&#xff1a;程序人生。 这个现象已经很久没看到了&#xff0c…

Mars3D Studio 的使用方法

Mars3D Studio的使用 1、介绍&#xff1a; mars3d Studio是mars3d研发团队于近期研发上线的一款 场景可视化编辑平台。拥有资源存档、团队协作、定制材质等丰富的功能。可以实现零代码构建一个可视化三维场景。 2、功能介绍 &#xff08;1&#xff09;数据上传&#xff1a…

Spring MVC 之Tomcat启动流程

从web.xml说起在开始 Spring MVC 的分析之前&#xff0c;先来聊一聊 Java 初学者接触的最多的 Java Web 基础。还记得我的第一个 Web 工程是由 Servlet、Velocity 和 Filter 来完成的&#xff0c;那时几乎所有人都是根据 Servlet、JSP 和 Filter 来编写自己的第一个 Hello Worl…

CD20靶向药物|适应症|市场销售-上市药品前景分析

CD20是靶向治疗的第一个靶点&#xff0c;是B细胞淋巴瘤的现代治疗药物。CD20作为治疗剂的使用被认为是方便的&#xff0c;原因有二。首先&#xff0c;在 CD20 阳性肿瘤的情况下&#xff0c;这种受体大量存在于 B 淋巴细胞表面——每个细胞大约有十万个分子。其次&#xff0c;干…

【面试题】前端 移动端自适应?

移动端 h5 开发中有一个绕不开的话题&#xff1a;移动端自适应方案。移动端的设备尺寸不尽相同&#xff0c;要把 UI 设计图较好地展示在移动端上&#xff0c;需要让 h5 页面能自适应设备尺寸。接下来将对移动端自适应的相关概念、方案和其他一些常见问题做个介绍。概念简介大厂…

使用docker-compose部署RocketMQ5.0

简介&#xff1a;使用docker-compose部署rocketmq5.0。文中会介绍docker-compose版本以及需要注意的项第一步&#xff1a;进入hub.docker.com搜索rocketmq我们选择第一个&#xff0c;因为第一个是7个月前更新的&#xff0c;&#xff08;我看有很多博客使用的依旧是最下面的那种…

[C++]服务器与客户端建立连接与检测断开的demo

该程序在IP127.0.0.1以及端口5000环境下测试 有一段时间没有在Windows下用C进行网络编程了&#xff0c;这段日子都在做QT的网络编程和OpenCV的图像识别。 今天重新写个Windows下C的&#xff0c;基于TCP的双端连接建立与断开检测的demo&#xff0c;巩固下自己Windows下的网络编程…

举个栗子~Tableau 技巧(251):统一多个工作表的坐标轴范围

在工作汇报场景&#xff0c;有一个很常见、很多数据粉反馈的需求&#xff1a;同一看板上的两个图表&#xff0c;因为轴范围不一致&#xff08;如下图&#xff09;&#xff0c;很难直观比较。有什么办法可以统一它们的坐标轴范围呢&#xff1f; 类似需求&#xff0c;不论两个还是…