boot.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #include "gd32f10x.h"
  2. #include "boot.h"
  3. #include "main.h"
  4. #include "delay.h"
  5. #include "fmc.h"
  6. #include "w25q32.h"
  7. #include <stdio.h>
  8. #include "ota_message.h"
  9. #include "ec800m.h"
  10. #include "usart.h"
  11. #define APP_PROGRAMMER_BLOCK 2 //程序在W25Q32中存放的位置
  12. load_a load_A;
  13. //返回str在数组中的索引
  14. static char* find_string(char *strs, char *str,int first, int len)
  15. {
  16. int i = 0;
  17. char *start = NULL;
  18. strs = strs + first;
  19. while(i < len){
  20. start = strstr(strs, str);
  21. if(start != NULL){
  22. break;
  23. }
  24. i++;
  25. strs++;
  26. }
  27. if(i == len + 1){
  28. return NULL;
  29. }
  30. return start;
  31. }
  32. int WaitForReadData(uint8_t* data,int timeout,int datalen)
  33. {
  34. uint32_t len = 0;
  35. bool timeoutFlag = false;
  36. if (timeout >= 0)
  37. {
  38. timeoutFlag = true;
  39. }
  40. while (1)
  41. {
  42. Delay_Ms(50);
  43. if ((UART0_RX_STAT > 0) && (find_string((char *)&UART0_RX_BUF, "\r\nOK\r\n",datalen, sizeof(UART0_RX_BUF))))
  44. {
  45. UART0_RX_STAT = 0;
  46. // char *p = strstr((char *)&UART0_RX_BUF, "CONNECT ");
  47. // if (p)
  48. // {
  49. // p += 8;
  50. // sscanf(p, "%u\r", &len); // 读取长度
  51. // if(len == datalen)
  52. // {
  53. // p = strchr(p, '\n') + 1; // 跳过换行
  54. memcpy(data,(char *)&UART0_RX_BUF,datalen);
  55. Clear_DMA_Buffer();
  56. return datalen;
  57. // }
  58. // else
  59. // {
  60. // Clear_DMA_Buffer();
  61. // return len;
  62. // }
  63. }
  64. timeout -= 50;
  65. if (timeoutFlag == true && timeout <= 0)
  66. {
  67. Clear_DMA_Buffer();
  68. return -1;
  69. }
  70. }
  71. }
  72. //进入bootloader更新
  73. void BootLoader_Brance(uint32_t app_byte)
  74. {
  75. GD32_EraseFlash(GD32_A_START_PAGE,GD32_A_PAGE_NUM);//擦除A区原有程序
  76. /* 打开UFS:otaDATA.txt */
  77. EC800MSendCmd(CLOSE_otaDATA_FILE,strlen(CLOSE_otaDATA_FILE));
  78. WaitResponse("QFCLOSE",1000);
  79. EC800MSendCmd(OPEN_otaDATA_FILE,strlen(OPEN_otaDATA_FILE));
  80. if(WaitResponse("QFOPEN:", 2000) == 0)
  81. return;
  82. for(uint8_t i=0;i<app_byte/1024;i++) //1KB写一次
  83. {
  84. uint8_t app_programmer[1024];
  85. memset(app_programmer,0,1024);
  86. // uint32_t addr=APP_PROGRAMMER_BLOCK*64*1024+i*1024; //其在w25q32中的地址
  87. // W25Q32_Read(app_programmer,addr,1024);
  88. while(1)
  89. {
  90. task_fwdgt_reload();
  91. int x = 0;
  92. EC800MSendCmd(READ_otaDATA_FILE,strlen(READ_otaDATA_FILE));
  93. Delay_Ms(200);
  94. x = WaitForReadData(app_programmer,2000,1024);
  95. // if((x != 1024) && (x != -1))
  96. // {
  97. // char* SEEK_otaDATA_FILE = "";
  98. // sprintf(SEEK_otaDATA_FILE,"AT+QFSEEK=1,%d,2\r\n",x);
  99. // EC800MSendCmd(SEEK_otaDATA_FILE,strlen(SEEK_otaDATA_FILE)); //出错的话文件指针向左偏移1024个字节
  100. // }
  101. // else
  102. if(x == 1024)
  103. {
  104. break;
  105. }
  106. }
  107. GD32_WriteFlash(GD32_A_SADDR+i*1024,(uint32_t *)&app_programmer,1024); //将读出的数据按页写入数据
  108. Delay_Ms(50);
  109. }
  110. //将不满1024数据单独写入
  111. if(app_byte % 1024 != 0)
  112. {
  113. uint32_t startAddress=(app_byte/1024)*1024;
  114. uint8_t app_programmer[1024];
  115. memset(app_programmer,0,1024);
  116. // uint32_t addr=APP_PROGRAMMER_BLOCK*64*1024+(app_byte/1024)*1024; //其在w25q32中的地址
  117. // W25Q32_Read(app_programmer,addr,app_byte%1024);
  118. while(1)
  119. {
  120. task_fwdgt_reload();
  121. int x = 0;
  122. EC800MSendCmd(READ_otaDATA_FILE,strlen(READ_otaDATA_FILE));
  123. Delay_Ms(200);
  124. x = WaitForReadData(app_programmer,2000,app_byte % 1024);
  125. // if(x != (app_byte % 1024) && (x != -1))
  126. // {
  127. // char* SEEK_otaDATA_FILE = "";
  128. // sprintf(SEEK_otaDATA_FILE,"AT+QFSEEK=1,%d,2\r\n",x);
  129. // EC800MSendCmd(SEEK_otaDATA_FILE,strlen(SEEK_otaDATA_FILE)); //出错的话文件指针向左偏移读取字节数
  130. // }
  131. // else
  132. if(x == (app_byte % 1024))
  133. {
  134. break;
  135. }
  136. }
  137. GD32_WriteFlash(GD32_A_SADDR+(app_byte/1024)*1024,(uint32_t *)&app_programmer,app_byte % 1024);
  138. Delay_Ms(50);
  139. }
  140. // 保存UFS文件
  141. while(1)
  142. {
  143. EC800MSendCmd(CLOSE_otaDATA_FILE,strlen(CLOSE_otaDATA_FILE));
  144. if(WaitResponse("OK", 2000) == 1)
  145. {
  146. break;
  147. }
  148. }
  149. Delay_Ms(50);
  150. clear_ota_message_config_block();
  151. LOAD_A(GD32_A_SADDR);
  152. }
  153. /*-------------------------------------------------*/
  154. /*函数名:设置SP */
  155. /*参 数:addr:栈顶指针初始值 */
  156. /*返回值:无 */
  157. /*-------------------------------------------------*/
  158. __asm void MSR_SP(uint32_t addr)
  159. {
  160. MSR MSP, r0
  161. BX r14
  162. }
  163. /*-------------------------------------------------*/
  164. /*函数名:跳转到A区 */
  165. /*参 数:addr:A区的起始地址 */
  166. /*返回值:无 */
  167. /*-------------------------------------------------*/
  168. void LOAD_A(uint32_t addr)
  169. {
  170. if((*(uint32_t *)addr>=0x20000000)&&(*(uint32_t *)addr<=0x20017FFF)){
  171. MSR_SP(*(uint32_t *)addr);
  172. load_A = (load_a)*(uint32_t *)(addr+4);
  173. BootLoader_Clear();
  174. load_A();
  175. }else ;
  176. }
  177. /*-------------------------------------------------*/
  178. /*函数名:清除B区使用的外设 */
  179. /*参 数:无 */
  180. /*返回值:无 */
  181. /*-------------------------------------------------*/
  182. void BootLoader_Clear(void)
  183. {
  184. gpio_deinit(GPIOA);
  185. gpio_deinit(GPIOB);
  186. }