【RT-Thread】STM32F1片内Flash实现Bootloader


前言

RT-Thread官网对于Bootloader的实现方案有非常详细的描述,目前支持F1、F4、L4系列单片机。教程中bootloader制作是基于stm32f407为硬件平台,且app制作是基于标准版rt-thread-v4.1.0的stm32f407-atk-explorer例程,app开发环境使用MDK5。本文基于stm32f1精英开发板为硬件平台,使用RT-Thread Studio开发环境进行app制作,实现bootloader功能。

官方教程:https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/application-note/system/rtboot/an0028-rtboot


1. 开发环境搭建

  • 硬件平台:STM32F103ZET6(精英板)
  • 软件版本:rt-thread-v4.1.0
  • 开发环境:RT-Thread Studio
  • 串口工具:Xshell 7、友善串口助手
  • 烧录工具:J-Link、J-Flash V6.86

2. Bootloader制作

1)硬件配置

STM32F103ZET6芯片的片内Flash即ROM大小为512K,RAM大小为64K。从起始地址的前64K(0x10000)用于bootloader,因此app的偏移地址为0x10000。通常定义app区和download区的大小一样,此处定义为128K。片内Flash剩余的192K未作定义,例如还可以根据需求定义factory(出厂固件区)、easyflash(数据库区)等。

在这里插入图片描述
2)加密压缩

加密压缩算法是可选项,用户可自行选择,但必须保持与后续OTA固件打包时候的选择完全一致。

在这里插入图片描述

3)logo配置

原本想制作一个好看点的logo,但是按官方给的在线生成方式,复制粘贴的logo图标提示字符不合法,最后只能输入数字和字母。

在线生成logo:http://patorjk.com/software/taag/#p=display&f=3D%20Diagonal&t=Zero%20Boot

在这里插入图片描述

4)生成bootloader

以上配置完成后,生成并自动下载得到一个压缩包文件:rt-boot.zip,解压得到rtboot_f1.bin即为bootloader文件。

5)烧录bootloader

使用J-Flash打开rtboot_f1.bin文件,起始地址设置为:0x08000000。执行Target->Promgram & Verify后,Start Application即可运行bootoader程序。为了方便查看上电过程日志,需要先将串口连接,波特率115200。

在调试过程中发现如果使用开发板的miniUSB线连接XShell7或SecureCRT9.1工具时,无法正常复位芯片且无法连接串口,原因暂未找出。

在这里插入图片描述
这里使用友善串口助手观察bootloader日志输出,复位后输出信息与bootloadr配置过程一致,说明bootloader制作成功。


3. APP程序制作

1)新建工程

在标准版rt-thread-v4.1.0的bsp中有stm32f103-atk-warshipv3例程,因此可以通过Env工具的menuconfig进行app的制作,使用RT-Thread Studio新建一个基于ATK-WARSHIPV3开发板的工程。

在这里插入图片描述

提示:官方例程使用的stm32f103-atk-warshipv3对应战舰开发板,它与精英板的单片机型号都是STM32F103ZET6,只是外设资源有差异,不影响本次测试。

2)FLASH配置

本次使用片内Flash存储,需要在硬件配置中开启: Enable on-chip FLASH
在这里插入图片描述

3)OTA配置

ota_downloader软件包在软件包->IoT-物联网分类中,可以直接通过搜索快速定位。

在这里插入图片描述

4)FAL配置

FAL配置在软件包->系统包中,开启FAL:Flash抽象层实现,管理 Flash设备和分区。在fal_cfg.h上定义分区表是app制作的关键内容,将在下文详细介绍。

在这里插入图片描述

5)添加fal_cfg.h

上述配置完成后,需要用户手动完成对FAL分区的定义,即在工程目录packages/fal-v1.0.0/inc文件夹下新建fal_cfg.h头文件,也可以从官方例程得到模板文件。关键内容为:

  1. 定义app起始地址;
  2. 声明片内flash;
  3. 定义FLASH设备表;
  4. 定义FAL抽象层分区表。

添加以下源代码:fal_cfg.h

/*
 * Date           Author       zlp
 * 2022-11-6      SummerGift   first version
 */
#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_

#include <rtthread.h>
#include <board.h>

/* 1.定义app起始地址 */
#define RT_APP_PART_ADDR    0x08010000

/* 2.声明片内FLASH */
extern const struct fal_flash_dev stm32_onchip_flash;

/* ====================== Flash Configuration ========================== */
/* 3.定义FLASH设备表 */
#define FAL_FLASH_DEV_TABLE                                          \
{                                                                    \
    &stm32_onchip_flash,                                         \
}

/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG

/* 4.定义FAL抽象层分区表 */
#define FAL_PART_TABLE                                                                                                     \
{                                                                                                                          \
    {FAL_PART_MAGIC_WROD, "bootloader", "onchip_flash",          0,      64 * 1024, 0}, \
    {FAL_PART_MAGIC_WROD, "app",        "onchip_flash",    0x10000,     128 * 1024, 0}, \
    {FAL_PART_MAGIC_WROD, "download",   "onchip_flash",    0x30000,     128 * 1024, 0}, \
}
#endif 

#endif /* _FAL_CFG_H_ */

