---
title: "STM32 W5500 OTA功能 - bootloader及app的??和??"
url: "https://maker.wiznet.io/chen/projects/STM32-W5500-OTA-bootloaderapp-by-chen/"
markdown_url: "https://maker.wiznet.io/chen/projects/STM32-W5500-OTA-bootloaderapp-by-chen/md"
type: "UCC: User Created Content"
author: "chen"
author_url: "https://maker.wiznet.io/chen/"
original_author: "chen"
original_url: "https://blog.csdn.net/lnniyunlong99/article/details/105603666"
published: "2021-08-03"
language: "zh"
likes: 0
views: 815
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# STM32 W5500 OTA功能 - bootloader及app的??和??

> STM32 W5500 OTA功能 - bootloader及app的??和??

Original author: chen (source: https://blog.csdn.net/lnniyunlong99/article/details/105603666)

## Article

通?W5500的??功能，到文件服?器下?STM32要更新的固件(可?行bin文件)，存?到STM32片?FLASH的APP???中，以待bootloader拷?到APP代??行?，以??OTA在?升?的功能。 我使用的芯片是STM32F103RCT6，48Kbyte的RAM?存和256Kbyte的片?FLASH。 片?FLASH?域?分 ?于片?FLASH?用的?分，包括4??域：bootloader?(36Kbyte)，App代??行?(108Kbyte)，App代????(108Kbyte)，用??据???(4Kbyte)，共256Kbyte，如?所示： 那?片?FLASH各??域??的索引地址?： Bootloader功能????? bootloader和普通的app程序?似，只不??在STM32上?后?始?行的，?????用??据?据???是否有已?下?好的固件要更新。 如果用??据?据????有下?好的固件?据要更新，?直接跳?到App代??行?； 如果用??据?据???有下?好的固件?据要更新，那?根据用??据???的下?固件文件?度，?App代????的?据拷?到App代??行?，如果拷?完成，??用??据???和App代?????据擦除，再跳?到App代??行?去?行更新好的新程序。 在Keil工程中，bootloader的配置 bootloader的代???： #ifndef __STM32F10X_H #define __STM32F10X_H #include "stm32f10x.h" #endif #ifndef __Z_UTIL_TIME_H #define __Z_UTIL_TIME_H #include "z_util_time.h" #endif #ifndef __Z_HARDWARE_LED_H #define __Z_HARDWARE_LED_H #include "z_hardware_led.h" #endif #ifndef __Z_HARDWARE_FLASH_H #define __Z_HARDWARE_FLASH_H #include "z_hardware_flash.h" #endif #include &lt;string.h> #define APP_FLASH_ADDRESS (0x8009000) #define BACKUP_FLASH_ADDRESS (0x8024000) #define RECORD_FLASH_ADDRESS (0x803F000) typedef void (*pFunction)(void); pFunction Jump_To_Application; uint32_t JumpAddress; void func_jump2app(void) { if (((*(__IO uint32_t*)APP_FLASH_ADDRESS) & 0x2FFC0000 ) == 0x20000000) { __disable_irq(); JumpAddress = *(__IO uint32_t*) (APP_FLASH_ADDRESS + 4); Jump_To_Application = (pFunction) JumpAddress; __set_MSP(*(__IO uint32_t*) APP_FLASH_ADDRESS); Jump_To_Application(); } } void func_led_onoff_cross(void); u16 flash_buf[1024]; int main() { u8 i; u32 len_backup; init_led(); func_flash_read_datas(RECORD_FLASH_ADDRESS, flash_buf, 128); delay_ms(10); if(flash_buf[0] == 0x0002)// to update { u8 i, page, suc; len_backup = flash_buf[2]*65536 + flash_buf[3]; page = len_backup / SECTOR_SIZE + 1; if(page &lt;= 54)//108kbyte { for(i = 0; i &lt; page; i++) { memset(flash_buf, 0xFFFF, sizeof(flash_buf)); func_flash_read_datas(BACKUP_FLASH_ADDRESS + i*2048, flash_buf, 1024); suc = func_flash_write_datas(APP_FLASH_ADDRESS + i*2048, flash_buf, 1024); if(suc != 0) { break; } } if(suc == 0)//copy success { //clear backup for(i = 0; i &lt; page; i++) { func_flash_erase_page(BACKUP_FLASH_ADDRESS + i*2048); } func_flash_erase_page(RECORD_FLASH_ADDRESS); } } } for(i = 0; i &lt; 5; i++) { func_led_onoff_cross(); } func_jump2app(); } void func_led_onoff_cross() { func_led1_on(); func_led2_off(); delay_ms(200); func_led2_on(); func_led1_off(); delay_ms(200); } App功能????? App的功能，????部分不作?本文描述重点。?于??或其他方式下?固件，通?一?外部??去?行，我?里使用了一????????下?固件的事件。 在App代??行?始的地方，做一?中?向量的配置 NVIC_SetVectorTable(NVIC_VectTab_FLASH, (FLASH_APPCODE_ADDR - FLASH_BASE_ADDR)); 然后初始化各?GPIO的操作，由于我是通?W5500的Http Get方式下?可?行文件bin，初始化一下??的配置，DHCP???取IP等。?有一?地方，是在??下??据的?程，通?一??子函??行注?存?函?，以??下?的方法和??分?。 //hook init_hooks_http_download_file_save(func_custom_http_downloading_file_save); 文件下?的?容，存?到App代????，下?完成后?存?升?固件的??以及下?了的固件文件的?度。 至于 STM32 W5500 Http Get方式下?固件的思路和??，可?考 《STM32 W5500 Http Client Get?求 下?bin文件思路和??》。 下?完成后，程序跳?到bootloader去?行。 ?于App的工程配置 App的??代?： #ifndef __STM32F10X_H #define __STM32F10X_H #include "stm32f10x.h" #endif #ifndef __Z_UTIL_TIME_H #define __Z_UTIL_TIME_H #include "z_util_time.h" #endif #ifndef __Z_HARDWARE_LED_H #define __Z_HARDWARE_LED_H #include "z_hardware_led.h" #endif #ifndef __Z_HARDWARE_USART2_H #define __Z_HARDWARE_USART2_H #include "z_hardware_usart2.h" #endif #ifndef __Z_HARDWARE_FLASH_H #define __Z_HARDWARE_FLASH_H #include "z_hardware_flash.h" #endif #ifndef __Z_HARDWARE_SPI_H #define __Z_HARDWARE_SPI_H #include "z_hardware_spi.h" #endif #ifndef __Z_HARDWARE_SWITCHKEYS_H #define __Z_HARDWARE_SWITCHKEYS_H #include "z_hardware_switchkeys.h" #endif #ifndef __W5500_H #define __W5500_H #include "w5500.h" #endif #ifndef __SOCKET_H #define __SOCKET_H #include "socket.h" #endif #ifndef __W5500_CONF_H #define __W5500_CONF_H #include "w5500_conf.h" #endif #ifndef __DHCP_H #define __DHCP_H #include "dhcp.h" #endif #ifndef __HTTPC_H #define __HTTPC_H #include "httpc.h" #endif typedef void (*pFunction)(void); pFunction Jump_To_Bootloader; uint32_t JumpAddress; void func_jump2bootloader(void) { if (((*(__IO uint32_t*)FLASH_BASE_ADDR) & 0x2FFC0000 ) == 0x20000000) { __disable_irq(); JumpAddress = *(__IO uint32_t*) (FLASH_BASE_ADDR + 4); Jump_To_Bootloader = (pFunction) JumpAddress; __set_MSP(*(__IO uint32_t*) FLASH_BASE_ADDR); Jump_To_Bootloader(); } } void func_led_onoff_cross(void); void func_led_onoff_sametime(void); void func_custom_http_downloading_file_save(u8 state, u8 pageno, u8* cache, u32 len_cache_cont)//pageno start from 1 { // func_usart2_dma_send_bytes(cache, len_cache_cont); if(state == 0)//downloading { //write FLASH Backup file content func_flash_write_datas(FLASH_APPBACKUP_ADDR + (pageno-1)*2048, (u16*)cache, SIZE_DOWNLOAD_CACHE/2); } else if(state == 1)//done { //write FLASH Backup file content func_flash_write_datas(FLASH_APPBACKUP_ADDR + (pageno-1)*2048, (u16*)cache, (len_cache_cont%2) == 0 ? (len_cache_cont/2) : (len_cache_cont/2+1)); //write FLASH Record { u16 arrs[4]; u32 downloadsize = (pageno-1)*SIZE_DOWNLOAD_CACHE + len_cache_cont; arrs[0] = 2; arrs[1] = 0xFFFF; arrs[2] = downloadsize >> 16; arrs[3] = (u16)downloadsize; func_flash_write_datas(FLASH_RECORD_ADDR, arrs, 4); } } } u8 buf[2048]; int main() { u8 state_k1_init; u8 mac[6]={0, }; DHCP_Get dhcp_get; //FIXME your file server ip u8 srv_ip[] = {192, 168, 1, 109}; u16 srv_port = 8888; NVIC_SetVectorTable(NVIC_VectTab_FLASH, (FLASH_APPCODE_ADDR - FLASH_BASE_ADDR)); init_led(); init_switchkeys(); init_system_spi(); func_w5500_reset(); // init_hardware_usart2_dma(115200); getMacByLockCode(mac); setSHAR(mac); sysinit(txsize, rxsize); setRTR(2000); setRCR(3); state_k1_init = func_get_switchkey1(); //USART DMA problem: 2 bytes missing // func_usart2_dma_send_bytes(mac, 2); // delay_ms(100); //hook init_hooks_http_download_file_save(func_custom_http_downloading_file_save); //DHCP for(;func_dhcp_get_ip_sub_gw(buf, sizeof(buf), 1, mac, &dhcp_get, 500) != 0;); if(func_dhcp_get_ip_sub_gw(buf, sizeof(buf), 1, mac, &dhcp_get, 500) == 0) { setSUBR(dhcp_get.sub); setGAR(dhcp_get.gw); setSIPR(dhcp_get.lip); close(1); } for(;;) { if(state_k1_init != func_get_switchkey1()) { u8 res; //downlaod bin file and reboot memset(buf, 0 , sizeof(buf)); res = func_http_get_download_file(0, srv_ip, srv_port, "/file/APP_Download.bin_1.1.8", 5000, buf, sizeof(buf)); if(res == 0) { //jump to bootloader func_jump2bootloader(); } state_k1_init = func_get_switchkey1(); } // func_led_onoff_cross(); func_led_onoff_sametime(); } } void func_led_onoff_cross() { func_led1_on(); func_led2_off(); delay_ms(500); func_led2_on(); func_led1_off(); delay_ms(500); } void func_led_onoff_sametime() { func_led1_on(); func_led2_on(); delay_ms(500); func_led2_off(); func_led1_off(); delay_ms(500); } ????果 ?bootloader???生成bin文件，通?STM32 ST-LINK Utility工具，?bootloader下?到0x08000000的位置上，如?： ?App??一版LED1和LED2交叉亮?的固件，通?STM32 ST-LINK Utility工具，?App下?到0x08009000的位置上，如?： 再??一版LED1和LED2同?亮?的固件，上?到文件服?器。 ?位板子后，程序先?行bootloader的LED交叉快速??，?后?入到原始App的LED慢速交叉??。??????，?后?秒，LED交叉快速??，然后??LED同?亮，同??。App固件升?完成！ ?? bootloader和App的思路比???，但是??的?程中，可能?遇到一些坑。??我遇到?的坑： 1、bootloader工程target的FLASH大小配置 2、bootloader工程的startup_stm32f10x_hd.s文件的堆?大小配置?小，?致Debug不好用，配置大一些就好了。 3、bootloader工程操作FLASH的代???，?致bin文件?容串位-通?STM32 ST-LINK Utility工具?? FLASH中??的?容是什?，?而排?解?了??。 4、App工程也是因?FLASH的操作不?，?致用??据????据串位。 ???????????????? 版??明：本文?CSDN博主「Mr_Johhny」的原?文章，遵循CC 4.0 BY-SA版???，???附上原文出??接及本?明。 原文?接：https://blog.csdn.net/lnniyunlong99/article/details/105603666

---

Source: https://maker.wiznet.io/chen/projects/STM32-W5500-OTA-bootloaderapp-by-chen/
