潘多拉 RT-Thread HTTP 协议固件升级
实验概述
本实验基于 HTTP 客户端实现 RT-Thread HTTP OTA 固件下载器,通过 HTTP 协议从 HTTP 服务器下载升级固件到设备,在潘多拉 IoT 开发板上完成 OTA 升级。HTTP 客户端代码参考 WebClient 软件包 。
虽然 RT-Thread 提供了一些工具简化固件升级的开发工作,但这部分内容对初学者来说仍然具有挑战性。因此,在开始实验之前,建议先阅读《RT-Thread OTA 固件升级》了解一下 OTA 固件升级的相关知识。
特别提示:实验中用到的 bootloader 程序以 bin 文件的形式提供,并且只适用于该 STM32L4 设备平台,文件位于 /bin/bootloader.bin。
硬件说明
本实验使用到潘多拉 IoT Board 的硬件资源如下:
- UART1(Tx:PA9,Rx:PA10)
- 片内 FLASH(512 KBytes)
- 片外 Nor Flash(16 MBytes)
- AP6181 WiFi 模块
分区说明
在本实验中,bootloader 程序和 app 程序存放在 STM32L4 MCU 的内部 Flash 中,download 下载区域存放在外部扩展的 Nor Flash 中。Flash 分区表如下:
分区名称 | 存储位置 | 分区大小 | 起始地址 | 结束地址 | 说明 |
---|---|---|---|---|---|
bootloader | 片内 Flash | 64K | 0x08000000 | 0x0800FFFF | bootloader 程序存储区 |
app | 片内 Flash | 448K | 0x08010000 | 0x0807FFFF | app 应用程序存储区 |
easyflash | Nor Flash | 512K | 0x00000000 | 0x0007FFFF | easyflash 存储区 |
download | Nor Flash | 1M | 0x00080000 | 0x0017FFFF | download 下载存储区 |
wifi_image | Nor Flash | 512K | 0x00180000 | 0x001FFFFF | WiFi 固件存储区 |
font | Nor Flash | 7M | 0x00200000 | 0x008FFFFF | 字库分区 |
filesystem | Nor Flash | 7M | 0x00900000 | 0x00FFFFFF | 文件系统分区 |
分区表定义在 bootloader 程序中,如果需要修改分区表,则需要修改 bootloader 程序。
注意:目前暂不支持用户自定义 bootloader,如果有商用需求,请联系 RT-Thread 获取支持。
示例代码
参考《潘多拉 IoT Board 开发环境》创建工程,在 applications/main.c 中输入如下代码。
#include <rtthread.h>
#include "wifi_config.h"
#include "board.h"
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#define APP_VERSION "2.0.0"
/* 将中断向量表起始地址重新设置为 app 分区的起始地址 */
static int ota_app_vtor_reconfig(void)
{
#define NVIC_VTOR_MASK 0x3FFFFF80
#define RT_APP_PART_ADDR 0x08010000
/* 根据应用设置向量表 */
SCB->VTOR = RT_APP_PART_ADDR & NVIC_VTOR_MASK;
return 0;
}
INIT_BOARD_EXPORT(ota_app_vtor_reconfig);
int main(void)
{
wlan_autoconnect_init();
LOG_D("The current version of APP firmware is %s", APP_VERSION);
return 0;
}
除了 main.c 文件,需要 ota_http.c 文件,它实现了基于 HTTP 的 OTA 固件下载功能。另外还依赖 fal 和 webclient 软件包。ota_http.c 仅有三个 API 接口,介绍如下:
print_progress 函数
static void print_progress(size_t cur_size , size_t total_size);
该函数用于打印文件的下载进度。
http_ota_fw_download 函数
static int http_ota_fw_download(const char* uri);
该函数基于 webclient API 实现了从指定的 URL 下载文件的功能,并将下载的文件存储到 download 分区。
URL 格式示例:http://192.168.1.10:80/rt-thread.rbl
。非 80 端口需要用户指定。如果使用了 TLS 加密连接,请使用 https://192.168.1.10:80/rt-thread.rbl
。
http_ota 函数
void http_ota(uint8_t argc, char **argv);
MSH_CMD_EXPORT(http_ota , OTA by http client: http_ota [url]);
HTTP OTA 入口函数,使用 MSH_CMD_EXPORT
函数将其导出为 http_ota 命令。http_ota 命令需要传入固件下载地址,例如:
http_ota http://192.168.1.10:80/rt-thread.rbl
完整代码:23_iot_ota_http
编译运行
编译工程
$ scons
...
LINK rtthread-stm32l4xx.elf
arm-none-eabi-objcopy -O binary rtthread-stm32l4xx.elf rt-thread.bin
arm-none-eabi-size rtthread-stm32l4xx.elf
text data bss dec hex filename
357752 2460 43680 403892 629b4 rtthread-stm32l4xx.elf
scons: done building targets.
将 bin 文件上传到 STM32(注意地址是 0x8010000)
st-flash write rt-thread.bin 0x8010000
另外还要将 bootloader 上传到地址 0x8000000
st-flash write bootloader.bin 0x8000000
打开串口终端,输出如下内容
[SFUD]Find a Winbond W25Q128 flash chip. Size is 16777216 bytes.
[SFUD]norflash0 flash device is initialize success.
RT-Thread Bootloader Starting...
[D/FAL] (fal_flash_init:61) Flash device | onchip_flash | addr: 0x08000000 | len: 0x00080000 | blk_size: 0x00000800 |initialized.
[D/FAL] (fal_flash_init:61) Flash device | nor_flash | addr: 0x00000000 | len: 0x01000000 | blk_size: 0x00001000 |initialized.
[I/FAL] ==================== FAL partition table ====================
[I/FAL] | name | flash_dev | offset | length |
[I/FAL] -------------------------------------------------------------
[I/FAL] | bootloader | onchip_flash | 0x00000000 | 0x00010000 |
[I/FAL] | app | onchip_flash | 0x00010000 | 0x00070000 |
[I/FAL] | easyflash | nor_flash | 0x00000000 | 0x00080000 |
[I/FAL] | download | nor_flash | 0x00080000 | 0x00100000 |
[I/FAL] | wifi_image | nor_flash | 0x00180000 | 0x00080000 |
[I/FAL] | font | nor_flash | 0x00200000 | 0x00700000 |
[I/FAL] | filesystem | nor_flash | 0x00900000 | 0x00700000 |
[I/FAL] =============================================================
[I/FAL] RT-Thread Flash Abstraction Layer (V0.2.0) initialize success.
[I/OTA] RT-Thread OTA package(V0.2.1) initialize success.
[I/OTA] Verify 'bootloader' partition(fw ver: 1.3, timestamp: 1545134551) success.
Find user application success.
The Bootloader will go to user application now.
\ | /
- RT - Thread Operating System
/ | \ 4.0.1 build Jan 8 2022
2006 - 2019 Copyright by rt-thread team
lwIP-2.0.2 initialized!
[I/sal.skt] Socket Abstraction Layer initialize success.
[SFUD] Find a Winbond flash chip. Size is 16777216 bytes.
[SFUD] w25q128 flash device is initialize success.
msh />[I/FAL] RT-Thread Flash Abstraction Layer (V0.2.0) initialize success.
[I/OTA] RT-Thread OTA package(V0.1.3) initialize success.
[I/OTA] Verify 'wifi_image' partition(fw ver: 1.0, timestamp: 1529386280) success.
[I/WLAN.dev] wlan init success
[I/WLAN.lwip] eth device init ok name:w0
[Flash] EasyFlash V3.2.1 is initialize success.
[Flash] You can get the latest version on https://github.com/armink/EasyFlash .
[D/main] The current version of APP firmware is 1.0.0
msh >