RT-Thread 使用HTTP固件下载方式进行OTA远程升级

参考资料:RT-T官网资料如下链接所示

STM32通用Bootloader (rt-thread.org)

1.app程序env配置过程

参考上述资料中"制作 app 固件"章节,分区大小根据自己设备而定,以下是我以407VET6为例设置的fal分区

notes:上述分区是由片内flash(on-chip)和外部flash(W25Q64)两部分分区构成,关于外部flash的配置和使用参考文章"RT-T下使用easyflash的配置过程_rtthread easyflash-CSDN博客"

我使用的工程逻辑是先把升级文件通过HTTP下载到外部flash"download"分区中,然后跳转到bootloat里面进行升级;

2.制作bootload bsp工程

在env中进行配置和裁剪功能,主要包括FAL相关配置、on-chip、spi、agile_upgrade相关配置,尽量裁剪到最简:

2.1 关于FAL相关配置、on-chip、spi等相关配置参考文章 RT-T下使用easyflash的配置过程_rtthread easyflash-CSDN博客

2.2 agile_upgrade配置

2.3 修改main函数

下边是部分参考代码

#include "main.h"
#include "fal.h"
#include <agile_upgrade.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

//app启动地址
#define BOOT_APP_ADDR 0x08010000


extern const struct agile_upgrade_ops agile_upgrade_fal_ops;

static uint32_t _written_len = 0;
static uint32_t _total_len = 0;

static void step_hook(int step) { LOG_D("step: %d\r\n", step); }

static void error_hook(int step, int code) { LOG_E("step: %d, err: %d\r\n", step, code); }

static void progress_hook(uint32_t cur_size, uint32_t total_size) {
    _written_len = cur_size;
    _total_len = total_size;
}

void qbt_jump_to_app(void)
{
    typedef void (*app_func_t)(void);
    u32 app_addr = BOOT_APP_ADDR;
    u32 stk_addr = *((__IO uint32_t *)app_addr);
    app_func_t app_func = (app_func_t)(*((__IO uint32_t *)(app_addr + 4)));

    if ((((u32)app_func & 0xff000000) != 0x08000000) || ((stk_addr & 0x2ff00000) != 0x20000000))
    {
        LOG_E("No legitimate application.");
        return;
    }

    LOG_I("Jump to application running ... \n");
    rt_thread_mdelay(200);
    
    __disable_irq();

    for(int i=0; i<128; i++)
    {
        __NVIC_DisableIRQ((IRQn_Type)i);
        __NVIC_ClearPendingIRQ((IRQn_Type)i);
    }
    
    SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;
    
    
    __set_CONTROL(0);
    __set_MSP(stk_addr);
    
    app_func();//Jump to application running
    
    LOG_E("Qboot jump to application fail.");
}

int main(void)
{
	
    agile_upgrade_set_step_hook(step_hook);
    agile_upgrade_set_error_hook(error_hook);
    agile_upgrade_set_progress_hook(progress_hook);

    agile_upgrade_t src_agu = {0};
    src_agu.name = "download";
    src_agu.user_data = "download";
    src_agu.ops = &agile_upgrade_fal_ops;

    agile_upgrade_t dst_agu = {0};
    dst_agu.name = "app";
    dst_agu.user_data = "app";
    dst_agu.ops = &agile_upgrade_fal_ops;

    agile_upgrade_release(&src_agu, &dst_agu, 1);
		
    LOG_D("Written len: %u, total len: %u\r\n", _written_len, _total_len);

	qbt_jump_to_app();
	
    return 0;
}

3.实现http远程升级

参考上述资料中"更多固件下载方式"章节,以下是配置

​3.1 在控制台执行命令"http_ota http://xxx/xxx/rtthreadf.rbl “,url更换成自己的

4.遇到的问题

4.1bootload程序编译报错

原因:link.sct文件中设置的内存大小为64k,但是编译后生成的code代码大小已经68k左右

解决:1.设置优化等级;2.对冗余函数的优化

优化后code代码在40k左右

参考资料:关于ARM Keil5 Optimization level 优化等级的一些分析_keil optimization_夜星辰2023的博客-CSDN博客

MDK中One ELF Section per Function选项功能探究_iceiilin的博客-CSDN博客

4.2 bootload程序进入死循环,没有跳转到app分区

原因:

        4.2.1 程序中通过万能驱动,spi通讯查找外部flash(W25Q16设备失败);

        4.2.2 只在"stm32f4xx_hal_msp.c“中修改spi1相关引脚配置,其他地方可能没有进行配置;

解决:通过STM32CubeMX配置spi1并生成工程

4.3 跳转到app分区后程序不能正常运行

原因:app分区地址设置错误导致修改中断向量表的跳转基地址错误

解决:#define RT_APP_PART_ADDR 0x08010000 0x10000:64k

AT32开发板中直接修改中断向量表 改为 0x10000

#define VECT_TAB_OFFSET 0x10000

STM32中通过函数实现:

/**
 * Function    ota_app_vtor_reconfig
 * Description Set Vector Table base location to the start addr of app(RT_APP_PART_ADDR).
*/
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);

4.4在控制台通过"http_ota http://xxx/xxx/rtthreadf.rbl “升级失败问题

解决:修改webclient.c文件两个地方

4.4.1 添加"rt_thread_mdelay(10);"

4.4.2 在1160行添加else

4.5 http升级后在bootload中写往"app"分区写程序失败

现象分析:从http服务器上获取后,开始升级,跳转到bootload中后,从"download"分区往"app"分区搬运程序,写入失败,从新用jlink烧录程序卡死到这一步,如下图所示:

原因:雅特力单片机不同型号,FLAH大小不同,扇区大小也不同,如下图所示为flash大小为4032K和1024K大小的扇区大小

解决:修改board.h文件中FLASH_PAGE_SIZE大小

  • 19
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程小白菜123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值