当前位置:   article > 正文

基于STM32单片机BOOTLOADER通过串口升级程序IAP——APP方案_stm32 bootloader 跳转完成后如何接收升级命令

stm32 bootloader 跳转完成后如何接收升级命令

                        此方法前提是你得有一个EEPROM

        我用的单片机是STM32F103ZET6 , 此单片机FLASH容量为512KB;

在此单片机里面FLASH的起始地址是0X8000000,BOOT作为引导加载程序一般都是从这个地址开始,单片机一上点默认会从这个地址开始运行,所以将自己的BOOT程序放在这个地址。

         其实boot也是个程序,只是他的主要功能是处理升级包。

        我将FLASH分成三个块,第一块是BOOT区,第二块是程序缓存区,第三块是APP区

BOOT

                我的boot代码大概33KB左右,所以我预留了40KB作为BOOT区

CODE 

                这个区是代码缓存区,一共160KB,将串口接收到的代码先存放在这个位置,等全部接受完成了,再把code区的代码移到APP区,然后跳转到APP就算完成bootloader

APP

                这一块是我的主要代码运行区,我预留了312KB

程序运行逻辑

BOOT启动-----》读取EEPROM,判断有没有更新: 

如果有---》将CODE区的代码移到APP区,然后跳转到APP区;

 如果没有-----》等待一段时间,如果接收到新的升级包,先把数据存放到CODE区,等全部接受完成了移到APP区。如果没有接收到升级包,直接跳转到APP

APP启动--------》等待接受升级包,如果接收到升级包,重启单片机,回到BOOT

BOOT程序里判断EEPROM状态代码

这个放在main函数里。运行此段之前先初始化串口和EEPROM

  1. uint32_t readAddr ; //程序缓存区地址
  2. uint32_t app_wrinte_addr; //APP启动地址
  3. uint32_t app_size; //升级包大小
  4. uint8_t read_write_buf[1200];
  5. uint8_t BOOTloader_ST=0;
  6. //检查EEPROM
  7. if(AT24CXX_Check()==0)//检查器件EEPROM已经初始化
  8. {
  9. USART3_Send_Str("------------------------------------------------------\r\n");
  10. USART3_Send_Str("---------BOOTLOADER程序正在运行正常--------------------\r\n");
  11. USART3_Send_Str("EEPROM硬件正常\r\n");
  12. //初始化bootloader状态
  13. BOOTloader_ST = AT24CXX_ReadOneByte(999);//升级标志位在最后面
  14. switch(BOOTloader_ST)
  15. {
  16. //无需升级
  17. case 0XA0: //等待10个心跳时间后如果还是没有收到升级包跳转APP
  18. //直接跳过
  19. USART3_Send_Str(" 等待接受升级程序\r\n");
  20. // iap_load_app(0X8032000);
  21. break;
  22. //准备升级
  23. case 0XA1: //擦除FLASH,准备接受
  24. AT24CXX_WriteOneByte(999,0XA0); //初始化时等于0XA1说明接受失败
  25. USART3_Send_Str("准备升级--升级失败--等待接受升级程序\r\n");
  26. break;
  27. //正在接受数据
  28. case 0XA2: //等待接受完成,超时跳转APP
  29. AT24CXX_WriteOneByte(999,0XA0); //初始化时等于0XA2说明接受失败
  30. USART3_Send_Str("接受中断--升级失败--等待接受升级程序\r\n");
  31. break;
  32. //等待升级命令
  33. case 0XA3: //等待开始升级命令
  34. AT24CXX_WriteOneByte(999,0XA0); //初始化时等于0XA3说明接受失败
  35. USART3_Send_Str("接受完成---等待接受升级命令\r\n");
  36. break;
  37. //接受失败
  38. case 0XA4:
  39. AT24CXX_WriteOneByte(999,0XA0); //初始化时等于0XA4说明接受失败
  40. BOOTloader_ST = 0XA0;
  41. USART3_Send_Str("---接受中断--升级失败--等待接受升级程序-----\r\n");
  42. break;
  43. //开始升级
  44. case 0XA5: //擦除APP区,缓存的升级包移到APP区,跳转到APP区
  45. AT24CXX_WriteOneByte(999,0XA6); //升级
  46. USART3_Send_Str("---------接受完成---开始升级----------\r\n");
  47. app_size = (AT24CXX_ReadOneByte(1000)<<24) | (AT24CXX_ReadOneByte(1001)<<16)| (AT24CXX_ReadOneByte(1002)<<8) |AT24CXX_ReadOneByte(1003);
  48. app_wrinte_addr = 0X8032000; //APP地址
  49. readAddr = 0X800A000; //代码缓存区地址
  50. while (app_size> 0)
  51. {
  52. if (app_size>=1024)
  53. {
  54. System_ReadInteriorFlash (readAddr, read_write_buf, 1024) ;
  55. System_WriteInteriorFlash(app_wrinte_addr,read_write_buf, 1024);
  56. readAddr+=1024;
  57. app_size-=1024;
  58. app_wrinte_addr+= 1024; //写入地址增加
  59. }
  60. else
  61. {
  62. System_ReadInteriorFlash (readAddr, read_write_buf,app_size);
  63. System_WriteInteriorFlash(app_wrinte_addr,read_write_buf,app_size);
  64. readAddr+=app_size;
  65. app_size-=app_size;
  66. app_wrinte_addr+= 1024; //写入地址增加
  67. }
  68. }
  69. USART3_Send_Str("--------------即将跳转APP----------\r\n");
  70. iap_load_app(0X8032000); //跳转到APP
  71. break;
  72. //升级成功,无需
  73. case 0XA6: //回到无需升级
  74. USART3_Send_Str("--------------升级成功-----------\r\n");
  75. AT24CXX_WriteOneByte(999,0XA0); //等待新更新
  76. break;
  77. default : //可能是第一次上电,默认回到0XA0状态
  78. AT24CXX_WriteOneByte(999,0XA0);
  79. break;
  80. }
  81. }

