main.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. #include "gd32e23x.h"
  2. #include "systick.h"
  3. #include <stdio.h>
  4. #include "main.h"
  5. #include "Fwdgt.h"
  6. #include "mb.h"
  7. #include "Led.h"
  8. #include "Key.h"
  9. #include "cfg.h"
  10. #include "main.h"
  11. #include "gd32e230x_conf.h"
  12. #include "string.h"
  13. #include "Timer.h"
  14. #include "md5.h"
  15. #define MD5_LENTH 8
  16. //#define USR_LED_RCU RCU_GPIOB
  17. //#define USR_LED_IO GPIOB
  18. //#define USR_LED GPIO_PIN_11
  19. uint8_t programe_erase_flag = 0;
  20. uint8_t programe_write_complete_flag = 0;
  21. uint8_t meta_erase_flag = 0;
  22. uint8_t meta_write_complete_flag = 0;
  23. uint8_t get_head_over_flag = 0;
  24. get_md_msg _msg = {0};
  25. static uint32_t start_addr = 0x00000000;
  26. uint32_t my_addr = 0;
  27. static uint32_t erase_size = 0;
  28. uint16_t CurrentAddr = 0;
  29. uint32_t operation_cmd_cnt = 0;
  30. uint8_t flash_flag = 0;
  31. uint8_t reboot_flag = 0;
  32. MD_DATA Md_Data[Mb_Wcmd_Width] = {0};
  33. META_DATA_S meta_data = {0};
  34. uint8_t read_meta_data[100] = {0};
  35. g_MD_Data g_md_data={
  36. .count = Mb_Wcmd_Width,
  37. .data = {0},
  38. };
  39. uint8_t md5_head[128] = {0};
  40. uint32_t md5_sum[MD5_LENTH] = {0};
  41. g_MD_Data* get_md_data()
  42. {
  43. return &g_md_data;
  44. }
  45. void flash_erase_page(uint32_t addr)
  46. {
  47. fmc_unlock();
  48. fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
  49. fmc_page_erase(addr);
  50. fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
  51. fmc_lock();
  52. }
  53. void flash_write_meta(META_DATA_S *meta_data)
  54. {
  55. fmc_unlock();
  56. uint32_t address = META_DATA;
  57. uint32_t *data = (uint32_t*)(meta_data);
  58. uint32_t data0 = 0;
  59. for(int i = 0; i < sizeof(META_DATA_S) / 4;i++)
  60. {
  61. data0 = *data;
  62. fmc_word_program(address,data0);
  63. data ++;
  64. fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
  65. address +=4;
  66. }
  67. fmc_lock();
  68. }
  69. user_code application = NULL;
  70. __IO uint32_t JumpAddress = NULL;
  71. void UserJumpToApplication(uint32_t addr)
  72. {
  73. /* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
  74. uint32_t JumpAddress = 0;
  75. if (((*(uint32_t*)addr)&0x2FFE0000)==0x20000000)
  76. {
  77. /* Jump to user application */
  78. __disable_irq();
  79. // del_md_timer();
  80. // del_modbus_uart();
  81. // delete_Timer14();
  82. // DeInitKey();
  83. SCB->VTOR = addr;
  84. //nvic_vector_table_set(NVIC_VECTTAB_FLASH,0x5400);
  85. JumpAddress = *(__IO uint32_t*) (addr + 4);
  86. application = (user_code)JumpAddress;
  87. /* Initialize user application's Stack Pointer */
  88. __set_MSP(*(__IO uint32_t*)(addr));
  89. application();
  90. }
  91. }
  92. void flash_get_meta(META_DATA_S *meta)
  93. {
  94. meta->operation_flag = *(uint32_t*)(UPGRADE_FLAG_ADDR);
  95. meta->partition = *(uint32_t*)(STARTUP_PARTATION);
  96. meta->errno = *(uint32_t*)(STARTUP_ERROR);
  97. meta->error_count = *(uint32_t*)(STARTUP_NUMBEAR);
  98. meta->rom_addr = *(uint32_t*)(STARTUP_ROM_ADDR);
  99. meta->recent_running_time = *(uint32_t*)(STARTUP_LAST_RUNNING_TIME);
  100. meta->running_app_version = *(uint32_t*)(STARTUP_APP_VERSION);
  101. meta->app1_version = *(uint32_t*)(APP1_VERSION);
  102. meta->app1_rom_addr = *(uint32_t*)(APP1_ROM_ADDR);
  103. meta->app1_partition = *(uint32_t*)(APP1_PARTATION);
  104. meta->app2_version = *(uint32_t*)(APP2_VERSION);
  105. meta->app2_rom_addr = *(uint32_t*)(APP2_ROM_ADDR);
  106. meta->app2_partition = *(uint32_t*)(APP2_PARTATION);
  107. uint32_t buff[MD5_LENTH] = {0};
  108. uint32_t addr = APP1_MD5;
  109. for(int i = 0;i < MD5_LENTH;i++)
  110. {
  111. buff[i] = *(uint32_t*)(addr);
  112. addr += 4;
  113. }
  114. memcpy(&meta->app1_md5[0],buff,sizeof(uint32_t) *MD5_LENTH);
  115. addr = APP2_MD5;
  116. for(int i = 0;i < MD5_LENTH;i++)
  117. {
  118. buff[i] = *(uint32_t*)(addr);
  119. addr += 4;
  120. }
  121. memcpy(&meta->app2_md5[0],buff,sizeof(uint32_t) *MD5_LENTH);
  122. meta->app1_size = *(uint32_t*)(APP1_SIZE);
  123. meta->app2_size = *(uint32_t*)(APP2_SIZE);
  124. }
  125. void flash_write_programe(uint32_t *addr,uint32_t* source,uint32_t lenth)
  126. {
  127. fmc_unlock();
  128. uint32_t *data = source;
  129. uint32_t *address = addr;
  130. for(int i = 0; i < ((lenth % 4) == 0 ? (lenth/4):((lenth/4)+1));i++,*address += 4)
  131. {
  132. fmc_word_program(*address,*data++);
  133. fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
  134. }
  135. *addr = *address;
  136. fmc_lock();
  137. }
  138. uint16_t cnt = 0;
  139. uint8_t md_status = 0;
  140. uint8_t upgrade_count = 0;
  141. static void break_2_boot_upgreade(void)
  142. {
  143. //__disable_irq();
  144. //__set_FAULTMASK(1);
  145. NVIC_SystemReset();
  146. }
  147. void operation_Flash_data(Flash_Data *data)
  148. {
  149. if(!data)
  150. return;
  151. if(data->index == 0)
  152. {
  153. if(md_status == UPGRADE_STATUS_IDE)
  154. {
  155. if(strncmp((const char *)(data->recive),MODBUS_HEAD,strlen(MODBUS_HEAD)) == 0){
  156. //memcpy(head_buffer,data->recive,data->lenth);
  157. int lenth = strlen(MODBUS_HEAD);
  158. memcpy(&_msg.magic,data->recive,lenth);
  159. _msg.size = (data->recive[lenth]) | (data->recive[lenth+1] << 8);
  160. _msg.patition = (data->recive[lenth+2]) | (data->recive[lenth+3] << 8) | (data->recive[lenth+4] << 16) | (data->recive[lenth+5] << 24);
  161. _msg.version = (data->recive[lenth+6]) | (data->recive[lenth+6] << 8) | (data->recive[lenth+8] << 16) | (data->recive[lenth+9] << 24);
  162. //memcmp(&md5_head,&data->recive,128);
  163. memcpy(_msg.md5,&data->recive[lenth+10],32);
  164. get_head_over_flag = 1;
  165. }
  166. }
  167. }else
  168. {
  169. if(md_status == UPGRADE_STATUS_WRITE_PROGRAME)
  170. {
  171. flash_write_programe(&my_addr,(uint32_t*)(data->recive),data->lenth);
  172. upgrade_count = 0;
  173. if(data->index < 0)
  174. {
  175. programe_write_complete_flag = 1;
  176. }
  177. }
  178. }
  179. }
  180. void ModBus_CMD(void)
  181. {
  182. if(g_md_data.data[operation_cmd_cnt].flag == 1)
  183. {
  184. uint32_t base_addr = g_md_data.data[operation_cmd_cnt].base_addr;
  185. //check data is or not header metadata;
  186. switch(base_addr)
  187. {
  188. case MD_WRITE_Addr:
  189. {
  190. operation_Flash_data(&g_md_data.data[operation_cmd_cnt].flash_Data);
  191. }
  192. break;
  193. case MD_WRITE_Reset:
  194. {
  195. break_2_boot_upgreade();
  196. }
  197. break;
  198. default:
  199. break;
  200. }
  201. g_md_data.data[operation_cmd_cnt].flag = 0;
  202. operation_cmd_cnt++;
  203. if(operation_cmd_cnt >= Mb_Wcmd_Width)
  204. {
  205. operation_cmd_cnt = 0;
  206. }
  207. }
  208. }
  209. Upgrade upgrade = {0};
  210. Upgrade *get_upgrade()
  211. {
  212. return &upgrade;
  213. }
  214. #define CHAR(b) (((b)<=9)?((b)+0x30):((b)-10+0x61));
  215. static void byte2char(char *chr, uint8_t b)
  216. {
  217. chr[0] = CHAR(b>>4);
  218. chr[1] = CHAR(b&0x0f);
  219. }
  220. uint8_t md5_check(uint32_t addr,uint32_t lenth,uint32_t* md5)
  221. {
  222. md5_ctx_t ctx;
  223. char m1[32];
  224. uint8_t i,tmp[16];
  225. md5_init(&ctx);
  226. uint32_t buff[64] = {0};
  227. uint32_t read_lenth;
  228. if(lenth % 4 == 0)
  229. read_lenth = lenth / 4;
  230. else
  231. read_lenth = lenth / 4 + 1;
  232. uint32_t base_addr = addr;
  233. int size = 0;
  234. int check_size = (64*4);
  235. do
  236. {
  237. for(int i = 0;i < 64;i++)
  238. {
  239. buff[i] = *(uint32_t*)(base_addr);
  240. base_addr += 4;
  241. }
  242. size += 64;
  243. if(size > read_lenth)
  244. {
  245. check_size = lenth;
  246. //check
  247. md5_update(&ctx,(uint8_t*)&buff,check_size);
  248. }else
  249. {
  250. //check
  251. md5_update(&ctx,(uint8_t*)&buff,check_size);
  252. lenth -= check_size;
  253. }
  254. }while(size < read_lenth);
  255. md5_final(&ctx, tmp);
  256. for (i=0; i<16; i++) {
  257. byte2char(&m1[i*2], tmp[i]);
  258. }
  259. if(memcmp(&m1, md5, sizeof(m1))) {
  260. return 0xFF;
  261. }
  262. return 0;
  263. }
  264. int main(void)
  265. {
  266. InitLED();
  267. InitKey();
  268. InitTimer();
  269. CurrentAddr = ReadKeyValue();
  270. eMBInit(MB_RTU, CurrentAddr, 0, 115200, MB_PAR_NONE);
  271. eMBEnable();
  272. flash_get_meta(&meta_data);
  273. //Fwdgt_Init();
  274. //read data and
  275. uint8_t app1_checum = 0xFF;
  276. uint8_t app2_checum = 0xFF;
  277. if(meta_data.operation_flag == 0x0)
  278. {
  279. #if (!USE_ONE_APP)
  280. if(meta_data.rom_addr == PROGRAME_APP1 || meta_data.rom_addr == PROGRAME_APP2)
  281. {
  282. if(meta_data.app1_rom_addr == PROGRAME_APP1)
  283. {
  284. app1_checum = md5_check(meta_data.app1_rom_addr,meta_data.app1_size,meta_data.app1_md5);
  285. }
  286. if(meta_data.app2_rom_addr == PROGRAME_APP2)
  287. {
  288. app2_checum = md5_check(meta_data.app2_rom_addr,meta_data.app2_size,meta_data.app2_md5);
  289. }
  290. if((app1_checum == 0) && (app2_checum == 0))
  291. {
  292. if(meta_data.errno != NOERROR && meta_data.error_count >= MAX_ERROR_COUNT)
  293. {
  294. //check current version is last versions?
  295. if(meta_data.app1_version == meta_data.app2_version)
  296. {
  297. }else
  298. {
  299. uint32_t version_max = meta_data.app1_version > meta_data.app2_version ? meta_data.app1_version :meta_data.app2_version;
  300. uint32_t version_min = meta_data.app1_version < meta_data.app2_version ? meta_data.app1_version :meta_data.app2_version;
  301. if(version_max == ERROR_VERSION)
  302. {
  303. }else if(meta_data.running_app_version == version_max)
  304. {
  305. //swtich lower version to running
  306. flash_erase_page(META_DATA);
  307. if(version_max == meta_data.app2_version){
  308. meta_data.partition = meta_data.app1_partition;
  309. meta_data.rom_addr = meta_data.app1_rom_addr;
  310. }else
  311. {
  312. meta_data.partition = meta_data.app2_partition;
  313. meta_data.rom_addr = meta_data.app2_rom_addr;
  314. }
  315. meta_data.running_app_version = version_min;
  316. meta_data.errno = 0;
  317. meta_data.error_count = 0;
  318. flash_write_meta(&meta_data);
  319. UserJumpToApplication(meta_data.rom_addr);
  320. }else
  321. {
  322. ;;
  323. }
  324. }
  325. }else
  326. {
  327. if(meta_data.rom_addr == PROGRAME_APP1)
  328. {
  329. if(app1_checum == 0){
  330. UserJumpToApplication(meta_data.rom_addr);
  331. if(app2_checum == 0)
  332. {
  333. flash_erase_page(META_DATA);
  334. meta_data.partition = meta_data.app2_partition;
  335. meta_data.rom_addr = meta_data.app2_rom_addr;
  336. meta_data.running_app_version = meta_data.app2_version;
  337. meta_data.errno = 0;
  338. meta_data.error_count = 0;
  339. flash_write_meta(&meta_data);
  340. UserJumpToApplication(meta_data.rom_addr);
  341. }
  342. }
  343. }
  344. if(meta_data.rom_addr == PROGRAME_APP2)
  345. {
  346. if(app2_checum == 0){
  347. UserJumpToApplication(meta_data.rom_addr);
  348. if(app1_checum == 0)
  349. {
  350. flash_erase_page(META_DATA);
  351. meta_data.partition = meta_data.app1_partition;
  352. meta_data.rom_addr = meta_data.app1_rom_addr;
  353. meta_data.running_app_version = meta_data.app1_version;
  354. meta_data.errno = 0;
  355. meta_data.error_count = 0;
  356. flash_write_meta(&meta_data);
  357. UserJumpToApplication(meta_data.rom_addr);
  358. }
  359. }
  360. }
  361. }
  362. }else if(app1_checum == 0)
  363. {
  364. if(meta_data.errno != NOERROR && meta_data.error_count >= MAX_ERROR_COUNT)
  365. {
  366. //upgrade
  367. }else
  368. {
  369. flash_erase_page(META_DATA);
  370. meta_data.partition = meta_data.app1_partition;
  371. meta_data.rom_addr = meta_data.app1_rom_addr;
  372. meta_data.running_app_version = meta_data.app1_version;
  373. meta_data.errno = 0;
  374. meta_data.error_count = 0;
  375. flash_write_meta(&meta_data);
  376. UserJumpToApplication(meta_data.rom_addr);
  377. }
  378. }else if(app2_checum == 0)
  379. {
  380. if(meta_data.errno != NOERROR && meta_data.error_count >= MAX_ERROR_COUNT)
  381. {
  382. //upgrade
  383. }else
  384. {
  385. flash_erase_page(META_DATA);
  386. meta_data.partition = meta_data.app2_partition;
  387. meta_data.rom_addr = meta_data.app2_rom_addr;
  388. meta_data.running_app_version = meta_data.app2_version;
  389. meta_data.errno = 0;
  390. meta_data.error_count = 0;
  391. flash_write_meta(&meta_data);
  392. UserJumpToApplication(meta_data.rom_addr);
  393. }
  394. }else
  395. {
  396. ;;
  397. }
  398. }
  399. #else
  400. if(meta_data.rom_addr == PROGRAME_APP1)
  401. {
  402. if(meta_data.app1_rom_addr == PROGRAME_APP1)
  403. {
  404. app1_checum = md5_check(meta_data.app1_rom_addr,meta_data.app1_size,meta_data.app1_md5);
  405. if(app1_checum == 0)
  406. {
  407. if(meta_data.errno != NOERROR && meta_data.error_count >= MAX_ERROR_COUNT)
  408. {
  409. //upgrade
  410. }else
  411. {
  412. UserJumpToApplication(meta_data.rom_addr);
  413. }
  414. }
  415. }
  416. }
  417. #endif
  418. }else
  419. {
  420. //wait to upgrade
  421. }
  422. md_status = UPGRADE_STATUS_IDE;
  423. while(1)
  424. {
  425. eMBPoll();
  426. //Fwdgt_reload();
  427. if(flash_flag)
  428. {
  429. LEDFlicker2();
  430. upgrade_count += 3;
  431. flash_flag = 0;
  432. }
  433. ModBus_CMD();
  434. switch(md_status)
  435. {
  436. case UPGRADE_STATUS_IDE:
  437. {
  438. //get and jie xi meta_data
  439. if(get_head_over_flag)
  440. {
  441. //½âÎöMetaDataºÍ²Á³ýflash
  442. if(_msg.patition == ONE){
  443. start_addr =PROGRAME_APP1;
  444. erase_size = PROGRAME_APP1_SIZE;
  445. md_status = UPGRADE_STATUS_ERASE_PROGRAME;
  446. }
  447. #if (!USE_ONE_APP)
  448. else if(_msg.patition == SECOND){
  449. start_addr = PROGRAME_APP2;
  450. erase_size = PROGRAME_APP2_SIZE;
  451. md_status = UPGRADE_STATUS_ERASE_PROGRAME;
  452. }
  453. #endif
  454. else{
  455. md_status = UPGRADE_STATUS_IDE;
  456. get_head_over_flag = 0;
  457. }
  458. }
  459. }
  460. break;
  461. case UPGRADE_STATUS_ERASE_PROGRAME:
  462. {
  463. if(programe_erase_flag == 0)
  464. {
  465. my_addr = start_addr;
  466. for(uint32_t i = 0;i < (erase_size/PAGE_SIZE);i++)
  467. {
  468. flash_erase_page(my_addr);
  469. my_addr += PAGE_SIZE;
  470. }
  471. my_addr = start_addr;
  472. programe_erase_flag = 1;
  473. md_status = UPGRADE_STATUS_WRITE_PROGRAME;
  474. upgrade_count = 0;
  475. }
  476. }
  477. break;
  478. case UPGRADE_STATUS_WRITE_PROGRAME:
  479. {
  480. if(upgrade_count > 10)
  481. {
  482. break_2_boot_upgreade();
  483. }
  484. if(programe_write_complete_flag)
  485. {
  486. md_status = UPGRADE_STATUS_ERASE_META;
  487. }
  488. }
  489. break;
  490. case UPGRADE_STATUS_ERASE_META:
  491. {
  492. if(meta_erase_flag == 0)
  493. {
  494. meta_data.partition = _msg.patition;
  495. meta_data.running_app_version = _msg.version;
  496. meta_data.errno = 0;
  497. meta_data.error_count = 0;
  498. if(meta_data.partition == ONE){
  499. meta_data.rom_addr =PROGRAME_APP1;
  500. meta_data.app1_partition = _msg.patition;
  501. meta_data.app1_rom_addr = PROGRAME_APP1;
  502. meta_data.app1_version = _msg.version;
  503. memcpy(meta_data.app1_md5,_msg.md5,32);
  504. meta_data.app1_size = _msg.size;
  505. }
  506. #if (!USE_ONE_APP)
  507. else if(meta_data.partition == SECOND)
  508. {
  509. meta_data.rom_addr =PROGRAME_APP2;
  510. meta_data.app2_partition = _msg.patition;
  511. meta_data.app2_rom_addr = PROGRAME_APP2;
  512. meta_data.app2_version = _msg.version;
  513. memcpy(meta_data.app2_md5,_msg.md5,32);
  514. meta_data.app2_size = _msg.size;
  515. }
  516. #endif
  517. else
  518. {
  519. // errno
  520. md_status = UPGRADE_STATUS_IDE;
  521. get_head_over_flag = 0;
  522. programe_write_complete_flag = 0;
  523. programe_erase_flag = 0;
  524. break;
  525. }
  526. meta_data.operation_flag = 0;
  527. meta_data.recent_running_time = 0;
  528. md_status = UPGRADE_STATUS_WTITE_META;
  529. flash_erase_page(META_DATA);
  530. meta_erase_flag = 1;
  531. }
  532. }
  533. break;
  534. case UPGRADE_STATUS_WTITE_META:
  535. {
  536. if(meta_write_complete_flag == 0){
  537. flash_write_meta(&meta_data);
  538. md_status = UPGRADE_STATUS_FINISH;
  539. meta_write_complete_flag = 1;
  540. }
  541. }
  542. break;
  543. case UPGRADE_STATUS_FINISH:
  544. {
  545. UserJumpToApplication(start_addr);
  546. md_status = UPGRADE_STATUS_IDE;
  547. meta_write_complete_flag = 0; //
  548. meta_erase_flag = 0;
  549. get_head_over_flag = 0;
  550. programe_erase_flag = 0;
  551. programe_write_complete_flag = 0;
  552. }
  553. break;
  554. default:
  555. break;
  556. }
  557. }
  558. return 0;
  559. }