Stm32f407 MCU rt thread off-chip spi flash OTA upgrade configuration example

Reference address https://www.rt-thread.org/document/site/application-note/system/rtboot/an0028-rtboot/

The first step is to generate BootLoader.

Bootloader obtains the address online: http://iot.rt-thread.com

1. Register an account and create a new product.

Click Firmware Upgrade, and then generate BootLoader.

2. Fill in the hardware information according to your own board configuration.

My board is using STM32F407VGT6, ROM is 1M, RAM is 192K.

Serial port 1 is the debug port, there is an off-chip SPI flash, W25Q128, the size is 128MBit or 16MByte.

Partition table configuration

Configure according to the figure

The address of the Bootloader is 0x08000000 to 0x08020000, and the size is 128K.

The address of the APP program is 0x08020000 to 0x080ffff, and the size is 896K.

Download Download to the off-chip SPI flash. The start address of the off-chip SPI flash is 0x00000000. The SPI flash space is large enough and 1024K is allocated.

Encryption and compression and logo are configured according to personal needs. Then generate BootLoader.

The second step is to download the Bootloader program.

Open the STM32 ST-LINK Utility software, connect to the circuit board, open the downloaded Bootloader program, the starting address of the download is 0x08000000 and then click download.

This is displayed after the program is running.

Of course, this is just the Bootloader program running, it has nothing to do with our application, we continue to make the application part.

The third step is to add spi flash driver to the APP application

1. Prepare a ready-made program with rt thread system and a project that can be used in the network part, and open menuconfig.

Enter the directory Hardware Drivers Config-->Onboard Peripheral Drivers

Open Enable SPI FLASH

Enter the directory Hardware Drivers Config-->On-chip Peripheral Drivers

Turn on Enable SPI BUS

After saving and exiting, use pkgs --update to update the software package

Then use scons --target=mdk5 to regenerate the project.

After compiling without errors, add a spi_w25q.c file, add a spi flash test program, and see if the driver is normal.

The test code is as follows:

#define SPI_BUS_NAME                    "spi1"

#define W25Q_SPI_DEVICE_NAME                 "spi10"
#define W25Q_FLASH_NAME                         "W25Q128"


rt_uint8_t wData[4096] = {"SPI bus write data to W25Q flash."};
rt_uint8_t rData[4096];

static int rt_hw_spi_flash_init()
{
    rt_err_t ree = RT_EOK;

    = rt_hw_spi_device_attach REE (SPI_BUS_NAME, W25Q_SPI_DEVICE_NAME, GPIOE., GPIO_PIN_1);
    / * use SFUD probe spi10 connection from the device, and initializing a block of flash spi10 device name * W25Q128 /
    IF (RT_NULL == rt_sfud_flash_probe (W25Q_FLASH_NAME, W25Q_SPI_DEVICE_NAME))
    {             return -RT_ERROR;     }     return ree; } INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init); static void spi_w25q_sample(void) {     struct rt_spi_device *spi_dev_w25q;     rt_uint8_t w25x_read_id = 0x90;     rt_uint8 = {0};









    /* 查找 spi 设备获取设备句柄 */
    spi_dev_w25q = (struct rt_spi_device *)rt_device_find(W25Q_SPI_DEVICE_NAME);
    if (!spi_dev_w25q)
    {
        rt_kprintf("spi sample run failed! can't find %s device!\n", W25Q_SPI_DEVICE_NAME);
    }
    else
    {
            rt_kprintf("spi sample run ok!\n");
            {
                struct rt_spi_configuration cfg;
                cfg.data_width = 8;
                cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0*/
                cfg.max_hz = 50 * 1000 * 1000; /* 50M */
                rt_spi_configure(spi_dev_w25q, &cfg);
            }
            /* 方式1:使用 rt_spi_send_then_recv()发送命令读取ID */
            rt_spi_send_then_recv(spi_dev_w25q, &w25x_read_id, 1, id, 5);
            rt_kprintf("use rt_spi_send_then_recv() read w25q ID is:%x%x\n", id[3], id[4]);
    }
}
MSH_CMD_EXPORT(spi_w25q_sample, spi w25q128 sample);