在串口接受协议里面运行的代码

  1. //下面这个几个变量是全局变量,不能用局部变量
  2. framne_all = uart485buff[6]<<8 | uart485buff[7]; //包总数
  3. frame_num = uart485buff[8]<<8 | uart485buff[9]; //包序号
  4. writesize = uart485buff[10]<<8 | uart485buff[11]; //数据大小
  5. if(frame_num==0) //第一包
  6. {
  7. writeaddr = 0x800A000;
  8. AT24CXX_WriteOneByte(999,0XA2); //正在接受数据
  9. System_WriteInteriorFlash(writeaddr, &uart485buff[12] , writesize) ; //写入到内部FLASH
  10. writeaddr += writesize;
  11. }
  12. else if(frame_num == (framne_all-1)) //最后一包
  13. {
  14. BOOTloader_ST = 0XA5;
  15. AT24CXX_WriteOneByte(999,0XA5); //开始升级
  16. System_WriteInteriorFlash(writeaddr, &uart485buff[12] , writesize) ; //写入到内部FLASH
  17. writeaddr += writesize;
  18. AT24CXX_WriteOneByte(999,0XA5); //开始升级
  19. USART3_Send_Str("\r\n");
  20. USART3_Send_Str("---升级包全部接受完成--即将重启--\r\n");
  21. writeaddr-=0x800A000;
  22. AT24CXX_WriteOneByte(1000,((u8)(writeaddr>>24)&0xFF));
  23. AT24CXX_WriteOneByte(1001,((u8)(writeaddr>>16)&0xFF));
  24. AT24CXX_WriteOneByte(1002,((u8)(writeaddr>>8)&0xFF));
  25. AT24CXX_WriteOneByte(1003,((u8)(writeaddr)&0xFF));
  26. reboot(); //重启或者跳转到0X8000000地址
  27. }
  28. else
  29. {
  30. System_WriteInteriorFlash(writeaddr,&uart485buff[12] , writesize) ; //写入到内部FLASH
  31. writeaddr += writesize;
  32. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/67556
推荐阅读
相关标签
  

闽ICP备14008679号