前言
由于项目需要实现OTA功能学习了一下具体实现方法,以备后期查看,有问题的地方随时指正修改
理论
1.什么是OTA
OTA是“over-the-air”的缩写,是一种无线技术,用于在不需要接触设备的情况下向移动设备或物联网设备提供更新、补丁或新版本的软件。OTA更新通常通过无线网络(如Wi-Fi或移动数据)进行,这使得设备可以在不需要任何物理连接的情况下获得更新。这种技术在智能手机、智能家居设备和车载系统等设备中得到广泛应用。
2.什么是BootLoader
BOOTloader是一段特殊的程序,在计算机启动时运行。它的主要作用是读取和加载操作系统。
当计算机启动时,BOOTloader首先加载并启动操作系统。它负责加载内存中的系统映像,并初始化基本硬件设置。BOOTloader还可以提供一些选项,如选择不同的操作系统版本或进入系统恢复模式。
BOOTloader通常存储在只读存储器(如ROM或flash存储器)中,因此不容易遭到破坏或更改。它是系统启动过程中非常重要的一部分,因为如果BOOTloader不能正常工作,则系统将无法启动。
所以我们想实现BootLoader的话要对flash分区,及对内部偏移地址进行指定,OTA主要是一种技术手段,我们主要是实现BootLoader。
正文
本次教程实现的功能是使用网线对STM32F407VGT6进行OTA升级。
BootLoader
- 新建工程
根据自己的实际情况选择芯片及型号后编译下载初始代码,检查芯片及串口功能是否良好。
2. 通过Cube配置功能
我这里使用的SPI3,CSS脚PE1。
点击CubeMX Settings 配置时钟,SPI引脚(片外Flash),串口
3.配置RT-Thread
在项目资源管理器中点击drivers->board.h文件配置 使能SPI、片内Flash
#define BSP_USING_SPI3
#define BSP_USING_ON_CHIP_FLASH
点击RT-Thread Settings 使能SPI、SFUD、FAL、QBOOT驱动程序
在FAL下要勾选FAL使用SFDU驱动程序,这个主要是管理片外Flash
在QBOOT组件下根据自己的需求进行勾选相应的功能
- 编写SFUD驱动及FAL分区
新建w25q.c文件添加如下代码,这个是使用SFUD驱动程序通过SPI对W25Q128抽象化管理。
#include <rtthread.h>
#include "drv_spi.h"
#include "spi_flash_sfud.h"
#define SPI_BUS_NAME "spi3"
#define W25Q_SPI_DEVICE_NAME "spi30"
//#define W25Q_FLASH_NAME "W25Q128"
static int rt_hw_spi_flash_init()
{
rt_err_t ree = RT_EOK;
ree = rt_hw_spi_device_attach(SPI_BUS_NAME, W25Q_SPI_DEVICE_NAME, GPIOE, GPIO_PIN_1);
//ree = rt_hw_spi_device_attach(SPI_BUS_NAME, W25Q_SPI_DEVICE_NAME, GPIOB, GPIO_PIN_6);
/* 使用 SFUD 探测 spi10 从设备,并将 spi10 连接的 flash 初始化为块设备,名称 W25Q128 */
if (RT_NULL == rt_sfud_flash_probe(FAL_USING_NOR_FLASH_DEV_NAME, W25Q_SPI_DEVICE_NAME))
{
return -RT_ERROR;
}
return ree;
}
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
新建fal_cfg.h文件,对flash引入及分配内存,这要注意芯片的flash大小及偏移地址可能不同,我这个是对F404VGT6的,所以要看数据手册进行修改。
#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_
#include <rtconfig.h>
#include <board.h>
#include <rtconfig.h>
#define FLASH_SIZE_GRANULARITY_16K (4 * 16 * 1024)
#define FLASH_SIZE_GRANULARITY_64K (64 * 1024)
#define FLASH_SIZE_GRANULARITY_128K (7 * 128 * 1024)
#define STM32_FLASH_START_ADRESS_16K STM32_FLASH_START_ADRESS
#define STM32_FLASH_START_ADRESS_64K (STM32_FLASH_START_ADRESS_16K + FLASH_SIZE_GRANULARITY_16K)
#define STM32_FLASH_START_ADRESS_128K (STM32_FLASH_START_ADRESS_64K + FLASH_SIZE_GRANULARITY_64K)
/* ===================== Flash device Configuration ========================= */
extern const struct fal_flash_dev stm32_onchip_flash_16k;
extern const struct fal_flash_dev stm32_onchip_flash_64k;
extern const struct fal_flash_dev stm32_onchip_flash_128k;
/* ===================== Flash device Configuration ========================= */
extern struct fal_flash_dev nor_flash0;
#define FAL_FLASH_DEV_TABLE \
{ \
&stm32_onchip_flash_16k, \
&stm32_onchip_flash_64k, \
&stm32_onchip_flash_128k, \
&nor_flash0, \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
//config_data分区必须是128k的整数倍,如果设置为1K,则在OTA升级后会擦除掉config_data分区的数据
//这种配置占用芯片flash太多,如果芯片flash存储空间不够可以考虑将config_data分区放在外部spi flash里
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WORD, "app", "onchip_flash_128k", 0, 768*1024, 0}, \
{FAL_PART_MAGIC_WORD, "config_data","onchip_flash_128k",768*1024, 128*1024, 0}, \
{FAL_PART_MAGIC_WORD, "download", FAL_USING_NOR_FLASH_DEV_NAME,0, 1024*1024, 0}, \
}
/*
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WORD, "config_data", "onchip_flash_128k", 0, 128*1024, 0}, \
{FAL_PART_MAGIC_WORD, "app","onchip_flash_128k",128*1024, 768*1024, 0}, \
{FAL_PART_MAGIC_WORD, "download", FAL_USING_NOR_FLASH_DEV_NAME,0, 1024*1024, 0}, \
}
*/
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */
修改main.c文件,添加FAL头文件及初始化
#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include <fal.h>
int main(void)
{
int count = 1;
fal_init();
while (count++)
{
// LOG_D("Hello RT-Thread!");
rt_thread_mdelay(1000);
}
return RT_EOK;
}
5,下载验证
编译下载验证,只要开到这几条打印就代表BootLoader成功了
APP实现
- 创建工程
复制bootl工程改名为App
2. 测试APP跳转
在RT-Thread Studio 中删除所有软件包,修改main函数,添加中断向量表跳转函数
#include <rtthread.h>
#include "fal.h"
#include <drivers/pin.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#define RT_APP_PART_ADDR 0x08020000
int main(void)
{
int count = 1;
fal_init();
// LOG_D("Hello RT-Thread!");
while (count++)
{
LOG_D("Hello RT-Thread!!!!!!");
rt_thread_mdelay(1000);
}
return RT_EOK;
}
static int ota_app_vtor_reconfig(void)
{
#define NVIC_VTOR_MASK 0xFFFFFF80
/* 根据应用设置向量表 */
SCB->VTOR = RT_APP_PART_ADDR & NVIC_VTOR_MASK;
return 0;
}
INIT_BOARD_EXPORT(ota_app_vtor_reconfig);
然后在linkscripts下修改链接脚本起始地址,和下载地址这个地址是app的起始地址
下载测试后发现可以正常跳转到app程序就OK了
- 配置驱动
接下来实现OTA功能
点击CubeMX Settings,添加以太网外设(根据自己实际引脚配置)
点击RT-Thread Settings添加ota_download、agile_console、agile_telnet、lwip组件
lwip组件下设置为静态ipv4
设置如下:
ota_download
Lwip
agile_telnet
agile_console
到这里就添加结束了,保存后在board.h文件下使能ETH并添加网卡型号
#define BSP_USING_ETH
#ifdef BSP_USING_ETH
#define PHY_USING_LAN8720A
/*#define PHY_USING_DM9161CEP*/
/*#define PHY_USING_DP83848C*/
#endif
编译后会出现一个报错,将这个报错注释掉
3.修改main.c函数
这里添加app的偏移地址,让中断向量表跳转及定义phy复位函数
#include <rtthread.h>
#include "fal.h"
#include <drivers/pin.h>
#include <board.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#define RT_APP_PART_ADDR 0x08020000
#define PHY_RESET_IO GET_PIN(A, 0)
void phy_reset(void)
{
rt_pin_mode(PHY_RESET_IO, PIN_MODE_OUTPUT);
rt_pin_write(PHY_RESET_IO, PIN_HIGH);
rt_thread_mdelay(50);
rt_pin_write(PHY_RESET_IO, PIN_LOW);
rt_thread_mdelay(50);
rt_pin_write(PHY_RESET_IO, PIN_HIGH);
}
int main(void)
{
int count = 1;
fal_init();
LOG_D("Hello RT-Thread!v1.0");
while (count++)
{
LOG_D("Hello RT-Thread!v1.0");
rt_thread_mdelay(1000);
}
return RT_EOK;
}
static int ota_app_vtor_reconfig(void)
{
#define NVIC_VTOR_MASK 0xFFFFFF80
/* 根据应用设置向量表 */
SCB->VTOR = RT_APP_PART_ADDR & NVIC_VTOR_MASK;
return 0;
}
INIT_BOARD_EXPORT(ota_app_vtor_reconfig);
烧入打印如下
4. 验证OTA功能
使用xshell和mywebServer
xshell配置如下IP地址是设备ip
点击连接后会连接上同时打印信息,用法和串口一样
修改main.c函数主要是为了验证 OTA不要下载进去。
将编译好的bin文件打包好,打包软件和打包方式在下图:
压缩算法要与bootloader的压缩方式一样,固件分区名要与fal分区相同,我要下载到app里,如果填写错误会导致QBoot搬运失败。
打开mywebserver,设置如下
服务目录是刚才打包好的的目录,IP地址是本机IP地址,要注意设备与本机IP在同一网段,端口号默认即可
在xshell中输入http_ota http://192.168.1.112:80/rtthread.rbl
这样mywebserver就侦听到了请求,然后将文件传输到指定分区。
如下看效果。
文章来源:https://www.toymoban.com/news/detail-700402.html
文章来源地址https://www.toymoban.com/news/detail-700402.html
到了这里,关于【RT-Thread】使用RT-Thread Studio 配置BootLoader及App实现OTA功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!