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

开发环境

  • 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就实现了双区更新的功能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Silicon Labs CP210x USB转UART桥接器是一种通过USB接口连接计算机和UART设备的芯片。它可以将USB接口转换为串行通信接口,使计算机能够直接与UART设备进行通信。 CP210x系列芯片采用了Silicon Labs独有的单芯片USB桥接器解决方案,具有高度集成的优势。它内部集成了USB控制器、UART控制器和相关接口电路,只需少量外部元件即可实现电路设计。同时,CP210x还支持广泛的操作系统和开发环境,如Windows、Linux、Mac OS等,方便开发者使用。 CP210x具有丰富的功能和性能。它具备高速传输能力,支持数据传输速率高达3Mbps,可以满足大部分应用的需求。此外,它还支持多种常见的UART通信协议,如RS-232、RS-422和RS-485等。通过使用CP210x,开发者可以简化串行通信设计,提高产品开发效率。 CP210x的工作原理是通过USB接口与计算机进行连接,并利用USB协议进行数据传输。它将USB接收到的数据进行解析,并通过UART接口将数据发送到目标设备。同样,它也可以接收UART设备发送的数据,并通过USB接口传输给计算机进行处理。这种转换过程是透明的,无需开发者关心具体的实现细节。 总的来说,Silicon Labs CP210x USB转UART桥接器是一种功能强大、易于使用的芯片,可实现USB和UART之间的数据传输连接。它广泛应用于各种领域,如工业控制、嵌入式系统、通信设备等,为设备的连接和通信提供了便利。 ### 回答2: Silicon Labs CP210x USB到UART桥接器是一种用于将USB接口转换为UART(通用异步收发器)接口的芯片。它允许计算机通过USB端口与串行设备进行通信,如微控制器、传感器、模块等。 CP210x系列芯片具有许多优点。首先,它们支持多种数据传输速率,从300 bps到3 Mbps不等,因此非常适用于不同的应用需求。其次,它们具有广泛的操作系统兼容性,包括Windows、Mac和Linux等主流系统。 另外,CP210x芯片也提供多种GPIO引脚,用于连接外部设备,如LED灯、按钮等。这些引脚可以方便地用于与外部设备的交互。此外,该芯片还具有内置的电源管理功能,能够自动控制供电和休眠模式,降低功耗。 对于开发者来说,CP210x芯片具有友好的集成开发环境(IDE)支持。Silicon Labs提供了官方的开发工具和文档,包括驱动程序、示例代码和用户手册等,使开发过程更加便捷和高效。 总之,CP210x USB到UART桥接器是一种功能强大的芯片,可以轻松实现USB与UART之间的数据传输。它适用于各种应用场景,包括嵌入式系统、物联网设备和消费电子产品等。 ### 回答3: Silicon Labs CP210x USB to UART Bridge是一款由硅实验室(Silicon Labs)开发的USB到UART(通用异步收发传输器)桥接芯片。它的主要功能是将USB接口转换为UART接口,从而实现电脑或其他USB主机设备与UART设备之间的通信。 由于CP210x桥接芯片支持USB 1.1和USB 2.0标准,因此它可以与广泛的设备兼容。它提供了高达920Kbps的高速UART传输速率,使得数据传输更加高效和稳定。 CP210x桥接芯片还具备丰富的功能和通用性。它支持多种UART模式(如7位/8位数据位、奇偶校验、停止位等)和流控制(如硬件流控制和软件流控制),以满足不同设备的需求。此外,它还支持自动流控制和自动线速率检测功能,大大简化了设计和配置过程。 CP210x桥接芯片还具备良好的电源管理功能。它的低功耗设计有助于延长电池寿命,并提供了多种低功耗模式选择,以适应电源管理需求。 硅实验室为CP210x桥接芯片提供了完整的软件支持。他们提供了Windows、Mac和Linux等操作系统的驱动程序和配置工具,以及USBXpress软件库和示例代码,以便用户可以快速集成和开发。 总之,Silicon Labs CP210x USB to UART Bridge是一款功能丰富、通用性强、性能稳定的USB到UART桥接芯片,为设备之间的通信提供了高效、可靠的解决方案

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值