IAP.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  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 "flash.h"
  38. #include "WDG.h"
  39. static __align(4)uint8_t WriteDataBuff[2048];
  40. static uint32_t s_writeAddress;
  41. static uint8_t s_iapStep;
  42. static uint32_t s_writeDataBuffSeek;
  43. //升级完成后, 重启标志
  44. uint8_t iap_reboot = 0;
  45. ///< 升级包信息
  46. static uint8_t s_flashType;
  47. static uint32_t s_version[4];
  48. static uint32_t s_flashMemSize;
  49. static uint32_t s_recvByte=0;
  50. static uint16_t s_sequence=0;
  51. //回传数据buffer 指针、 及数据长度
  52. static uint8_t* s_wData = NULL;
  53. static uint16_t s_wLen = 0;
  54. typedef void (*pFunction)(void);
  55. static pFunction s_jumpToApplication;
  56. /**
  57. * JumpTOApp
  58. *
  59. * @param[in] none
  60. * @return none
  61. *
  62. * @brief Jump to APP Code
  63. */
  64. void JumpTOApp1(void)
  65. {
  66. uint32_t JumpAddress;
  67. //if ( (*(__IO uint32_t *)APP1_ADDRESS) <= 0x80000)
  68. if (((*(__IO uint32_t *)APP1_ADDRESS) >= 0x1FFF0000) && ((*(__IO uint32_t *)APP1_ADDRESS) <= 0x2000EFFF))
  69. {
  70. DisableInterrupts /* 关全局中断 */
  71. s_jumpToApplication = (pFunction)(*(__IO uint32_t *)(APP1_ADDRESS + 4)); /* 指向APP程序的Reset中断*/
  72. __set_MSP(*(__IO uint32_t*)APP1_ADDRESS);
  73. s_jumpToApplication();
  74. }
  75. else
  76. {
  77. //printf("top of stack pointer is unvalid! enter APP update!\r\n");
  78. return;
  79. }
  80. while (1);
  81. }
  82. int App_MD5_Check(uint32_t addr,unsigned int all_len)
  83. {
  84. unsigned char digest[16];
  85. // unsigned char *md5_ptr=(unsigned char *)(StartMode_Addr+72);
  86. unsigned int i,update_len;
  87. MD5_CTX md5c;
  88. all_len -= 16;
  89. MD5Init(&md5c);
  90. for(i=0;i<all_len;)
  91. {
  92. if(all_len>(i+512))
  93. update_len = 512;
  94. else
  95. update_len = all_len-i;
  96. //memcpy(WriteDataBuff,(const void *)(addr+i),update_len);
  97. FLASH_DRV_Read(&g_Flash_Config,(addr+i), (uint8_t*)WriteDataBuff, update_len);
  98. MD5Update (&md5c, WriteDataBuff, update_len);
  99. i += update_len;
  100. WDG_Feed();
  101. }
  102. MD5Final(digest,&md5c);
  103. //memcpy(iapbuf,(const void *)(addr+all_len),16);
  104. for(i=0;i<16;++i)
  105. {
  106. if(digest[i]!=*(unsigned char *)(addr+all_len+i))
  107. break;
  108. }
  109. if(i>=16)
  110. return 1;
  111. else
  112. return 0;
  113. }
  114. /*
  115. // appxaddr:应用程序的起始地址
  116. // appbuf:应用程序CODE.
  117. // appsize:应用程序大小(字节).
  118. void IAP_write_appbin(uint32_t appxaddr, uint8_t *appbuf, uint32_t appsize)
  119. {
  120. uint32_t t;
  121. uint16_t i = 0;
  122. uint16_t temp;
  123. uint32_t fwaddr = appxaddr; //当前写入的地址
  124. uint32_t *dfu = appbuf;
  125. for (t = 0; t < appsize; t += 2)
  126. {
  127. temp = (uint16_t)dfu[1] << 8;
  128. temp += (uint16_t)dfu[0];
  129. dfu += 2; //偏移2个字节
  130. iapbuf[i++] = temp;
  131. if (i == 1024)
  132. {
  133. i = 0;
  134. HAL_GPIO_TogglePin(WDI_sp706_kanmemgou_GPIO_Port, WDI_sp706_kanmemgou_Pin);
  135. STMFLASH_Write(fwaddr, iapbuf, 1024);
  136. fwaddr += 2048; //偏移2048 16=2*8.所以要乘以2.
  137. }
  138. }
  139. if (i)
  140. STMFLASH_Write(fwaddr, iapbuf, i); //将最后的一些内容字节写进去.
  141. }
  142. */
  143. //
  144. int IAP_Init(void)
  145. {
  146. s_recvByte=0;
  147. s_sequence=0;
  148. s_version[0] = 0;
  149. s_version[1] = 0;
  150. s_version[2] = 0;
  151. s_version[3] = 0;
  152. s_flashType = 0;
  153. s_flashMemSize = 0;
  154. iap_reboot = 0;
  155. return 0;
  156. }
  157. void IAP_Start(void)
  158. {
  159. if (s_iapStep == 1)
  160. {
  161. return; ///<repeat start
  162. }
  163. s_writeAddress = APP2_ADDRESS;
  164. s_iapStep = 1;
  165. }
  166. int IAP_Write(uint8_t *pdata, uint16_t length)
  167. {
  168. status_t ret = STATUS_SUCCESS;
  169. uint16_t MiniLength = 0;
  170. if (s_iapStep != 1) ///<防止用户不先调用start就开始写
  171. return -1;
  172. while (length > 0)
  173. {
  174. if ((s_writeAddress < APP2_ADDRESS) || (s_writeAddress >= APP2_ADDRESS_END)) ///<IAP不能超出APP_BKP地址范围
  175. return -1;
  176. if (s_writeDataBuffSeek + length > EFLASH_PAGE_SIZE_INIT) ///得到单次写入的长度
  177. {
  178. MiniLength = EFLASH_PAGE_SIZE_INIT - s_writeDataBuffSeek; ///<长度超出buff
  179. }
  180. else
  181. {
  182. MiniLength = length; ///<全部写完,
  183. }
  184. memcpy(&WriteDataBuff[s_writeDataBuffSeek], pdata, MiniLength);
  185. pdata += MiniLength;
  186. s_writeDataBuffSeek += MiniLength;
  187. length -= MiniLength;
  188. if (s_writeDataBuffSeek == EFLASH_PAGE_SIZE_INIT)
  189. {
  190. FLASH_DRV_UnlockCtrl();
  191. //ret = EFLASH_PageErase(s_writeAddress); ///<erase page
  192. ret = FLASH_DRV_EraseSector(&g_Flash_Config, s_writeAddress, EFLASH_PAGE_SIZE_INIT);
  193. if (ret != STATUS_SUCCESS) return -1;
  194. //ret = EFLASH_PageEraseVerify(s_writeAddress); ///< verify erase state
  195. ret = FLASH_DRV_VerifySection(&g_Flash_Config,s_writeAddress, EFLASH_PAGE_SIZE_INIT/8);
  196. if (ret != STATUS_SUCCESS) return -1;
  197. //ret = EFLASH_PageProgram(s_writeAddress, (uint32_t *)WriteDataBuff, 512);
  198. ret = FLASH_DRV_Program(&g_Flash_Config, s_writeAddress, EFLASH_PAGE_SIZE_INIT, (uint8_t*)WriteDataBuff);
  199. if (ret != STATUS_SUCCESS) return -1;
  200. FLASH_DRV_LockCtrl();
  201. s_writeAddress += EFLASH_PAGE_SIZE_INIT;
  202. s_writeDataBuffSeek = 0;
  203. }
  204. }
  205. return 0;
  206. }
  207. int IAP_Stop(void)
  208. {
  209. status_t ret = STATUS_SUCCESS;
  210. s_iapStep = 0; ///<stop后重置step
  211. if ((s_writeAddress < APP2_ADDRESS) || (s_writeAddress >= APP2_ADDRESS_END)) ///<IAP不能超出APP_BKP地址范围
  212. return -1;
  213. FLASH_DRV_UnlockCtrl();
  214. //ret = EFLASH_PageErase(s_writeAddress); ///<erase page
  215. ret = FLASH_DRV_EraseSector(&g_Flash_Config, s_writeAddress, EFLASH_PAGE_SIZE_INIT);
  216. if (ret != STATUS_SUCCESS) return -1;
  217. //ret = EFLASH_PageEraseVerify(s_writeAddress); ///< verify erase state
  218. ret = FLASH_DRV_VerifySection(&g_Flash_Config,s_writeAddress, EFLASH_PAGE_SIZE_INIT/8);
  219. if (ret != STATUS_SUCCESS) return -1;
  220. //ret = EFLASH_PageProgram(s_writeAddress, (uint32_t *)WriteDataBuff, 512); ///<此处应该不满2048,但还是全部写入,后面为多余字节
  221. ret = FLASH_DRV_Program(&g_Flash_Config, s_writeAddress, EFLASH_PAGE_SIZE_INIT, (uint8_t*)WriteDataBuff);
  222. if (ret != STATUS_SUCCESS) return -1;
  223. FLASH_DRV_LockCtrl();
  224. return 0;
  225. }
  226. /**
  227. * DataTransferRequestHandle
  228. *
  229. * @param[in] pdata:data point
  230. * @param[in] length:data length
  231. *
  232. * @return none
  233. *
  234. * @brief 上位机通信 数据传输请求
  235. */
  236. static void DataTransferRequestHandle(uint8_t *pdata, uint16_t length)
  237. {
  238. uint32_t _version[4];
  239. s_flashType = pdata[2];
  240. _version[0] = ((uint32_t)pdata[3]<<24) | ((uint32_t)pdata[4]<<16)| ((uint32_t)pdata[5]<<8)| pdata[6];
  241. _version[1] = ((uint32_t)pdata[7]<<24) | ((uint32_t)pdata[8]<<16)| ((uint32_t)pdata[9]<<8)| pdata[10];
  242. _version[2] = ((uint32_t)pdata[11]<<24) | ((uint32_t)pdata[12]<<16)| ((uint32_t)pdata[13]<<8)| pdata[14];
  243. _version[3] = ((uint32_t)pdata[15]<<24) | ((uint32_t)pdata[16]<<16)| ((uint32_t)pdata[17]<<8)| pdata[18];
  244. s_flashMemSize = pdata[19];
  245. s_flashMemSize <<= 8;
  246. s_flashMemSize += pdata[20];
  247. s_flashMemSize <<= 8;
  248. s_flashMemSize += pdata[21];
  249. s_flashMemSize <<= 8;
  250. s_flashMemSize += pdata[22];
  251. s_wData[s_wLen++] = DataTransferCmdHost;
  252. s_wData[s_wLen++] = DataTransferRequest;
  253. if (s_flashType != IAP_BIN_FILE) ///<目前只支持传输IAP bin 文件
  254. {
  255. s_wData[s_wLen++] = ResultParamErr;
  256. }
  257. else
  258. {
  259. if (s_flashMemSize > APP_SIZE)
  260. {
  261. s_wData[s_wLen++] = ResultExceedLimit; ///<exceed limit
  262. }
  263. else
  264. {
  265. IAP_Start();
  266. s_wData[s_wLen++] = ResultSuccess;
  267. }
  268. }
  269. s_wData[s_wLen++] = (uint8_t)((MaxBlockSize >> 24) & 0xff);
  270. s_wData[s_wLen++] = (uint8_t)((MaxBlockSize >> 16) & 0xff);
  271. s_wData[s_wLen++] = (uint8_t)((MaxBlockSize >> 8) & 0xff);
  272. s_wData[s_wLen++] = (uint8_t)(MaxBlockSize & 0xff);
  273. //版本不一致
  274. if(0 != memcmp(s_version, _version, 16)){
  275. s_version[0] = _version[0];
  276. s_version[1] = _version[1];
  277. s_version[2] = _version[2];
  278. s_version[3] = _version[3];
  279. s_recvByte=0;
  280. s_sequence=0;
  281. }
  282. s_wData[s_wLen++] = (s_sequence>>8)&0xFF;
  283. s_wData[s_wLen++] = s_sequence&0xFF;
  284. }
  285. /**
  286. * TransferDataHandle
  287. *
  288. * @param[in] pdata:data point
  289. * @param[in] length:data length
  290. *
  291. * @return none
  292. *
  293. * @brief 上位机通信 传输数据处理
  294. */
  295. static void TransferDataHandle(uint8_t *pdata, uint16_t length)
  296. {
  297. uint16_t _sequence = pdata[2];
  298. _sequence <<= 8;
  299. _sequence += pdata[3];
  300. s_wData[s_wLen++] = DataTransferCmdHost;
  301. s_wData[s_wLen++] = DataTransferRequest;
  302. if (length-4 > MaxBlockSize)
  303. {
  304. s_wData[s_wLen++] = ResultExceedLimit; ///<长度超出限制
  305. IAP_Stop();
  306. }
  307. else if (_sequence != s_sequence)
  308. {
  309. s_wData[s_wLen++] = ResultSequenceErr; ///<序列号不正确
  310. IAP_Stop();
  311. }
  312. else
  313. {
  314. if (0 != IAP_Write(&pdata[4], length - 4))
  315. {
  316. s_wData[s_wLen++] = ResultExecErr; ///<执行错误
  317. IAP_Stop();
  318. }else{
  319. s_wData[s_wLen++] = ResultSuccess; ///<succeed
  320. s_recvByte += length - 4;
  321. s_sequence++;
  322. }
  323. }
  324. s_wData[s_wLen++] = (s_sequence>>8)&0xFF;
  325. s_wData[s_wLen++] = s_sequence&0xFF;
  326. }
  327. /**
  328. * TransferExitHandle
  329. *
  330. * @param[in] pdata:data point
  331. * @param[in] length:data length
  332. *
  333. * @return none
  334. *
  335. * @brief 上位机通信 传输数据结束
  336. */
  337. static void TransferExitHandle(uint8_t *pdata, uint16_t length)
  338. {
  339. s_wData[s_wLen++] = DataTransferCmdHost;
  340. s_wData[s_wLen++] = DataTransferRequest;
  341. //crc = ((uint16_t)pdata[2] << 8) | pdata[3];
  342. if (0 != IAP_Stop())
  343. {
  344. s_wData[s_wLen++] = ResultExecErr; ///<执行错误
  345. }
  346. else
  347. {
  348. if (s_recvByte != s_flashMemSize)
  349. {
  350. s_wData[s_wLen++] = ResultTotalLengthErr; ///<接收数据长度不正确
  351. }
  352. else
  353. {
  354. s_wData[s_wLen++] = ResultSuccess;
  355. config->App2Size = s_flashMemSize;
  356. config->IapFlag = Startup_Update;
  357. SaveConfig();
  358. //if (0 != SaveConfig())
  359. //{
  360. // data[index] = ResultExecErr;
  361. //}
  362. iap_reboot = 1;
  363. }
  364. }
  365. }
  366. /**
  367. * IAP_CmdHandle
  368. *
  369. * @param[in] pdata:recv data point
  370. * @param[in] length:data length
  371. * @param[in] pout:send data point
  372. * @return none
  373. *
  374. * @brief 上位机通信 数据接收处理函数
  375. */
  376. uint16_t IAP_CmdHandle(uint8_t* pdata, uint16_t length, uint8_t* pout)
  377. {
  378. s_wData = pout;
  379. s_wLen = 0;
  380. if(DataTransferCmd == pdata[0]){
  381. switch (pdata[1])
  382. {
  383. case DataTransferRequest: //0x00
  384. DataTransferRequestHandle(pdata, length);
  385. break;
  386. case TransferData: //0x01
  387. TransferDataHandle(pdata, length);
  388. break;
  389. case TransferExit: //0x02
  390. TransferExitHandle(pdata, length);
  391. break;
  392. default :
  393. s_wData[0] = ResultCmdErr;
  394. s_wLen = 1;
  395. break;
  396. }
  397. }else{
  398. s_wData[0] = ResultCmdErr;
  399. s_wLen = 1;
  400. }
  401. return s_wLen;
  402. }
  403. /**
  404. * @bieaf 进行BootLoader的启动
  405. *
  406. * @param none
  407. * @return none
  408. */
  409. void Start_BootLoader(void)
  410. {
  411. //uint16_t crcCheck;
  412. uint32_t writed_len;
  413. uint32_t will_write_len;
  414. status_t ret = STATUS_SUCCESS;
  415. switch (config->IapFlag) ///< 读取是否启动应用程序 */
  416. {
  417. case Startup_Normal: ///< 正常启动 */ //在APP2中可以设定此标志位 使得下次重启之后进入APP1
  418. {
  419. //printf("> Normal start......\r\n");
  420. break;
  421. }
  422. case Startup_Update: /*启动最新的程序 */
  423. //printf("> Startup_Update start......\r\n");
  424. //crcCheck = crc16((const uint8_t *)APP2_ADDRESS, config->App2Size);
  425. if ((config->App2Size <= APP_SIZE) && App_MD5_Check(APP2_ADDRESS,config->App2Size))
  426. {
  427. writed_len =0;
  428. will_write_len = config->App2Size;
  429. do{
  430. WDG_Feed();
  431. if(will_write_len >= EFLASH_PAGE_SIZE_INIT){
  432. //memcpy(WriteDataBuff, (void *)(APP2_ADDRESS+writed_len), EFLASH_PAGE_SIZE_INIT);
  433. FLASH_DRV_Read(&g_Flash_Config,(APP2_ADDRESS+writed_len), (uint8_t*)WriteDataBuff, EFLASH_PAGE_SIZE_INIT);
  434. FLASH_DRV_UnlockCtrl();
  435. //ret = EFLASH_PageErase(APP1_ADDRESS+writed_len); ///<erase page
  436. ret = FLASH_DRV_EraseSector(&g_Flash_Config, (APP1_ADDRESS+writed_len), EFLASH_PAGE_SIZE_INIT);
  437. if (ret != STATUS_SUCCESS) break;
  438. //ret = EFLASH_PageEraseVerify(APP1_ADDRESS+writed_len); ///< verify erase state
  439. ret = FLASH_DRV_VerifySection(&g_Flash_Config,(APP1_ADDRESS+writed_len), EFLASH_PAGE_SIZE_INIT/8);
  440. if (ret != STATUS_SUCCESS) break;
  441. //ret = EFLASH_PageProgram(APP1_ADDRESS+writed_len, (uint32_t *)WriteDataBuff, 512);
  442. ret = FLASH_DRV_Program(&g_Flash_Config, (APP1_ADDRESS+writed_len), EFLASH_PAGE_SIZE_INIT, (uint8_t*)WriteDataBuff);
  443. if (ret != STATUS_SUCCESS) break;
  444. FLASH_DRV_LockCtrl();
  445. writed_len += EFLASH_PAGE_SIZE_INIT;
  446. will_write_len -= EFLASH_PAGE_SIZE_INIT;
  447. }else{
  448. //memcpy(WriteDataBuff, (void *)(APP2_ADDRESS+writed_len), will_write_len);
  449. FLASH_DRV_Read(&g_Flash_Config,(APP2_ADDRESS+writed_len), (uint8_t*)WriteDataBuff, will_write_len);
  450. FLASH_DRV_UnlockCtrl();
  451. //ret = EFLASH_PageErase(APP1_ADDRESS+writed_len); ///<erase page
  452. ret = FLASH_DRV_EraseSector(&g_Flash_Config, (APP1_ADDRESS+writed_len), EFLASH_PAGE_SIZE_INIT);
  453. if (ret != STATUS_SUCCESS) break;
  454. //ret = EFLASH_PageEraseVerify(APP1_ADDRESS+writed_len); ///< verify erase state
  455. ret = FLASH_DRV_VerifySection(&g_Flash_Config,(APP1_ADDRESS+writed_len), EFLASH_PAGE_SIZE_INIT/8);
  456. if (ret != STATUS_SUCCESS) break;
  457. //ret = EFLASH_PageProgram(APP1_ADDRESS+writed_len, (uint32_t *)WriteDataBuff, (will_write_len+3)/4);
  458. ret = FLASH_DRV_Program(&g_Flash_Config, (APP1_ADDRESS+writed_len), (((will_write_len+7)/8)*8), (uint8_t*)WriteDataBuff);
  459. if (ret != STATUS_SUCCESS) break;
  460. FLASH_DRV_LockCtrl();
  461. writed_len += will_write_len;
  462. will_write_len = 0;
  463. }
  464. }while(will_write_len > 0);
  465. if(STATUS_SUCCESS == ret){
  466. config->App1Size = config->App2Size;
  467. }
  468. }
  469. config->IapFlag = Startup_APP1;
  470. SaveConfig();
  471. case Startup_APP1: /*启动最新的程序 */
  472. //printf("> Startup_APP1 start......\r\n");
  473. //printf("> Startup_APP1 App1Size = [%d].\r\n", config->App1Size);
  474. //crcCheck = crc16((const uint8_t *)APP1_ADDRESS, config->App1Size);
  475. if((config->App1Size <= APP_SIZE) && App_MD5_Check(APP1_ADDRESS,config->App1Size))
  476. {
  477. //printf("> Startup_APP1 JumpTOApp1 ......\r\n");
  478. JumpTOApp1();
  479. }
  480. break;
  481. default: ///< 启动失败
  482. {
  483. return;
  484. }
  485. }
  486. }