IAP.c 16 KB

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