After compiling and downloading, run the spi_w25q_sample function to read the ID number of the flash.

The fourth step is to add SFUD management framework

After we open Enable SPI FLASH in menuconfig, we will add the following definitions in rtconfig.h

SFUD framework is used by default

Then add the following code to the spi_w25q.c file, compile and download.

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);

 

Execute the sfud_w25q_sample function

You can use the sf command to test flash initialization, reading and writing, erasing, etc.

The flash initialization and reading and writing tests are normal.

The fifth step is to add the fal management framework

From the figure above, it can be seen that the FAL abstraction layer is located in the upper layer of the SFUD framework, which can manage multiple Flash hardware (including on-chip Flash and off-chip Flash) in a unified manner, and provide the upper layer such as DFS file system layer with multiple Flash hardware at the bottom The unified access interface is convenient for upper-layer applications to access the underlying hardware.

Open menuconfig, enter RT-Thread online packages-->system packages

Open fal

The default SFUD device name is norflash0, and the device name can be changed to W25Q128. The configuration interface is as follows.

Then enter Hardware Drivers config -->on-chip peripheral Drivers

Turn on Enable on-chip FLASH

After saving and exiting, use pkgs --update to update the software package to the local, and then use scons --target=mdk5 to regenerate the project.

After opening the project, an error is reported and the fal_cfg.h file cannot be found. Let's add the file path of fal_cfg.h

The file path is packages\fal-v0.5.0\samples\porting

Then open the fal_flash_sfud_port.c file,

Our flash model is W25Q128, the size is 16M, here is changed to 16 * 1024 * 1024.

Compile it, it prompts that these are not defined

The default fal_cfg.h file does not define stm32_onchip_flash_16k.

Since the internal flash distribution of the stm32f4 series is as follows

There are three sizes of flash block: 16k, 64k, and 128k, so three block devices need to be defined.

We open the fal_cfg.h file and change it as follows

#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_

#include <rtconfig.h>
#include <board.h>


#define RT_APP_PART_ADDR                0x08020000

 

#ifndef FAL_USING_NOR_FLASH_DEV_NAME
#define NOR_FLASH_DEV_NAME             "norflash0"
#else
#define NOR_FLASH_DEV_NAME              FAL_USING_NOR_FLASH_DEV_NAME
#endif


#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 const struct fal_flash_dev stm32_onchip_flash;
extern struct fal_flash_dev nor_flash0;

