您的位置:

STM32 OTA固件升级详解

一、STM32OTA升级

STM32OTA是一种支持无线OTA(Over The Air)升级的Firmware Update模块,它能够使得用户在不必使用有线接口的情况下,对物联网设备进行Firmware Update。OTA升级对于物联网设备而言极为常见,因为物联网设备通常分布于较为广阔的区域内,而线缆等常用的有线接口则无法满足其进行升级的需求。例如,一次线下的固件升级需要一个自行车行业的耗时,上百家门店,使用OTA升级调网关和固件环境不超过半天。

在STM32中,OTA功能通过HAL库的netconn socket机制实现。netconn是FreeRTOS对于lwip的TCP/IP协议栈的一种封装,而socket则是netconn的进一步封装。通过这种方式,我们可以非常简单的实现OTA升级功能。

二、STM32OTA升级包添加CRC

在OTA升级过程中,一个非常重要的点就是包的完整性检查。当接收到一份包以后,我们需要验证它的CRC校验值是否正确,如果不正确我们就会认为其是无效的。这样可以保证我们始终在进行OTA升级时都是全程可靠的。在STM32 OTA中,CRC校验的计算和验证工作都是由HAL库中的CRC模块来完成的。

下面是完整的示例代码:

//添加头文件
#include "main.h"
#include "stm32f4xx_hal.h"
#include "lwip/opt.h"
#include "lwip.h"
#include "netif.h"
#include "stm32f4xx_hal_crc.h"
//加入CRC手动操作
static uint32_t UcmCrcCal(uint32_t ucmBuf,uint32_t ucmLen,uint32_t ucmCrc)
{
  uint32_t i;
  uint8_t *pcBuf;
  pcBuf=(uint8_t *)ucmBuf;
  if(pcBuf==NULL)
  {
    return 0;
  }
  for(i=0;i>8)^ucaCrcTable[(ucmCrc&0xff)^pcBuf[i]];
  }
  return ucmCrc;
}

  

三、STM32OTA升级方案

按照我们对OTA的理解,其大致的升级流程应该是这样的:

1.客户端发送请求给服务器,请求进行OTA升级;

2.服务器根据客户端发送的请求,将符合条件的升级包发送给客户端;

3.客户端接收到升级包后进行CRC校验,如果CRC校验通过,则将升级包写入Flash;

4.客户端重启,将已经写入Flash的新代码运行;

在STM32中的OTA实现原理类似于上述流程,但是有一些小的差异。

四、STM32OTA升级例程

下面是一份跟STM32OTA相关的示例代码,其中包括了OTA模块的初始化和netconn socket的使用:

/* Defined in user file */
#include "stm32ota.h"

/* Defined in BSP file */
#include "lwip.h"

static struct netconn* netconn_ota = NULL;

uint8_t generate_ota_request_pkt(uint8_t* pkt_buf, uint16_t max_len, 
                                 uint32_t start_address, uint32_t file_size)
{
    memset(pkt_buf, 0, max_len);
    /* OTA request packet is pre-defined in OTA protocol */
    pkt_buf[0] = STM32_OTA_CMD_REQUEST;  /* Command code */
    /* Start address of target area to be placed with new firmware */
    pkt_buf[1] = (start_address>>8)&0xff;
    pkt_buf[2] = start_address&0xff;
    /* Size of new firmware */
    pkt_buf[3] = (file_size>>24)&0xff;
    pkt_buf[4] = (file_size>>16)&0xff;
    pkt_buf[5] = (file_size>>8)&0xff;
    pkt_buf[6] = file_size&0xff;
    /* Calculate checksum */
    uint16_t crc = crc16_compute(pkt_buf, 7);
    pkt_buf[7] = crc>>8;
    pkt_buf[8] = crc&0xff;

    return 9;
}

HAL_StatusTypeDef stm_ota_request(uint32_t start_addr, uint32_t file_size)
{
    uint8_t ota_buf[20] = {0};
    uint16_t ota_buf_len;
    struct netbuf* recvbuf = NULL;
    uint8_t* pkt_buf;
    uint16_t pkt_len = 0;
    netconn_ota = netconn_new(NETCONN_TCP);
    netconn_connect(netconn_ota, &server_address, server_port);
    /* Generate OTA request packet */
    pkt_buf = ota_buf;
    pkt_len = generate_ota_request_pkt(pkt_buf, 20, start_addr, file_size);
    /* Send OTA request packet to server over TCP connection */
    netconn_write(netconn_ota, pkt_buf, pkt_len, NETCONN_COPY);
    /* Wait for response */
    if (netconn_recv(netconn_ota, &recvbuf) == ERR_OK) {
        /* Successfully received OTA response */
        /* ... */
    }

    return HAL_OK;
}

五、STM32OTA升级电路

对于STM32OTA相关的电路,实现OTA升级所必须的元件主要包括BOOT0/BOOT1引脚和串口(UART)信号线。BOOT0/BOOT1引脚和串口信号线都分别是STM32的GPIO和USART模块提供的。

以下是BOOT0/BOOT1引脚的电路连接图:

六、STM32OTA升级详细流程

STM32 OTA的升级流程非常简单,可以通过以下几个步骤来完成:

1.开启Bootloader模式。

2.建立OTA升级的TCP连接。

3.使用OTA协议进行数据传输。

4.写入Flash并且启动新程序。

下面是流程图:

七、总结

本文对于STM32 OTA升级的相关知识进行了详细的阐述,并通过示例代码和电路图对其进行了实现。OTA升级对于物联网设备而言极为重要,可以使得用户在不必使用有线接口的情况下,对物联网设备进行安全和便捷的升级操作。通过对OTA升级的学习和实践,可以让我们更好的理解物联网设备的工作原理,提高我们在物联网领域中的技术能力和应用水平。