6)修改main.c

在主程序中需要添加以下内容:

  1. 包含fal.h头文件,调用fal_init();
  2. 定义并打印输出版本信息;
  3. 中断向量重映射;

添加以下源代码:main.c

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-11-06     obito0   first version
 */

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#include "fal.h"

/* defined the LED0 pin: PB5 */
#define LED0_PIN    GET_PIN(B, 5)
/* defined the LED1 pin: PE5 */
#define LED1_PIN    GET_PIN(E, 5)

int main(void)
{
    /* set LED0 pin mode to output */
    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
    /* set LED1 pin mode to output */
    rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);

    fal_init();

    rt_kprintf("APP firmware version: %s", "V1.0.0");

    while (1)
    {
        rt_pin_write(LED0_PIN, PIN_LOW);
        rt_pin_write(LED1_PIN, PIN_HIGH);
        rt_thread_mdelay(100);
        rt_pin_write(LED0_PIN, PIN_HIGH);
        rt_pin_write(LED1_PIN, PIN_LOW);
        rt_thread_mdelay(200);
    }
}

/* 中断向量重映射 */
static int ota_app_vtor_reconfig(void)
{
    #define NVIC_VTOR_MASK   0x3FFFFF80
    /* Set the Vector Table base location by user application firmware definition */
    SCB->VTOR = RT_APP_PART_ADDR & NVIC_VTOR_MASK;

    return 0;
}
INIT_BOARD_EXPORT(ota_app_vtor_reconfig);

7)修改链接脚本

在board/linker_scripts目录下有三个链接脚本文件,分别对应于三种不同开发环境:link.icf(IAR)、link.lds(RT-Thread Studio)、link.sct(MDK5)。在此打开link.lds链接脚本编辑器,修改可用存储区域中的ROM起始地址和大小,对应于配置bootloader时设置的app起始地址和大小。

在这里插入图片描述

以上完成app的制作,编译输出rtthread.bin文件。

8)烧录app

直接在RT-Thread Studio执行下载程序,正常现象是下载完成后芯片自动复位,先执行bootloader程序,在启动程序中检测到app程序,自动跳转到app程序。

在这里插入图片描述
以上过程验证了bootloader和app的功能,接下来需要通过Ymodem实现从PC端通过串口下载升级程序。


4. OTA固件打包

在进行YModem下载程序之前需要先对app应用程序固件进行打包,此前已经烧录的app版本为V1.0.0,为了更直观的验证升级结果,对V1.0.0版本的app程序做以下修改:

修改内容:
1)修改版本号为V2.0.0;
2)修改led指示灯显示效果;
3)增加FAL的factory分区;

编译输出rtthread.bin文件,通过rt_ota_packaging_tool.exe工具进行打包,输出rtthread.rbl即为YModem可传输的文件。

注:压缩和加密算法必须与制作bootloader时的选择保持一致!

在这里插入图片描述

OTA固件打包工具:https://github.com/RT-Thread-packages/ota_downloader


5. Ymodem升级

YModem协议是由XModem协议演变而来的一种非常高效的文件传输协议,XShell、SecureCRT等工具均支持YModem协议传输。所以此时将串口工具切换为XShell 7,连接成功后按回车键确认msh命令正常,并按tab或输入help查看msh命令中是否有ymodem_ota。

注:如果msh命令中列表中没有ymodem_ota命令,说明在app制作过程中,没有配置ymodem_ota软件包,需要返回到app程序V1.0.0的制作过程。

输入ymodem_ota命令后,终端输出提示信息选择需要传输的文件,并输出“C”字符等待。右键依次选择:传输->Ymodem->用Ymodem发送,通过文件对话框选中上述打包好的rtthread.rbl文件,以下为传输完成后的界面:

说明:此界面未实现正常的自动重启,正常情况下传输完成后应自动重启,与上述烧录bootloader时的复位失败为同一问题!

在这里插入图片描述

由于在XShell7终端连接时自动复位失败,无法查看确认下载成功与否。此时关闭XShell7终端,将串口连接工具切回友善调试助手,连接之后通过手动复位查看bootloader启动时是否将downloader区的V2.0.0程序搬运到app运行区,并跳转到app区执行V2.0.0程序。

手动复位后的结果如下:

在这里插入图片描述
在这里插入图片描述
在bootloader程序中主要执行以下过程:

  1. 校验downloader区;
  2. 擦除app区;
  3. 写入app区;
  4. 校验app区;
  5. 跳转到app区;

最终实现app程序V2.0.0的升级。


小结

本文基本实现STM32F1的Bootloader功能,并通过Ymodem进行程序升级,但这只是从PC端到设备升级,过程中也还存一些小问题,并不算真正意义上的OTA远程升级。当然通过串口通讯也可方便的扩展到其它无线通讯模块实现OTA功能。此外,RT-Thread官方给出的这个Bootloader升级方案确实极大的简化了OTA开发过程,提高了开发效率。但由于生成的Bootloader文件是一个bin固件包,对于想深入了解Bootloader程序内部实现逻辑的开发者来说,如果给用户开放出Bootloader的源码,似乎更符合RT-Thread的开源特色。

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值