/* flash device table */
#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 */
#define FAL_PART_TABLE                                                                                                  \
{                                                                                                                       \
        {FAL_PART_MAGIC_WROD, "bootloader",     "onchip_flash",                                    0,       128 * 1024, 0}, \
    {FAL_PART_MAGIC_WROD,        "app",     "onchip_flash",                           128 * 1024,       896 * 1024, 0}, \
    {FAL_PART_MAGIC_WROD,   "download", NOR_FLASH_DEV_NAME,                                            0,      1024 * 1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */

#endif /* _FAL_CFG_H_ */

Then compile again, there is no error, and then add fal_init(); in the main function, compile and download.

Step 6 add easyflash

Open menuconfig

进入RT-Thread online packages-->tools packages

Open EasyFlash

Then open RT-Thread online packages-->IOT-internet of things

Open ota_downloader

After saving and exiting, use pkgs --update to update the software package, and then use scons --target=mdk5 to regenerate the project.

Then add the el_fal_port.c file in the EasyFlash directory of the keil project

el_fal_port.c is in the packages\EasyFlash-v4.1.0\ports directory.

 

Then there is an error when compiling and downloading

This is the timeval structure defined in sockets.h and time.h.

Then change the name of the timeval structure in time.h, and change it in time.c by the way, and then there is no error in compiling.

Then change the interrupt vector table and print version information in the main.c file.

Then change the program download address here,

Then download the bootloader again, and download the program compiled by keil.

The version is 0.0.0, then change the version number in keil to 0.0.1, and then compile and generate the bin file

Use rt_ota_packaging_tool.exe tool to generate rbl file

Then enter ymodem_ota in Xshell 6

Then use the ymodem tool in Xshell to send the rbl file to the microcontroller

Then the chip will automatically restart and update the program

After the update is completed, the version number becomes 0.0.1, indicating that the update was successful.

 

 

 

 

 

 

 

 

Enter the directory RT_Thread online packages-->IoT-internet of things-->

打开ota_downloader:The firmware downloader which using on RT-Thread

Then select Enable OTA downloader debug and Enable Ymoden OTA

Then enter Hardware Drivers Config-->on-chip Peripheral Drivers-->Enable on-chip FLASH

After saving and exiting, use the scons --target=mdk5 command to generate the MDK5 project.

Open the MDK5 project, add the written application in Applications, and then compile it.

Prompt that fal_cfg.h is not found

Add the file path of fal_cfg.h

Under packages\fal-v0.5.0\samples\porting

Then compile and prompt STM32_FLASH_START_ADRESS_16K these are not defined,

Then open the fal_cfg.h file and found that it is not the same as the official document

Then compiled the bsp of Punctual Atom as the official one, and copied it as follows.

Source code

#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_

#include <rtconfig.h>
#include <board.h>


#define RT_APP_PART_ADDR                0x08040000

#define NOR_FLASH_DEV_NAME             "norflash0"

#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 table */
#define FAL_FLASH_DEV_TABLE                                          \
{                                                                    \
    &stm32_onchip_flash_16k,                                         \
    &stm32_onchip_flash_64k,                                         \
    &stm32_onchip_flash_128k,                                                     \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE                                                               \
{                                                                                    \
    {FAL_PART_MAGIC_WORD,        "bl",     "stm32_onchip",         0,   64*1024, 0}, \
    {FAL_PART_MAGIC_WORD,       "app",     "stm32_onchip",   64*1024,  704*1024, 0}, \
    {FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME,         0, 1024*1024, 0}, \
    {FAL_PART_MAGIC_WORD,  "download", NOR_FLASH_DEV_NAME, 1024*1024, 1024*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */

#endif /* _FAL_CFG_H_ */

Then compile without error, add the following content in the main function.

The most important step is to modify the link address of the APP firmware.

The official document is filled with 0x08040000, we change it to 0x08020000

Because the starting address of the APP we configured in BootLoader is 0x08020000, not 0x08040000. This is different from the official configuration, so you must modify it.

Then the RT_APP_PART_ADDR defined in the fal_cfg.h file is also changed to 0x08020000

Then compile and download, print out the current version number V0.0.0

Step 4 Pack the APP firmware

Use the RT-Thread OTA firmware packager to package the app firmware and make an upgrade firmware that can be downloaded to the download partition. The firmware packaging tool can be found in the tools folder under the ota_downloader package.

  1. Before packaging the firmware, first modify  stm32f407-atk-explorer/applications/main.c the value of the APP_VERSION macro to 2.0.0 as a reference, and then recompile to generate a new rtthread.bin file . The modified content is shown in the following figure:

2. Double-click to open the  tools\ota_packager\rt_ota_packaging_tool.exe program, and use the OTA firmware packaging tool to package the rtthread.bin file compiled in the previous step into a  file that can be upgraded  rtthread.rbl , as shown in the following figure:

The fifth step is to perform OTA upgrade

Use mywebserver software to find the directory where the rbl file is located, select the local IP address for the IP address, and click start.

Power on the development board, wait for the success of obtaining the IP address, and then enter http_ota http://192.168.1.72/rtthread.rbl in the shell to start the OTA upgrade

我这里使用了{"cmd":"robotset2","model":"b1","robot_id":"1503090496","data":{"updata":"http://192.168.2.119/rtthread.rbl"}}

This command starts the remote upgrade via TCP.

The shell process is the same, the system will automatically restart after the download is complete

Guess you like

Origin blog.csdn.net/qq_25186745/article/details/107121699