rtt-studio——OTA远程升级(HTTP)
2026/7/18 20:26:48 网站建设 项目流程

一.软件准备:

1.rtthread-studio

2.mobaxterm(可选)

3.STM32 ST-LINK Utility

4.cubemx

二.制作Bootloader

1.打开rtt官方的网站登录进去iot_admin

2.注册并进入新建一个产品(随意书写就行),按照步骤1,2,3,根据自己手头板子型号来制作bootloader,stm32f407默认是128k给bootloader,所以app区应该是从0x8020000开始,根据自己程序所占的空间大小,来分配对应的data大小(128的整数倍),download区是最好跟app区配置一样的(选的是片上外设,就没有配置spi flash):

3.bootloader生成之后,会生成.zip文件,解压缩里面有.bin文件,打开STM32 ST-LINK Utility这个软件,先设置:

配置如下(前提是先连接stlink与单片机)

然后点击连接

连接成功会出现如图所示:

选择刚刚生成的bootloader的.bin文件,然后点击start下载:

三.硬件驱动配置

1.在cubemx中开启网口即可,时钟这些配置一下,网上教程很多。

2.打开rtthread-studio,进行相关的配置:

配置自己相关的局域网地址即可。

3.编译驱动时会报错,需要把如图:

这个文件中的

section 2这部分替换为下面的(根据板子上的网口芯片,正点原子开发板是lan8720)

/* LAN8720A_PHY_ADDRESS Address*/ #define LAN8720A_PHY_ADDRESS 1U /* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ #define PHY_RESET_DELAY ((uint32_t)0x000000FFU) /* PHY Configuration delay */ #define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) #define PHY_READ_TO ((uint32_t)0x0000FFFFU) #define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) /* Section 3: Common PHY Registers */ #define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */ #define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */ #define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ #define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ #define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ #define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ #define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ #define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ #define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ #define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ #define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ #define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ #define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ #define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ #define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ /* Section 4: Extended PHY Registers */ #define PHY_SR ((uint16_t)0x1FU) /*!< PHY status register Offset */ #define PHY_SPEED_STATUS ((uint16_t)0x0004U) /*!< PHY Speed mask */ #define PHY_DUPLEX_STATUS ((uint16_t)0x0010U) /*!< PHY Duplex mask */ #define PHY_ISFR ((uint16_t)0x001DU) /*!< PHY Interrupt Source Flag register Offset */ #define PHY_ISFR_INT4 ((uint16_t)0x000BU) /*!< PHY Link down inturrupt */

再把main中的与eth相关的注释掉,再编译

5.修改board.c中的文件:

修改board.h中的文件:

6.添加软件包:

5.1rtthread应该是在ota-download里内置了fal这个,所以不需要下载(先安装下面的ota),需要额外添加一个文件:

文件内容如下:

/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-12-5 SummerGift first version */ #ifndef _FAL_CFG_H_ #define _FAL_CFG_H_ #include <rtthread.h> #include <board.h> #ifdef BSP_USING_SPI_FLASH_LITTLEFS extern struct fal_flash_dev w25q128; #else extern const struct fal_flash_dev stm32_onchip_flash; #endif /* flash device table */ #ifdef BSP_USING_SPI_FLASH_LITTLEFS #define FAL_FLASH_DEV_TABLE \ { \ &w25q128, \ } #else #define FAL_FLASH_DEV_TABLE \ { \ &stm32_onchip_flash, \ } #endif /* ====================== Partition Configuration ========================== */ #ifdef FAL_PART_HAS_TABLE_CFG /* partition table */ #ifdef BSP_USING_SPI_FLASH_LITTLEFS #define FAL_PART_TABLE \ { \ {FAL_PART_MAGIC_WROD, "spiflash0", "W25Q128", 0 , 16 * 1024 * 1024, 0}, \ } #else #define FAL_PART_TABLE \ { \ {FAL_PART_MAGIC_WROD, "bootloader", "onchip", 0x00000, 128 * 1024, 0}, \ {FAL_PART_MAGIC_WROD, "app", "onchip", 0x20000, 384 * 1024, 0}, \ {FAL_PART_MAGIC_WROD, "download", "onchip", 0x80000, 384 * 1024, 0}, \ } #endif #endif /* FAL_PART_HAS_TABLE_CFG */ #endif /* _FAL_CFG_H_ */

