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

2023-05-16

开发环境

  • 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

下载MinGW有困难的可以直接下载这个 bt_host_uart_dfu.exe

三 升级

升级的过程如下图:
在这里插入图片描述

  1. 固件(APP)收到 bt_host_uart_dfu.exe 发过来的升级指令:20 00 FF 02,固件收到改指令以后重启并进入bootloader模式
  2. bootloader接收 bt_host_uart_dfu.exe 发送过来的新固件。
  3. bootloader将新固件直接写到APP区域

全部写完以后直接启动APP,在升级过程中如果被中断了,那么设备将一直处于bootloader模式。

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

将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模式。

4.1 升级过程描述

通过下面几步操作可以实现双区更新,并且升级过程被中断还可以启动老的固件。
在这里插入图片描述

  1. 固件(APP)收到 bt_host_uart_dfu.exe 发过来的升级指令:20 00 FF 02,固件收到改指令以后重启并进入bootloader模式
  2. bootloader接收 bt_host_uart_dfu.exe 发送过来的新固件。
  3. bootloader将新固件写到APP_bak区域。

一直重复步骤2和3直到所有固件都接收完成

  1. 新固件验证完成以后,bootloader将APP_bak区域的新固件搬运到APP区域,并启动新的APP

4.2 代码修改

  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 boundary
  if (address % pageSize == 0UL) {
    flash_erasePage(address);
  }

  // Erase all pages that start inside the write range
  for (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_length
      LOGD("all length: %d\n", app_length);
      install_application(app_length);
      app_length = 0;
      return;
  }


  // Check if addresses to write to are within writeable space
  if ((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 command
      switch (command.header.command) {
        case SYSTEM_RESET:
          LOGD("Reset request\n");

          //ching: 长度传0xA5A5A5A5,新固件已经接收完成,开始搬运工作
          parseCb->applicationCallback(0, NULL, 0xA5A5A5A5, NULL);

         
          break;

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

silicon labs平台通过串口升级固件方案 的相关文章

  • 使用catkin进行工程管理

    catkin是什么 这是一个管理ros代码的工程管理工具 xff0c 基于cmake xff0c 但是比cmake多更多功能 xff0c 是cmake上层的代码管理规则 ros之前采用的是ros build xff0c 现在用catkin
  • ROS-melodic 安装 及:rosdep init 和 rosdep update 失败问题解决总结

    正常安装ros流程 ros 安装 melodic sudo sh c 39 etc lsb release amp amp echo 34 deb http mirrors tuna tsinghua edu cn ros ubuntu D
  • ubuntu 安装Opencv4版本后安装Opencv3,并在项目中区分使用

    安装 xff1a ubuntu 安装OpenCV3版本后安装OpenCV4 xff0c 且多版本共存 wyyang2的博客 CSDN博客 https blog csdn net wyyang2 article details 1039894
  • Ubuntu 16.04录屏软件

    Ubuntu 16 04安装录屏软件Simple Screen Recorder https www maartenbaert be simplescreenrecorder https jingyan baidu com article
  • debug时一个非常坑爹的问题——单步调试正常但是运行没结果

    单步调试能得到正确答案 xff0c 运行不出来 本人用的是codeblocks xff0c 20 03版本 话说有一天晚上 xff0c 那个不平凡的夜 xff0c 还有不到十个小时数据结构的实验课就要上交报告了 xff0c 而自己的程序却出
  • DataX使用、同步MySQL数据到HDFS案例

    文章目录 4 DataX使用4 1 DataX使用概述4 1 1 DataX任务提交命令4 1 2 DataX配置文件格式 4 2 同步MySQL数据到HDFS案例4 2 1 MySQLReader之TableMode4 2 1 1 编写配
  • 支持期限提至10年,Ubuntu 18.04 LTS

    给技术最前线加星标 xff0c 每天看技术热点 综合自 xff1a cnBeta COM Solidot Mark Shuttleworth宣布将支持Ubuntu 18 04 LTS长达十年时间 xff0c 让LTS版本的含金量更足 xff
  • 实训第五天:我的页面布局,API接口(一言,天气预报)

    1 不用不用脚本和弹窗获取手机信息 xff0c 用微信公众平台的组件开发能力 open data用于展示微信开放的数据 部分代码 xff1a lt view class 61 34 container 34 gt lt view class
  • 这是一个失败的程序员

    写程序至今 xff0c 未入门 xff0c 什么都不懂 xff01
  • adb dumpsys命令用法

    dumpsys命令功能很强大 xff0c 能dump系统服务的各种状态 xff0c 非常有必要熟悉该命令的用法以及含义 一 概述 1 1 dumpsys命令用法 可通过dumpsys命令查询系统服务的运行状态 对象的成员变量属性值 xff0
  • matlab subs函数

    在matlab命令行查看subs函数的帮助 subs函数一共有三种使用方法 xff1a subs s old new subs s new subs s 点击 subs 的参考页可以看到下面的详细说明 第一种使用方法 说明 xff1a su
  • Docker----如何更改docker镜像的存储路径

    原文链接 Docker 如何更改docker镜像的存储路径 背景 随着docker容器已经镜像的使用 xff0c docker镜像占用大量磁盘空间 xff0c 当然可以通过不断的删除镜像或者设置定时任务删除镜像 xff0c 但是有时候还是挺
  • ROS的geometry_msgs/PoseWithCovarianceStamped Message 消息格式

    溪西创客小屋 geometry msgs PoseWithCovarianceStamped Message Raw Message Definition This expresses an estimated pose with a re
  • 线程和进程的理解

    一 介绍线程和进程 什么是线程 是程序执行的最小单位 xff0c 一个进程在执行过程中产生建多个线程 xff0c 同一进程中的 多个 线程共享同一块内存空间及系统资源 xff0c 线程数进程的一部分 xff0c 因此线程数也被称为轻量级进程
  • Windows安装tensorflow-gpu

    0 想在Windows环境安装tensorflow gpu xff0c 显卡必须是N卡 xff08 本文以3070显卡为例进行说明 xff09 1 安装好Anaconda以及Pycharm xff08 安装教程 xff1a https ww
  • 16.进程-进程间通信概述

    进程间通信 xff0c 也就是大家常说的 IPC Inter Process Communication xff0c 指的是不同的进程间进行交流 xff0c 本质上就是进程之间发送和接收数据 xff1b 本质上 xff0c 信号也是属于进程
  • PNP问题-位姿估计方法梳理(pose estimation)

    tags 单目视觉 位姿测量 目标3D精确模型已知 xff08 建立2D 3D对应关系 xff09 xff1a 点特征 P3P问题 基于针孔成像模型 Gao的方法 xff08 opencv emgucv xff09 Kneip 的 P3P
  • 室内无人机定位导航

    个人观点 xff1a 可研究的方向 1 静态规划方面 xff1a 将控制与定位结合起来 xff1b 修正回环检测误差 xff0c 提高算法的计算精度和执行效率 xff1b 2 动态规划方面 xff1a 用神经网络识别运动物体的行进方向 xf
  • 树莓派3b程序控制无人机 (一)——电脑连树莓派

    设备 xff1a 树莓派3b xff08 备有键盘 xff0c 鼠标 xff09 xff1b win10 x64笔记本 xff1b UAV pixhawk飞控板 etc network interfaces 的设置可参考以下链接 xff1a
  • 三星6410裸机程序开发

    网上关于S3C6410裸机程序开发都是基于RealView RVDS 也有一些是基于eclipse的 xff0c 但都没有详细介绍在eclipse中如何建立S3C6410裸机程序工程 尽管友善之臂提供的6410裸机程序示例使用了eclips

随机推荐

  • linux socket can程序cantool

    最近写了个自认为不错的基于linux socket can程序 xff0c 主要功能 xff1a 程序具备全部CAN功能 xff0c 包括CAN标准帧 扩展帧接收与发送 CAN总线错误判断 环回等功能适用基于LINUX SOCKET机制实现
  • Linux CAN编程详解

    Linux CAN编程详解 是一篇百度文库上的文档 xff0c 主要描述了以下内容 xff1a can总线介绍及其帧类型 xff1b Linux 系统中CAN 接口配置 xff1b Linux 系统中CAN 接口应用程序开发 xff1b L
  • c++中冒号(:)和双冒号(::)的用法和c/c++ 位域结构体

    1 冒号 xff08 xff09 用法 xff08 1 xff09 表示结构体内 位域的定义 xff08 即该变量占几个bit空间 xff09 typedef struct XXX unsigned char a 4 unsigned ch
  • CAN总线与RS485的比较

    最近一个项目总体方案设计为分布式系统 xff0c 于是在通讯上纠结于CAN总线还是RS485 因此在网上搜索一些了一些关于RS485和CAN总线的资料 xff0c 除进一步认识RS485通讯特点外 xff0c 认识了CAN总线的特点及其与R
  • Linux内核中常见内存分配函数

    1 原理说明 Linux 内核中采 用了一种同时适用于32 位和64 位系统的内 存分页模型 xff0c 对于32 位系统来说 xff0c 两级页表足够用了 xff0c 而在x86 64 系 统中 xff0c 用到了四级页表 xff0c 如
  • MII、RMII、GMII接口的详细介绍

    概述 xff1a MII Media Independent Interface 介质无关接口 或称为媒体独立接口 xff0c 它是IEEE 802 3定义的以太网行业标准 它包括一个数据接口和一个MAC和PHY之间的管理接口 数据接口包括
  • Visual Studio .NET 2003中出现“无法启动调试 没有正确安装调试器”错误的解决方法

    最近 xff0c 装了Visual Studio NET 2010后 xff0c 在Visual Studio NET 2003中进行运行调试 xff0c 突然出现 无法启动调试 没有正确安装调试器 提示 xff0c 不能向往常一样进入控制
  • ftime()函数

    ftime 函数取得目前的时间和日期 相关函数 xff1a time ctime gettimeofday 表头文件 xff1a include lt sys timeb h gt 函数定义 xff1a int ftime struct t
  • 几道经典的嵌入式C语言笔试题

    C语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法 这些年 xff0c 我既参加也组织了许多这种测试 xff0c 在这过程中我意识到这些测试能为带面试者和被面试者提供许多有用信息 xff0c 此外 xff0c 撇开面试的压力不谈 xf
  • 解决eclipse中出现Resource is out of sync with the file system问题

    作者 xff1a reille 本博客网址 xff1a http blog csdn net reille xff0c 转载本博客原创文章请注明出处 本文内容概要 xff1a 解决eclipse中出现Resource is out of s
  • 代码中特殊的注释技术——TODO、FIXME和XXX的用处

    作者 xff1a reille 本博客网址 xff1a http blog csdn net reille xff0c 转载本博客原创文章请注明出处 本文内容概要 xff1a 代码中特殊的注释技术 TODO FIXME和XXX的用处 更多请
  • 个人网站梦想终实现即reille blog | velep.com成长之路

    最近用wordpress开放平台软件建立了一个属于自己的个人博客网站velep com即reille blog xff0c 中文名 xff1a reille博客 xff0c 圆了自己多年来的梦想 xff0c 感觉像是在这大千互联网里找到了属
  • PaddleX树莓派部署--神经计算棒2代

    PaddleX树莓派部署 神经计算棒2代 PaddleX支持在树莓派上插入NCS2 神经计算棒2代 通过OpenVINO部署PadlleX训练出来的分类模型 注意 xff1a 目前仅支持分类模型 仅支持Armv7hf的树莓派 前置条件 OS
  • Hbase数据结构和体系架构

    1 HBase与关系数据库比较 1 xff09 行式数据库 优点 1 数据存储在一起 2 INSERT UPDATE数据较容易 缺点 1 选择操作 xff08 select xff09 时 xff0c 即使是几行所有数据也要被读取 2 xf
  • Ubuntu安装remmina

    官方教程 xff1a https github com FreeRDP Remmina wiki sudo apt span class hljs attribute add span span class hljs attribute r
  • ros运行rviz时出现QXcbConnection: XCB error: 148错误

    原因 xff1a 由于使用了vnc远程控制下位机 xff0c rviz是一个基于opengl开发的图形插件 xff0c 需要使用理论的屏幕参数 xff08 thetis screen xff09 xff0c 使用vnc会导致屏幕参数值不对
  • FreeRTOS内核源码解读之-------系统启动(三)

    前面文章两篇文章介绍了FreeRTOS的启动过程 xff0c 但是有些问题还没有解决 xff0c 在本篇文章中将会逐一解决 首先 xff0c 在 FreeRTOS内核源码解读之 系统启动 xff08 一 xff09 中提到Cortex M4
  • C++ MathGL 二维数据绘图

    C 43 43 MathGL环境搭建参考 https blog csdn net vaincury article details 105438971 MathGL官网 http mathgl sourceforge net doc en
  • 面经——小马智行2022秋招嵌入式

    笔试 单选 xff1a 双向链表 实时操作系统特征 死锁的必要条件 小端对齐时 xff0c 不用sizeof判断int长度 const typedef 结构体字节对齐 堆和栈 n阶阶乘的时间复杂度 tcpudp static 常见通信协议
  • silicon labs平台通过串口升级固件方案

    开发环境 windowssimplicity studio 5geck sdk 4 1 一 bootloader 新建BGAPI UART DFU工程 工程新建完成以后看一下linkerfile ld文件的flash和ram的配置跟自己的a