rtthread studio中STM32进行OTA(一)

制作bootloader

我们要使用外部flash作为ota的分区,所以先要添加flash驱动,flash管脚连接如下图:

1.在rtthread studio中建立工程,填写对应的芯片型号及调试串口如图:

2.编译下载如图:

串口打印内容如下:

3.添加flash驱动,点击spi图标和舒SFUD图标
4.打开CUBEMUX,配置spi和串口







5.在目录drive下的board.h问文件里打开spi和片上flash如图:

6.添加flash相关程序,编译下载如图,显示添加flash成功:


flash程序如下:
#include <rtthread.h>
#include “drv_spi.h”
#include “spi_flash_sfud.h”

#define SPI_BUS_NAME “spi1”
#define W25Q_SPI_DEVICE_NAME “spi10”
#define W25Q_FLASH_NAME “W25Q512”
//FAL_USING_NOR_FLASH_DEV_NAME

rt_uint8_t wData[4096] = {“SPI bus write data to W25Q512 flash.”};
rt_uint8_t rData[4096];

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, GPIOA, GPIO_PIN_15);
/* 使用 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);
static void sfud_w25q_sample(void)
{
rt_spi_flash_device_t flash_dev;
sfud_flash_t sfud_dev;
struct rt_device_blk_geometry geometry;

// 1- use sfud api
rt_kprintf("\n 1 - Use SFUD API \n");

sfud_dev = rt_sfud_flash_find_by_dev_name(W25Q_FLASH_NAME);
if(sfud_dev == RT_NULL){
    rt_kprintf("sfud can't find %s device.\n", W25Q_FLASH_NAME);
}else{
    rt_kprintf("sfud device name: %s, sector_count: %d, bytes_per_sector: %d, block_size: %d.\n",
                sfud_dev->name, sfud_dev->chip.capacity / sfud_dev->chip.erase_gran,
                sfud_dev->chip.erase_gran, sfud_dev->chip.erase_gran);

    if(sfud_erase_write(sfud_dev, 0x002000, sizeof(wData), wData) == SFUD_SUCCESS)
        rt_kprintf("sfud api write data to w25q128(address:0x2000) success.\n");

    if(sfud_read(sfud_dev, 0x002000, sizeof(rData), rData) == SFUD_SUCCESS)
        rt_kprintf("sfud api read data from w25q128(address:0x2000) is:%s\n", rData);
}

// 2- use rt_device api
rt_kprintf("\n 2 - Use rt_device API \n");

flash_dev = (rt_spi_flash_device_t)rt_device_find(W25Q_FLASH_NAME);
if(flash_dev == RT_NULL){
    rt_kprintf("rt_device api can't find %s device.\n", W25Q_FLASH_NAME);
}else{
    rt_device_open(&flash_dev->flash_device, RT_DEVICE_OFLAG_OPEN);

    if(rt_device_control(&flash_dev->flash_device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry) == RT_EOK)
        rt_kprintf("spi flash device name: %s, sector_count: %d, bytes_per_sector: %d, block_size: %d.\n",
                flash_dev->flash_device.parent.name, geometry.sector_count, geometry.bytes_per_sector, geometry.block_size);

    if(rt_device_write(&flash_dev->flash_device, 0x03, wData, 1) > 0)
        rt_kprintf("rt_device api write data to w25q128(address:0x3000) success.\n");

    if(rt_device_read(&flash_dev->flash_device, 0x03, rData, 1) > 0)
        rt_kprintf("rt_device api read data from w25q128(address:0x3000) is:%s\n", rData);

    rt_device_close(&flash_dev->flash_device);
}

}
MSH_CMD_EXPORT(sfud_w25q_sample, sfud w25q128 sample);
接下来要添加fal,原因如图,我们要ota就不能跳过FAL层:
7.在组件中查找fal,如图:
编译下发现有报错,原因缺少fal_cfg.h文件,从下面的sample文件夹里copy一个,修改下在编译就通过了。


8.在main函数中添加fal初始化函数,如图:
9.把w25qxx.c文件里的W25Q_FLASH_NAME改成FAL_USING_NOR_FLASH_DEV_NAME

编译下载后,可以看到串口打印信息,如图:
10.使用fal指令读写一下flash
到这里,我们的flash就添加完了。
11.添加qboot软件包,添加后有一些依赖包自动添加不用管,去掉syswatch组件



12.编译通过下载,再找一个测试程序测试下boot是否能够正常跳转
先更改测试程序下载区域



下载后会看到app程序会打印Hello RT-Thread lan8720A!看看对不对

下载后首先bootloader程序运行,几秒后打印信息显示跳转到app程序,然后app程序开始运行,刚开始时候boot程序中打印信息为Hello RT-Thread999!,跳转后打印信息为 Hello RT-Thread lan8720A!,成功跳转。到这里bootloader程序功能就正常了。

物联沃分享整理
物联沃-IOTWORD物联网 » STM32 OTA教程(一)

发表评论