在board.h中再添加:

对于drivers文件夹下的drv_flash_f4.c,替换成下面的代码:

/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-12-5 SummerGift first version */ #include "board.h" #ifdef BSP_USING_ON_CHIP_FLASH #include "drv_config.h" #include "drv_flash.h" #if defined(RT_USING_FAL) || defined(PKG_USING_FAL) #include "fal.h" #endif //#define DRV_DEBUG #define LOG_TAG "drv.flash" #include <drv_log.h> /* Base address of the Flash sectors Bank 1 */ #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */ #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */ #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */ #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */ #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */ #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */ #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */ #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */ #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */ #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */ #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */ #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */ /* Base address of the Flash sectors Bank 2 */ #define ADDR_FLASH_SECTOR_12 ((uint32_t)0x08100000) /* Base @ of Sector 0, 16 Kbytes */ #define ADDR_FLASH_SECTOR_13 ((uint32_t)0x08104000) /* Base @ of Sector 1, 16 Kbytes */ #define ADDR_FLASH_SECTOR_14 ((uint32_t)0x08108000) /* Base @ of Sector 2, 16 Kbytes */ #define ADDR_FLASH_SECTOR_15 ((uint32_t)0x0810C000) /* Base @ of Sector 3, 16 Kbytes */ #define ADDR_FLASH_SECTOR_16 ((uint32_t)0x08110000) /* Base @ of Sector 4, 64 Kbytes */ #define ADDR_FLASH_SECTOR_17 ((uint32_t)0x08120000) /* Base @ of Sector 5, 128 Kbytes */ #define ADDR_FLASH_SECTOR_18 ((uint32_t)0x08140000) /* Base @ of Sector 6, 128 Kbytes */ #define ADDR_FLASH_SECTOR_19 ((uint32_t)0x08160000) /* Base @ of Sector 7, 128 Kbytes */ #define ADDR_FLASH_SECTOR_20 ((uint32_t)0x08180000) /* Base @ of Sector 8, 128 Kbytes */ #define ADDR_FLASH_SECTOR_21 ((uint32_t)0x081A0000) /* Base @ of Sector 9, 128 Kbytes */ #define ADDR_FLASH_SECTOR_22 ((uint32_t)0x081C0000) /* Base @ of Sector 10, 128 Kbytes */ #define ADDR_FLASH_SECTOR_23 ((uint32_t)0x081E0000) /* Base @ of Sector 11, 128 Kbytes */ /** * @brief Gets the sector of a given address * @param None * @retval The sector of a given address */ static rt_uint32_t GetSector(rt_uint32_t Address) { rt_uint32_t sector = 0; if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) { sector = FLASH_SECTOR_0; } else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) { sector = FLASH_SECTOR_1; } else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) { sector = FLASH_SECTOR_2; } else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) { sector = FLASH_SECTOR_3; } else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) { sector = FLASH_SECTOR_4; } else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) { sector = FLASH_SECTOR_5; } else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) { sector = FLASH_SECTOR_6; } else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) { sector = FLASH_SECTOR_7; } #if defined(FLASH_SECTOR_8) else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) { sector = FLASH_SECTOR_8; } #endif #if defined(FLASH_SECTOR_9) else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) { sector = FLASH_SECTOR_9; } #endif #if defined(FLASH_SECTOR_10) else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) { sector = FLASH_SECTOR_10; } #endif #if defined(FLASH_SECTOR_11) else if((Address < ADDR_FLASH_SECTOR_12) && (Address >= ADDR_FLASH_SECTOR_11)) { sector = FLASH_SECTOR_11; } #endif #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx) else if((Address < ADDR_FLASH_SECTOR_13) && (Address >= ADDR_FLASH_SECTOR_12)) { sector = FLASH_SECTOR_12; } else if((Address < ADDR_FLASH_SECTOR_14) && (Address >= ADDR_FLASH_SECTOR_13)) { sector = FLASH_SECTOR_13; } else if((Address < ADDR_FLASH_SECTOR_15) && (Address >= ADDR_FLASH_SECTOR_14)) { sector = FLASH_SECTOR_14; } else if((Address < ADDR_FLASH_SECTOR_16) && (Address >= ADDR_FLASH_SECTOR_15)) { sector = FLASH_SECTOR_15; } else if((Address < ADDR_FLASH_SECTOR_17) && (Address >= ADDR_FLASH_SECTOR_16)) { sector = FLASH_SECTOR_16; } else if((Address < ADDR_FLASH_SECTOR_18) && (Address >= ADDR_FLASH_SECTOR_17)) { sector = FLASH_SECTOR_17; } else if((Address < ADDR_FLASH_SECTOR_19) && (Address >= ADDR_FLASH_SECTOR_18)) { sector = FLASH_SECTOR_18; } else if((Address < ADDR_FLASH_SECTOR_20) && (Address >= ADDR_FLASH_SECTOR_19)) { sector = FLASH_SECTOR_19; } else if((Address < ADDR_FLASH_SECTOR_21) && (Address >= ADDR_FLASH_SECTOR_20)) { sector = FLASH_SECTOR_20; } else if((Address < ADDR_FLASH_SECTOR_22) && (Address >= ADDR_FLASH_SECTOR_21)) { sector = FLASH_SECTOR_21; } else if((Address < ADDR_FLASH_SECTOR_23) && (Address >= ADDR_FLASH_SECTOR_22)) { sector = FLASH_SECTOR_22; } else /* (Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_23) */ { sector = FLASH_SECTOR_23; } #endif return sector; } /** * Read data from flash. * @note This operation's units is word. * * @param addr flash address * @param buf buffer to store read data * @param size read bytes size * * @return result */ int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size) { size_t i; if ((addr + size) > STM32_FLASH_END_ADDRESS) { LOG_E("read outrange flash size! addr is (0x%p)", (void*)(addr + size)); return -1; } for (i = 0; i < size; i++, buf++, addr++) { *buf = *(rt_uint8_t *) addr; } return size; } /** * Write data to flash. * @note This operation's units is word. * @note This operation must after erase. @see flash_erase. * * @param addr flash address * @param buf the write data buffer * @param size write bytes size * * @return result */ int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size) { rt_err_t result = RT_EOK; rt_uint32_t end_addr = addr + size; rt_uint32_t written_size = 0; rt_uint32_t write_size = 0; if ((end_addr) > STM32_FLASH_END_ADDRESS) { LOG_E("write outrange flash size! addr is (0x%p)", (void*)(addr + size)); return -RT_EINVAL; } if (size < 1) { return -RT_EINVAL; } HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); while (written_size < size) { if (((addr + written_size) % 4 == 0) && (size - written_size >= 4)) { if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr + written_size, *((rt_uint32_t *)(buf + written_size))) == HAL_OK) { if (*(rt_uint32_t *)(addr + written_size) != *(rt_uint32_t *)(buf + written_size)) { result = -RT_ERROR; break; } } else { result = -RT_ERROR; break; } write_size = 4; } else if (((addr + written_size) % 2 == 0) && (size - written_size >= 2)) { if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr + written_size, *((rt_uint16_t *)(buf + written_size))) == HAL_OK) { if (*(rt_uint16_t *)(addr + written_size) != *(rt_uint16_t *)(buf + written_size)) { result = -RT_ERROR; break; } } else { result = -RT_ERROR; break; } write_size = 2; } else { if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, addr + written_size, *((rt_uint8_t *)(buf + written_size))) == HAL_OK) { if (*(rt_uint8_t *)(addr + written_size) != *(rt_uint8_t *)(buf + written_size)) { result = -RT_ERROR; break; } } else { result = -RT_ERROR; break; } write_size = 1; } written_size += write_size; } HAL_FLASH_Lock(); if (result != RT_EOK) { return result; } return size; } /** * Erase data on flash. * @note This operation is irreversible. * @note This operation's units is different which on many chips. * * @param addr flash address * @param size erase bytes size * * @return result */ int stm32_flash_erase(rt_uint32_t addr, size_t size) { rt_err_t result = RT_EOK; rt_uint32_t FirstSector = 0, NbOfSectors = 0; rt_uint32_t SECTORError = 0; if ((addr + size) > STM32_FLASH_END_ADDRESS) { LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void*)(addr + size)); return -RT_EINVAL; } if (size < 1) { return -RT_EINVAL; } /*Variable used for Erase procedure*/ FLASH_EraseInitTypeDef EraseInitStruct; /* Unlock the Flash to enable the flash control register access */ HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); /* Get the 1st sector to erase */ FirstSector = GetSector(addr); /* Get the number of sector to erase from 1st sector*/ NbOfSectors = GetSector(addr + size - 1) - FirstSector + 1; /* Fill EraseInit structure*/ EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; EraseInitStruct.Sector = FirstSector; EraseInitStruct.NbSectors = NbOfSectors; if (HAL_FLASHEx_Erase(&EraseInitStruct, (uint32_t *)&SECTORError) != HAL_OK) { result = -RT_ERROR; goto __exit; } __exit: HAL_FLASH_Lock(); if (result != RT_EOK) { return result; } LOG_D("erase done: addr (0x%p), size %d", (void*)addr, size); return size; } #if defined(RT_USING_FAL) || defined(PKG_USING_FAL) static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size); static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size); static int fal_flash_erase(long offset, size_t size); const struct fal_flash_dev stm32_onchip_flash = { "onchip", STM32_FLASH_START_ADRESS, STM32_FLASH_SIZE, (128 * 1024), {NULL, fal_flash_read, fal_flash_write, fal_flash_erase} }; static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size) { return stm32_flash_read(stm32_onchip_flash.addr + offset, buf, size); } static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size) { return stm32_flash_write(stm32_onchip_flash.addr + offset, buf, size); } static int fal_flash_erase(long offset, size_t size) { return stm32_flash_erase(stm32_onchip_flash.addr + offset, size); } #endif #endif /* BSP_USING_ON_CHIP_FLASH */

