IAP.c 15 KB

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