iap.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("AutoChips Software") are
  4. * protected under relevant copyright laws. The information contained herein is
  5. * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
  6. * the prior written permission of AutoChips inc. and/or its licensors, any
  7. * reproduction, modification, use or disclosure of AutoChips Software, and
  8. * information contained herein, in whole or in part, shall be strictly
  9. * prohibited.
  10. *
  11. * AutoChips Inc. (C) 2016. All rights reserved.
  12. *
  13. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  14. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
  15. * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
  16. * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
  17. * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  19. * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
  20. * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
  21. * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
  22. * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
  23. * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
  24. * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
  25. * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
  26. * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  27. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
  28. * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
  29. * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
  30. * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
  31. * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
  32. */
  33. #include <string.h>
  34. //#include "crc16.h"
  35. #include "iap.h"
  36. #include "md5c.h"
  37. #include "global_def.h"
  38. #include "parameters.h"
  39. #include "stdio.h"
  40. //#include "watchdog.h"
  41. static __align(4) uint8_t WriteDataBuff[EFLASH_PAGE_SIZE];
  42. static uint32_t s_writeAddress;
  43. static uint8_t s_iapStep;
  44. static uint32_t s_writeDataBuffSeek;
  45. //升级完成后, 重启标志
  46. uint8_t iap_reboot = 0;
  47. ///< 升级包信息
  48. static uint8_t s_flashType;
  49. static uint32_t s_version[4];
  50. static uint32_t s_flashMemSize;
  51. static uint32_t s_recvByte=0;
  52. static uint16_t s_sequence=0;
  53. //回传数据buffer 指针、 及数据长度
  54. static uint8_t* s_wData = NULL;
  55. static uint16_t s_wLen = 0;
  56. typedef void (*pFunction)(void);
  57. static pFunction s_jumpToApplication;
  58. static uint32_t GetPage(uint32_t Addr)
  59. {
  60. uint32_t page = 0;
  61. if (Addr < (EFLASH_BASE + EFLASH_BANK_SIZE))
  62. {
  63. /* Bank 1 */
  64. page = (Addr - EFLASH_BASE) / EFLASH_PAGE_SIZE;
  65. }
  66. else
  67. {
  68. /* Bank 2 */
  69. page = (Addr - (EFLASH_BASE + EFLASH_BANK_SIZE)) / EFLASH_PAGE_SIZE;
  70. }
  71. return page;
  72. }
  73. /**
  74. * @brief Gets the bank of a given address
  75. * @param Addr: Address of the FLASH Memory
  76. * @retval The bank of a given address
  77. */
  78. static uint32_t GetBank(uint32_t Addr)
  79. {
  80. return FLASH_BANK_1;
  81. }
  82. /**
  83. * JumpTOApp
  84. *
  85. * @param[in] none
  86. * @return none
  87. *
  88. * @brief Jump to APP Code
  89. */
  90. void JumpTOApp1(void)
  91. {
  92. uint32_t JumpAddress;
  93. printf("> IAP JumpTOApp1 ......\r\n");
  94. if(((*(__IO uint32_t *)APP1_ADDRESS) & 0x2FFE0000) == 0x20000000)
  95. {
  96. __set_PRIMASK(1);// 关闭全局中断
  97. JumpAddress = *(__IO uint32_t *)(APP1_ADDRESS + 4); // Jump to user application
  98. s_jumpToApplication = (pFunction)JumpAddress; // Initialize user application's Stack Pointer
  99. __set_MSP(*(__IO uint32_t*)APP1_ADDRESS);
  100. s_jumpToApplication(); /* jump to app */
  101. }
  102. else
  103. {
  104. printf("top of stack pointer is unvalid! enter APP update!\r\n");
  105. return;
  106. }
  107. //while (1);
  108. }
  109. int App_MD5_Check(uint32_t addr,unsigned int all_len)
  110. {
  111. unsigned char digest[16];
  112. // unsigned char *md5_ptr=(unsigned char *)(StartMode_Addr+72);
  113. unsigned int i,update_len;
  114. MD5_CTX md5c;
  115. all_len -= 16;
  116. MD5Init(&md5c);
  117. for(i=0;i<all_len;)
  118. {
  119. if(all_len>(i+512))
  120. update_len = 512;
  121. else
  122. update_len = all_len-i;
  123. memcpy(WriteDataBuff,(const void *)(addr+i),update_len);
  124. MD5Update (&md5c, WriteDataBuff, update_len);
  125. i += update_len;
  126. // Watchdog_Feed();
  127. }
  128. MD5Final(digest,&md5c);
  129. //memcpy(iapbuf,(const void *)(addr+all_len),16);
  130. for(i=0;i<16;++i)
  131. {
  132. if(digest[i]!=*(unsigned char *)(addr+all_len+i))
  133. break;
  134. }
  135. if(i>=16)
  136. return 1;
  137. else
  138. return 0;
  139. }
  140. /*
  141. // appxaddr:应用程序的起始地址
  142. // appbuf:应用程序CODE.
  143. // appsize:应用程序大小(字节).
  144. void IAP_write_appbin(uint32_t appxaddr, uint8_t *appbuf, uint32_t appsize)
  145. {
  146. uint32_t t;
  147. uint16_t i = 0;
  148. uint16_t temp;
  149. uint32_t fwaddr = appxaddr; //当前写入的地址
  150. uint32_t *dfu = appbuf;
  151. for (t = 0; t < appsize; t += 2)
  152. {
  153. temp = (uint16_t)dfu[1] << 8;
  154. temp += (uint16_t)dfu[0];
  155. dfu += 2; //偏移2个字节
  156. iapbuf[i++] = temp;
  157. if (i == 1024)
  158. {
  159. i = 0;
  160. HAL_GPIO_TogglePin(WDI_sp706_kanmemgou_GPIO_Port, WDI_sp706_kanmemgou_Pin);
  161. STMFLASH_Write(fwaddr, iapbuf, 1024);
  162. fwaddr += 2048; //偏移2048 16=2*8.所以要乘以2.
  163. }
  164. }
  165. if (i)
  166. STMFLASH_Write(fwaddr, iapbuf, i); //将最后的一些内容字节写进去.
  167. }
  168. */
  169. //
  170. int IAP_Init(void)
  171. {
  172. /*
  173. EFLASH_StatusType ret = EFLASH_STATUS_SUCCESS;
  174. memcpy(reflectionBuff, (void *)CONFIG_ADDRESS, sizeof(Config_type));
  175. if (config->flag0 != Flag0Value || config->flag1 != flag1Value)
  176. {
  177. // initiliaze flash
  178. memset(reflectionBuff, 0, sizeof(Config_type));
  179. config->flag0 = Flag0Value;
  180. config->flag1 = flag1Value;
  181. EFLASH_UnlockCtrl();
  182. ret = EFLASH_PageErase(CONFIG_ADDRESS); ///<erase page
  183. if (ret != EFLASH_STATUS_SUCCESS) return -1;
  184. ret = EFLASH_PageEraseVerify(CONFIG_ADDRESS); ///< verify erase state
  185. if (ret != EFLASH_STATUS_SUCCESS) return -1;
  186. ret = EFLASH_PageProgram(CONFIG_ADDRESS, (uint32_t *)reflectionBuff, (sizeof(Config_type)>>2)+1); ///<
  187. if (ret != EFLASH_STATUS_SUCCESS) return -1;
  188. EFLASH_LockCtrl();
  189. }
  190. */
  191. s_recvByte=0;
  192. s_sequence=0;
  193. s_version[0] = 0;
  194. s_version[1] = 0;
  195. s_version[2] = 0;
  196. s_version[3] = 0;
  197. s_flashType = 0;
  198. s_flashMemSize = 0;
  199. iap_reboot = 0;
  200. return 0;
  201. }
  202. void IAP_Start(void)
  203. {
  204. if (s_iapStep == 1)
  205. {
  206. return; ///<repeat start
  207. }
  208. s_writeAddress = APP2_ADDRESS;
  209. s_iapStep = 1;
  210. }
  211. int IAP_Write(uint8_t *pdata, uint16_t length)
  212. {
  213. HAL_StatusTypeDef ret = HAL_OK;
  214. FLASH_EraseInitTypeDef pEraseInit;
  215. uint32_t pageError = 0;
  216. uint16_t MiniLength = 0;
  217. if (s_iapStep != 1) ///<防止用户不先调用start就开始写
  218. return -1;
  219. while (length > 0)
  220. {
  221. if ((s_writeAddress < APP2_ADDRESS) || (s_writeAddress >= APP2_ADDRESS_END)) ///<IAP不能超出APP_BKP地址范围
  222. return -1;
  223. if (s_writeDataBuffSeek + length > 2048) ///得到单次写入的长度
  224. {
  225. MiniLength = 2048 - s_writeDataBuffSeek; ///<长度超出buff
  226. }
  227. else
  228. {
  229. MiniLength = length; ///<全部写完,
  230. }
  231. memcpy(&WriteDataBuff[s_writeDataBuffSeek], pdata, MiniLength);
  232. pdata += MiniLength;
  233. s_writeDataBuffSeek += MiniLength;
  234. length -= MiniLength;
  235. if (s_writeDataBuffSeek == 2048)
  236. {
  237. HAL_FLASH_Unlock();
  238. pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
  239. pEraseInit.Page = GetPage(s_writeAddress);
  240. pEraseInit.Banks = GetBank(s_writeAddress);
  241. pEraseInit.NbPages = 1;
  242. ret = HAL_FLASHEx_Erase(&pEraseInit, &pageError);
  243. //if (ret != HAL_OK) return -1;
  244. for(int i=0; i<(EFLASH_PAGE_SIZE>>3); i++){
  245. ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, s_writeAddress+i*8, *(uint64_t *)(WriteDataBuff+i*8));
  246. }
  247. HAL_FLASH_Lock();
  248. s_writeAddress += 2048;
  249. s_writeDataBuffSeek = 0;
  250. }
  251. }
  252. return ret;
  253. }
  254. int IAP_Stop(void)
  255. {
  256. HAL_StatusTypeDef ret = HAL_OK;
  257. FLASH_EraseInitTypeDef pEraseInit;
  258. uint32_t pageError = 0;
  259. s_iapStep = 0; ///<stop后重置step
  260. if ((s_writeAddress < APP2_ADDRESS) || (s_writeAddress >= APP2_ADDRESS_END)) ///<IAP不能超出APP_BKP地址范围
  261. return -1;
  262. HAL_FLASH_Unlock();
  263. pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
  264. pEraseInit.Page = GetPage(s_writeAddress);
  265. pEraseInit.Banks = GetBank(s_writeAddress);
  266. pEraseInit.NbPages = 1;
  267. ret = HAL_FLASHEx_Erase(&pEraseInit, &pageError);
  268. //if (ret != HAL_OK) return -1;
  269. for(int i=0; i<(EFLASH_PAGE_SIZE>>3); i++){
  270. ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, s_writeAddress+i*8, *(uint64_t *)(WriteDataBuff+i*8));
  271. }
  272. HAL_FLASH_Lock();
  273. return ret;
  274. }
  275. /**
  276. * DataTransferRequestHandle
  277. *
  278. * @param[in] pdata:data point
  279. * @param[in] length:data length
  280. *
  281. * @return none
  282. *
  283. * @brief 上位机通信 数据传输请求
  284. */
  285. static void DataTransferRequestHandle(uint8_t *pdata, uint16_t length)
  286. {
  287. uint32_t _version[4];
  288. s_flashType = pdata[2];
  289. _version[0] = ((uint32_t)pdata[3]<<24) | ((uint32_t)pdata[4]<<16)| ((uint32_t)pdata[5]<<8)| pdata[6];
  290. _version[1] = ((uint32_t)pdata[7]<<24) | ((uint32_t)pdata[8]<<16)| ((uint32_t)pdata[9]<<8)| pdata[10];
  291. _version[2] = ((uint32_t)pdata[11]<<24) | ((uint32_t)pdata[12]<<16)| ((uint32_t)pdata[13]<<8)| pdata[14];
  292. _version[3] = ((uint32_t)pdata[15]<<24) | ((uint32_t)pdata[16]<<16)| ((uint32_t)pdata[17]<<8)| pdata[18];
  293. s_flashMemSize = pdata[19];
  294. s_flashMemSize <<= 8;
  295. s_flashMemSize += pdata[20];
  296. s_flashMemSize <<= 8;
  297. s_flashMemSize += pdata[21];
  298. s_flashMemSize <<= 8;
  299. s_flashMemSize += pdata[22];
  300. s_wData[s_wLen++] = DataTransferCmdHost;
  301. s_wData[s_wLen++] = DataTransferRequest;
  302. if (s_flashType != IAP_BIN_FILE) ///<目前只支持传输IAP bin 文件
  303. {
  304. s_wData[s_wLen++] = ResultParamErr;
  305. }
  306. else
  307. {
  308. if (s_flashMemSize > APP_SIZE)
  309. {
  310. s_wData[s_wLen++] = ResultExceedLimit; ///<exceed limit
  311. }
  312. else
  313. {
  314. IAP_Start();
  315. s_wData[s_wLen++] = ResultSuccess;
  316. }
  317. }
  318. s_wData[s_wLen++] = (uint8_t)((MaxBlockSize >> 24) & 0xff);
  319. s_wData[s_wLen++] = (uint8_t)((MaxBlockSize >> 16) & 0xff);
  320. s_wData[s_wLen++] = (uint8_t)((MaxBlockSize >> 8) & 0xff);
  321. s_wData[s_wLen++] = (uint8_t)(MaxBlockSize & 0xff);
  322. //版本不一致
  323. if(0 != memcmp(s_version, _version, 16)){
  324. s_version[0] = _version[0];
  325. s_version[1] = _version[1];
  326. s_version[2] = _version[2];
  327. s_version[3] = _version[3];
  328. s_recvByte=0;
  329. s_sequence=0;
  330. }
  331. s_wData[s_wLen++] = (s_sequence>>8)&0xFF;
  332. s_wData[s_wLen++] = s_sequence&0xFF;
  333. }
  334. /**
  335. * TransferDataHandle
  336. *
  337. * @param[in] pdata:data point
  338. * @param[in] length:data length
  339. *
  340. * @return none
  341. *
  342. * @brief 上位机通信 传输数据处理
  343. */
  344. static void TransferDataHandle(uint8_t *pdata, uint16_t length)
  345. {
  346. uint16_t _sequence = pdata[2];
  347. _sequence <<= 8;
  348. _sequence += pdata[3];
  349. s_wData[s_wLen++] = DataTransferCmdHost;
  350. s_wData[s_wLen++] = DataTransferRequest;
  351. if (length-4 > MaxBlockSize)
  352. {
  353. s_wData[s_wLen++] = ResultExceedLimit; ///<长度超出限制
  354. IAP_Stop();
  355. }
  356. else if (_sequence != s_sequence)
  357. {
  358. s_wData[s_wLen++] = ResultSequenceErr; ///<序列号不正确
  359. IAP_Stop();
  360. }
  361. else
  362. {
  363. if (0 != IAP_Write(&pdata[4], length - 4))
  364. {
  365. s_wData[s_wLen++] = ResultExecErr; ///<执行错误
  366. IAP_Stop();
  367. }else{
  368. s_wData[s_wLen++] = ResultSuccess; ///<succeed
  369. s_recvByte += length - 4;
  370. s_sequence++;
  371. }
  372. }
  373. s_wData[s_wLen++] = (s_sequence>>8)&0xFF;
  374. s_wData[s_wLen++] = s_sequence&0xFF;
  375. }
  376. /**
  377. * TransferExitHandle
  378. *
  379. * @param[in] pdata:data point
  380. * @param[in] length:data length
  381. *
  382. * @return none
  383. *
  384. * @brief 上位机通信 传输数据结束
  385. */
  386. static void TransferExitHandle(uint8_t *pdata, uint16_t length)
  387. {
  388. s_wData[s_wLen++] = DataTransferCmdHost;
  389. s_wData[s_wLen++] = DataTransferRequest;
  390. //crc = ((uint16_t)pdata[2] << 8) | pdata[3];
  391. if (0 != IAP_Stop())
  392. {
  393. s_wData[s_wLen++] = ResultExecErr; ///<执行错误
  394. }
  395. else
  396. {
  397. if (s_recvByte != s_flashMemSize)
  398. {
  399. s_wData[s_wLen++] = ResultTotalLengthErr; ///<接收数据长度不正确
  400. }
  401. else
  402. {
  403. s_wData[s_wLen++] = ResultSuccess;
  404. config->App2Size = s_flashMemSize;
  405. config->IapFlag = Startup_Update;
  406. SaveConfig();
  407. //if (0 != SaveConfig())
  408. //{
  409. // data[index] = ResultExecErr;
  410. //}
  411. iap_reboot = 1;
  412. }
  413. }
  414. }
  415. /**
  416. * IAP_CmdHandle
  417. *
  418. * @param[in] pdata:recv data point
  419. * @param[in] length:data length
  420. * @param[in] pout:send data point
  421. * @return none
  422. *
  423. * @brief 上位机通信 数据接收处理函数
  424. */
  425. uint16_t IAP_CmdHandle(uint8_t* pdata, uint16_t length, uint8_t* pout)
  426. {
  427. s_wData = pout;
  428. s_wLen = 0;
  429. if(DataTransferCmd == pdata[0]){
  430. switch (pdata[1])
  431. {
  432. case DataTransferRequest: //0x00
  433. DataTransferRequestHandle(pdata, length);
  434. break;
  435. case TransferData: //0x01
  436. TransferDataHandle(pdata, length);
  437. break;
  438. case TransferExit: //0x02
  439. TransferExitHandle(pdata, length);
  440. break;
  441. default :
  442. s_wData[0] = ResultCmdErr;
  443. s_wLen = 1;
  444. break;
  445. }
  446. }else{
  447. s_wData[0] = ResultCmdErr;
  448. s_wLen = 1;
  449. }
  450. return s_wLen;
  451. }
  452. /**
  453. * @bieaf 进行BootLoader的启动
  454. *
  455. * @param none
  456. * @return none
  457. */
  458. void Start_BootLoader(void)
  459. {
  460. //uint16_t crcCheck;
  461. uint32_t writed_len;
  462. uint32_t will_write_len;
  463. HAL_StatusTypeDef ret = HAL_OK;
  464. FLASH_EraseInitTypeDef pEraseInit;
  465. uint32_t pageError = 0;
  466. switch (config->IapFlag) ///< 读取是否启动应用程序 */
  467. {
  468. case Startup_Normal: ///< 正常启动 */ //在APP2中可以设定此标志位 使得下次重启之后进入APP1
  469. {
  470. printf("> IAP Normal start......\r\n");
  471. break;
  472. }
  473. case Startup_Update: /*启动最新的程序 */
  474. printf("> IAP Update start......\r\n");
  475. //crcCheck = crc16((const uint8_t *)APP2_ADDRESS, config->App2Size);
  476. if ((config->App2Size <= APP_SIZE) && App_MD5_Check(APP2_ADDRESS,config->App2Size))
  477. {
  478. writed_len =0;
  479. will_write_len = config->App2Size;
  480. do{
  481. //Watchdog_Feed();
  482. if(will_write_len >= 2048){
  483. memcpy(WriteDataBuff, (void *)(APP2_ADDRESS+writed_len), 2048);
  484. // EFLASH_UnlockCtrl();
  485. // ret = EFLASH_PageErase(APP1_ADDRESS+writed_len); ///<erase page
  486. // if (ret != EFLASH_STATUS_SUCCESS) break;
  487. // ret = EFLASH_PageEraseVerify(APP1_ADDRESS+writed_len); ///< verify erase state
  488. // if (ret != EFLASH_STATUS_SUCCESS) break;
  489. // ret = EFLASH_PageProgram(APP1_ADDRESS+writed_len, (uint32_t *)WriteDataBuff, 512);
  490. // if (ret != EFLASH_STATUS_SUCCESS) break;
  491. // EFLASH_LockCtrl();
  492. HAL_FLASH_Unlock();
  493. pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
  494. pEraseInit.Page = GetPage(APP1_ADDRESS+writed_len);
  495. pEraseInit.Banks = GetBank(APP1_ADDRESS+writed_len);
  496. pEraseInit.NbPages = 1;
  497. ret = HAL_FLASHEx_Erase(&pEraseInit, &pageError);
  498. //if (ret != HAL_OK) return -1;
  499. for(int i=0; i<(EFLASH_PAGE_SIZE>>3); i++){
  500. ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, APP1_ADDRESS+writed_len+i*8, *(uint64_t *)(WriteDataBuff+i*8));
  501. }
  502. HAL_FLASH_Lock();
  503. writed_len += 2048;
  504. will_write_len -= 2048;
  505. }else{
  506. memcpy(WriteDataBuff, (void *)(APP2_ADDRESS+writed_len), will_write_len);
  507. // EFLASH_UnlockCtrl();
  508. // ret = EFLASH_PageErase(APP1_ADDRESS+writed_len); ///<erase page
  509. // if (ret != EFLASH_STATUS_SUCCESS) break;
  510. // ret = EFLASH_PageEraseVerify(APP1_ADDRESS+writed_len); ///< verify erase state
  511. // if (ret != EFLASH_STATUS_SUCCESS) break;
  512. // ret = EFLASH_PageProgram(APP1_ADDRESS+writed_len, (uint32_t *)WriteDataBuff, (will_write_len+3)/4);
  513. // if (ret != EFLASH_STATUS_SUCCESS) break;
  514. // EFLASH_LockCtrl();
  515. HAL_FLASH_Unlock();
  516. pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
  517. pEraseInit.Page = GetPage(APP1_ADDRESS+writed_len);
  518. pEraseInit.Banks = GetBank(APP1_ADDRESS+writed_len);
  519. pEraseInit.NbPages = 1;
  520. ret = HAL_FLASHEx_Erase(&pEraseInit, &pageError);
  521. //if (ret != HAL_OK) return -1;
  522. for(int i=0; i<(will_write_len+7)/8; i++){
  523. ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, APP1_ADDRESS+writed_len+i*8, *(uint64_t *)(WriteDataBuff+i*8));
  524. }
  525. HAL_FLASH_Lock();
  526. writed_len += will_write_len;
  527. will_write_len = 0;
  528. }
  529. }while(will_write_len > 0);
  530. if(HAL_OK == ret){
  531. config->App1Size = config->App2Size;
  532. }
  533. }
  534. config->IapFlag = Startup_APP1;
  535. SaveConfig();
  536. case Startup_APP1: /*启动最新的程序 */
  537. printf("> IAP Startup app1 ......\r\n");
  538. //crcCheck = crc16((const uint8_t *)APP1_ADDRESS, config->App1Size);
  539. if((config->App1Size <= APP_SIZE) && App_MD5_Check(APP1_ADDRESS,config->App1Size))
  540. {
  541. printf("> IAP Startup app1 222 ......\r\n");
  542. JumpTOApp1();
  543. }
  544. break;
  545. default: ///< 启动失败
  546. {
  547. return;
  548. }
  549. }
  550. }