修改终端向量表的便宜地址

修改linkscripts中的link文件,大小是你的app的data区的大小:

7.添加ota软件包:

进入修改配置选项(自己电脑的ip地址)

修改/packages/src中的http_ota.c文件:

/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-03-22 Murphy the first version */ #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <rtthread.h> #include <finsh.h> #include "webclient.h" #include <fal.h> #define DBG_ENABLE #define DBG_SECTION_NAME "http_ota" #ifdef OTA_DOWNLOADER_DEBUG #define DBG_LEVEL DBG_LOG #else #define DBG_LEVEL DBG_INFO #endif #define DBG_COLOR #include <rtdbg.h> #ifdef PKG_USING_HTTP_OTA #define HTTP_OTA_BUFF_LEN (2 * 1024) #define GET_HEADER_BUFSZ 1024 #define GET_RESP_BUFSZ 512 #define HTTP_OTA_DL_DELAY (10 * RT_TICK_PER_SECOND) #define HTTP_OTA_URL PKG_HTTP_OTA_URL /* the address offset of download partition */ #ifndef RT_USING_FAL #error "Please enable and confirgure FAL part." #endif /* RT_USING_FAL */ const struct fal_partition * dl_part = RT_NULL; static int begin_offset = 0; static int file_size = 0; static void print_progress(size_t cur_size, size_t total_size) { static unsigned char progress_sign[100 + 1]; uint8_t i, per = cur_size * 100 / total_size; if (per > 100) { per = 100; } for (i = 0; i < 100; i++) { if (i < per) { progress_sign[i] = '='; } else if (per == i) { progress_sign[i] = '>'; } else { progress_sign[i] = ' '; } } progress_sign[sizeof(progress_sign) - 1] = '\0'; LOG_I("Download: [%s] %03d%%\033[1A", progress_sign, per); } /* handle function, you can store data and so on */ static int http_ota_fw_download(const char* uri) { int ret = RT_EOK; int status; int read_len; uint8_t *buffer = RT_NULL; struct webclient_session* session = RT_NULL; /* create webclient session and set header response size */ session = webclient_session_create(GET_HEADER_BUFSZ); if (!session) { LOG_E("open uri failed."); ret = -RT_ERROR; goto __exit; } /* * Use one normal GET and stream its body to flash. This also works with * HTTP servers (such as Python http.server) which do not support Range. */ status = webclient_get(session, uri); if (status != 200) { LOG_E("HTTP GET failed, status: %d", status); ret = -RT_ERROR; goto __exit; } file_size = webclient_content_length_get(session); if (file_size == 0) { LOG_E("Request file size is 0!"); ret = -RT_ERROR; goto __exit; } else if (file_size < 0) { LOG_E("webclient GET request type is chunked."); ret = -RT_ERROR; goto __exit; } LOG_I("OTA file size is (%d)", file_size); LOG_I("\033[1A"); /* Get download partition information and erase download partition data */ if ((dl_part = fal_partition_find("download")) == RT_NULL) { LOG_E("Firmware download failed! Partition (%s) find error!", "download"); ret = -RT_ERROR; goto __exit; } if (file_size > dl_part->len) { LOG_E("Firmware is too large! File size (%d), partition size (%d)", file_size, dl_part->len); ret = -RT_ERROR; goto __exit; } LOG_I("Start erase flash (%s) partition!", dl_part->name); if (fal_partition_erase(dl_part, 0, file_size) < 0) { LOG_E("Firmware download failed! Partition (%s) erase error!", dl_part->name); ret = -RT_ERROR; goto __exit; } LOG_I("Erase flash (%s) partition success!", dl_part->name); buffer = rt_malloc(HTTP_OTA_BUFF_LEN); if (buffer == RT_NULL) { LOG_E("No memory for OTA buffer (%d bytes).", HTTP_OTA_BUFF_LEN); ret = -RT_ENOMEM; goto __exit; } while (begin_offset < file_size) { int remaining = file_size - begin_offset; int request_len = remaining > HTTP_OTA_BUFF_LEN ? HTTP_OTA_BUFF_LEN : remaining; read_len = webclient_read(session, buffer, request_len); if (read_len <= 0) { LOG_E("Read firmware failed at offset %d, error %d.", begin_offset, read_len); ret = -RT_ERROR; goto __exit; } if (fal_partition_write(dl_part, begin_offset, buffer, read_len) != read_len) { LOG_E("Firmware download failed! Partition (%s) write data error!", dl_part->name); ret = -RT_ERROR; goto __exit; } begin_offset += read_len; print_progress(begin_offset, file_size); } ret = RT_EOK; if (ret == RT_EOK) { if (session != RT_NULL) { webclient_close(session); session = RT_NULL; } LOG_I("\033[0B"); LOG_I("Download firmware to flash success."); LOG_I("System now will restart..."); rt_hw_interrupt_disable(); NVIC_SystemReset(); } else { LOG_E("Download firmware failed."); } __exit: if (buffer != RT_NULL) rt_free(buffer); if (session != RT_NULL) webclient_close(session); begin_offset = 0; return ret; } void http_ota(uint8_t argc, char **argv) { if (argc < 2) { rt_kprintf("using uri: " HTTP_OTA_URL "\n"); http_ota_fw_download(HTTP_OTA_URL); } else { http_ota_fw_download(argv[1]); } } /** * msh />http_ota [url] */ MSH_CMD_EXPORT(http_ota, Use HTTP to download the firmware); #endif /* PKG_USING_HTTP_OTA */

在main中书写:

#include <fal.h> int fal_partitions; /* OTA depends on the FAL flash device and partition table. */ fal_partitions = fal_init(); if (fal_partitions <= 0) { rt_kprintf("[MAIN] Error: FAL initialization failed (%d)\n", fal_partitions); return -1; } rt_kprintf("[MAIN] FAL initialized, %d partitions found\n", fal_partitions);

四.打包app

编译自己的工程,编译完成后,会生成.bin文件:

找到打包应用:

选择debug下的.bin文件:

打包完成之后,会生成一个.rbl文件:

五.远程烧录测试:

在.rbl文件夹中打开cmd:

运行命令:

python -m http.server 8080

进入单片机的串口中,使用命令:

计算机的ip地址,这样,就会远程ota升级成功

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询