找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3906|回复: 3
收起左侧

基于STM32F4系列的ETH IAP在线升级程序

[复制链接]
ID:136423 发表于 2020-10-19 10:56 | 显示全部楼层 |阅读模式
     此bootloader程序可以通过http或tftp方式更新STm32应用程序,是否进入BOOTLOADER程序可以根据读取板载外接存储器中的字节判断,能够做到做到了现场快速更改程序,省时省力!

STM32F4的以太网移植及IAP
   在移植过程中,对于以太网协议还有许多不理解的地方,通过以后的实践学习,不断深入理解并完善此文档。
1.    以太网的移植(无操作系统
打开LWIP1.4.1 移植文件,需要移植的src 文件port文件。其中port文件移植ethernetif.c/.h文件;src文件移植①api文件中所有.c文件,②core文件中除ipv6及snmp文件外所有文件,③ include中除ipv6及posix外所有的.h文件。由于此处移植无操作系统,所以在IAP_SERVICE 文件中定义了sys_arch.c,其中只有返回外部时间函数return  get_systick()。注意KEIL5相应的路径页需要包含对应的头文件。

2.    移植FATS 系统
FTFP传输文件是512k block形式传送的,需要移植 FATS 文件系统。此处不多说,有比较多的资料讲这块。

3.    移植ETH 驱动及 DP83848驱动
ETH 驱动是从官网上直接移植的,DP83848驱动通过lan8720修改过来的,区别就是lan8720的硬启动需要一定的时延,而DP83848基本上不需要硬重启的时间。需要注意的是在PHY驱动中,有些系统PHY 驱动中启动了MAC中断,那么在主程序中就可以不轮询ETH_CheckFrameReceived()函数,及ETH_DMA 是否接受到数据。反之,如果不启动MAC中断,则需要轮询ETH_CheckFrameReceived()函数。
4.    Tftp 服务程序
Tftp 协议是在udp协议上升级而来,保证了文件传输的准确性。是在udp传输数据的基础上加上了特殊的包头与报位,并且有特定检验传输数据是否有问题的机制。报文格式如图1所示。


图1
  如图2所示,为tftp的传输数据实现过程。在tftpserver.c/h 函数中有详细的TFTP函数实现。在IAP_tftp_process_write()函数中,起始完udp_recv()函数后,起始FLASH开始写文件。需要注意的是,在函数IAP_wrq_recv_callback()中检验是否写完,当接收返回的数据小于512+2+2KB时,说明传输文件完成,需要置标志位,并锁上STM32内部FLASH。
图2

5.    注意事项
程序中以系统时钟作为TCP、ARP定时器(SystickCnt计数变量),在stm32f4xx_it.c 中可以看到,lwip以此时钟为基准调用LwIP_Periodic_Handle(SystickCnt)函数。在中断中,把接收到的缓冲区数据给lwip 处理ethernetif_input(&netif)。
而在netcongf.c 文件中,必须把ARPTimer和TCPTimer的初始值给一个未定义的数值的变量localtime才能传输,这里先这么用。改成ETH_DMAs试验看是否能够解决这个问题。


TFTP_IAP.jpg HTTP_IAP_3.jpg HTTP_IAP_2.jpg HTTP_IAP_1.jpg

单片机源程序如下:
  1. /**
  2.   * @file    main.c
  3.   * @author  WB R&D Team - openmcu666  Debuger by Lyu Xin
  4.   * @version V1.0
  5.   * @date    2017.03.09
  6.   * @brief   Main Program body
  7.   */
  8.         

  9. #include "stm32f4xx.h"
  10. #include "Gpio.h"
  11. #include "usart.h"
  12. #include "main.h"
  13. #include "stm32f4x7_eth.h"
  14. #include "netconf.h"
  15. #include "eth_bsp.h"
  16. #include "Gpio.h"
  17. #include "tftpserver.h"
  18. #include "httpserver.h"
  19. #include "eeprom.h"

  20. //uint8_t  data[40] = "bootloadering...";
  21. uint8_t tftp_flag = 0;      //文件传输完成标识

  22. __IO uint32_t SystickCnt = 0;
  23. typedef  void (*pFunction)(void);
  24. pFunction Jump_To_Application;
  25. uint32_t JumpAddress;

  26. static void delay(__IO uint32_t nCount)
  27. {
  28.   __IO uint32_t index = 0;
  29.   for(index = 80000*nCount; index != 0; index--)
  30.   {
  31.   }
  32. }

  33. uint32_t get_systick(void)
  34. {
  35.   return SystickCnt;
  36. }


  37. //从扇区5开始擦除 ,偏移128KB ,为0x08020000,作为APP起始地址
  38. //可用HTTP或TFTP方式,默认TFTP,如需更改,见main.h文件

  39. /*****************************************************************************
  40. **   Main Function  main()
  41. ******************************************************************************/
  42. int main(void)
  43. {  
  44.         uint8_t write_buf = 0;
  45.         uint8_t read_buf = 0;
  46.         I2C_EE_Init();
  47. #ifdef BOOTLOADER_EN                        
  48.         write_buf = 0x66;               
  49.         I2C_EE_BufferWrite(&write_buf,1,1);                                  //第0块第0字节
  50. #endif
  51.         
  52. #ifdef APP_EN
  53.         write_buf = 0x55;               
  54.         I2C_EE_BufferWrite(&write_buf,1,1);                                  //第0块第0字节
  55. #endif        
  56.         
  57.         I2C_EE_BufferRead(&read_buf,1,1);
  58.   if( read_buf == 0x55 ){   
  59.      iap();
  60.   }
  61.         else if(read_buf != 0x55 ){
  62.            SysTick_Config(SystemCoreClock / 1000);        //systick必须在以太网初始化之前配置
  63.      eth_init();   
  64.      LwIP_Init();
  65. #ifdef USE_IAP_HTTP
  66.      IAP_httpd_init();
  67. #endif
  68.   
  69. #ifdef USE_IAP_TFTP  
  70.     IAP_tftpd_init();
  71. #endif   
  72.      while (1)
  73.                  {
  74.                                 if (ETH_CheckFrameReceived()){
  75.                                          LwIP_Pkt_Handle();
  76.                                         }
  77.                                 LwIP_Periodic_Handle(SystickCnt);
  78.                                 if(tftp_flag == 1){
  79.                                                                 break;
  80.                                 }
  81.                     else{
  82. //                                           UDP_Client_Broadcast(data,40);
  83.                                continue;
  84.                     }
  85.      }
  86.                 iap();
  87.   }
  88. }
  89. void iap(void)
  90. {
  91.                  if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000) == 0x20000000)
  92.                 {
  93.                         //跳转到用户程序
  94.                         JumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
  95.                         Jump_To_Application = (pFunction) JumpAddress;
  96.                         //初始化用户程序的堆栈指针
  97.                         __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
  98.                         Jump_To_Application();
  99.                 }  
  100. }
复制代码

所有资料51hei提供下载:
EHT_IAP 18.11.5 有效.7z (1.41 MB, 下载次数: 116)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:136423 发表于 2020-10-19 10:57 | 显示全部楼层
后期有时间会继续完善
回复

使用道具 举报

ID:960080 发表于 2023-2-1 19:26 | 显示全部楼层
感谢楼主,这帖子帮了大忙了
回复

使用道具 举报

ID:624093 发表于 2023-12-13 19:09 | 显示全部楼层
感谢楼主,真是及时雨!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表