wm_fwup.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. /*****************************************************************************
  2. *
  3. * File Name : wm_fwup.c
  4. *
  5. * Description: firmware update Module
  6. *
  7. * Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd.
  8. * All rights reserved.
  9. *
  10. * Author : dave
  11. *
  12. * Date : 2014-6-16
  13. *****************************************************************************/
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include "wm_mem.h"
  18. #include "list.h"
  19. #include "wm_debug.h"
  20. #include "wm_internal_flash.h"
  21. #include "wm_crypto_hard.h"
  22. #include "utils.h"
  23. #include "wm_fwup.h"
  24. #include "wm_watchdog.h"
  25. #include "wm_wifi.h"
  26. #include "wm_flash_map.h"
  27. #include "wm_wl_task.h"
  28. #include "wm_params.h"
  29. #include "wm_param.h"
  30. #include "wm_ram_config.h"
  31. #define FWUP_MSG_QUEUE_SIZE (4)
  32. #define FWUP_TASK_STK_SIZE (256)
  33. #define FWUP_MSG_START_ENGINEER (1)
  34. static struct tls_fwup *fwup = NULL;
  35. static tls_os_queue_t *fwup_msg_queue = NULL;
  36. static u32 *fwup_task_stk = NULL;
  37. static u8 oneshotback = 0;
  38. extern int tls_fls_fast_write_init(void);
  39. extern int tls_fls_fast_write(u32 addr, u8 *buf, u32 length);
  40. extern void tls_fls_fast_write_destroy(void);
  41. static void fwup_update_autoflag(void)
  42. {
  43. u8 auto_reconnect = 0xff;
  44. tls_wifi_auto_connect_flag(WIFI_AUTO_CNT_FLAG_GET, &auto_reconnect);
  45. if(auto_reconnect == WIFI_AUTO_CNT_TMP_OFF)
  46. {
  47. auto_reconnect = WIFI_AUTO_CNT_ON;
  48. tls_wifi_auto_connect_flag(WIFI_AUTO_CNT_FLAG_SET, &auto_reconnect);
  49. }
  50. return;
  51. }
  52. int tls_fwup_img_header_check(IMAGE_HEADER_PARAM_ST *img_param)
  53. {
  54. psCrcContext_t crcContext;
  55. unsigned int crcvalue = 0;
  56. unsigned int crccallen = 0;
  57. int i = 0;
  58. IMAGE_HEADER_PARAM_ST run_param;
  59. if (img_param->magic_no != SIGNATURE_WORD)
  60. {
  61. return FALSE;
  62. }
  63. /*temperary forbid to update secboot*/
  64. if (img_param->img_attr.b.img_type != IMG_TYPE_FLASHBIN0)
  65. {
  66. return FALSE;
  67. }
  68. /*check run image and upgrade image have the same image info*/
  69. tls_fls_read(img_param->img_header_addr, (u8 *)&run_param, sizeof(run_param));
  70. if ((run_param.img_attr.b.signature && (img_param->img_attr.b.signature == 0))
  71. || ((run_param.img_attr.b.signature == 0) && img_param->img_attr.b.signature))
  72. {
  73. return FALSE;
  74. }
  75. if ((run_param.img_attr.b.code_encrypt && (img_param->img_attr.b.code_encrypt == 0))
  76. || ((run_param.img_attr.b.code_encrypt == 0) && img_param->img_attr.b.code_encrypt))
  77. {
  78. return FALSE;
  79. }
  80. if (img_param->img_addr % IMAGE_START_ADDR_MSK) //vbr register must be 1024 align.
  81. {
  82. return FALSE;
  83. }
  84. if ((img_param->img_addr|FLASH_BASE_ADDR) >= USER_ADDR_START)
  85. {
  86. return FALSE;
  87. }
  88. if ((img_param->img_addr|FLASH_BASE_ADDR) + img_param->img_len >= USER_ADDR_START)
  89. {
  90. return FALSE;
  91. }
  92. if(((img_param->upgrade_img_addr|FLASH_BASE_ADDR) < CODE_UPD_START_ADDR)
  93. || ((img_param->upgrade_img_addr|FLASH_BASE_ADDR) + img_param->img_len >= CODE_RUN_START_ADDR))
  94. {
  95. return FALSE;
  96. }
  97. crccallen = (sizeof(IMAGE_HEADER_PARAM_ST)-4);
  98. tls_crypto_crc_init(&crcContext, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, 3);
  99. for (i = 0; i < crccallen/4; i++)
  100. {
  101. MEMCPY((unsigned char *)&crcvalue, (unsigned char *)img_param +i*4, 4);
  102. tls_crypto_crc_update(&crcContext, (unsigned char *)&crcvalue, 4);
  103. }
  104. crcvalue = 0;
  105. tls_crypto_crc_final(&crcContext, &crcvalue);
  106. if (img_param->hd_checksum == crcvalue)
  107. {
  108. return TRUE;
  109. }
  110. else
  111. {
  112. return FALSE;
  113. }
  114. }
  115. static void fwup_scheduler(void *data)
  116. {
  117. u8 *buffer = NULL;
  118. int err;
  119. u32 msg;
  120. u32 len;
  121. u32 image_checksum = 0;
  122. //u32 org_checksum = 0;
  123. struct tls_fwup_request *request;
  124. struct tls_fwup_request *temp;
  125. IMAGE_HEADER_PARAM_ST booter;
  126. while (1)
  127. {
  128. err = tls_os_queue_receive(fwup_msg_queue, (void **)&msg, 0, 0);
  129. tls_watchdog_clr();
  130. if(err != TLS_OS_SUCCESS)
  131. {
  132. continue;
  133. }
  134. switch(msg)
  135. {
  136. case FWUP_MSG_START_ENGINEER:
  137. if(dl_list_empty(&fwup->wait_list) == 0)
  138. {
  139. fwup->current_state |= TLS_FWUP_STATE_BUSY;
  140. }
  141. dl_list_for_each_safe(request, temp, &fwup->wait_list, struct tls_fwup_request, list)
  142. {
  143. request->status = TLS_FWUP_REQ_STATUS_BUSY;
  144. if(fwup->current_state & TLS_FWUP_STATE_ERROR)
  145. {
  146. TLS_DBGPRT_WARNING("some error happened during firmware update, so discard all the request in the waiting queue!\n");
  147. if(fwup->current_state & TLS_FWUP_STATE_ERROR_IO)
  148. {
  149. request->status = TLS_FWUP_REQ_STATUS_FIO;
  150. }
  151. else if(fwup->current_state & TLS_FWUP_STATE_ERROR_SIGNATURE)
  152. {
  153. request->status = TLS_FWUP_REQ_STATUS_FSIGNATURE;
  154. }
  155. else if(fwup->current_state & TLS_FWUP_STATE_ERROR_MEM)
  156. {
  157. request->status = TLS_FWUP_REQ_STATUS_FMEM;
  158. }
  159. else if(fwup->current_state & TLS_FWUP_STATE_ERROR_CRC)
  160. {
  161. request->status = TLS_FWUP_REQ_STATUS_FCRC;
  162. }
  163. goto request_finish;
  164. }
  165. else if(fwup->current_state & TLS_FWUP_STATE_COMPLETE)
  166. {
  167. TLS_DBGPRT_WARNING("the firmware updating conpletes, so discard the request in the waiting queue!\n");
  168. request->status = TLS_FWUP_REQ_STATUS_FCOMPLETE;
  169. goto request_finish;
  170. }
  171. if(fwup->current_image_src <= TLS_FWUP_IMAGE_SRC_WEB)
  172. {
  173. buffer = request->data;
  174. if(fwup->received_len < sizeof(IMAGE_HEADER_PARAM_ST))
  175. {
  176. len = sizeof(IMAGE_HEADER_PARAM_ST) - fwup->received_len;
  177. if(request->data_len < len)
  178. {
  179. len = request->data_len;
  180. }
  181. MEMCPY((u8 *)&booter + fwup->received_len, buffer, len);
  182. request->data_len -= len;
  183. buffer += len;
  184. fwup->received_len += len;
  185. if(fwup->received_len == sizeof(IMAGE_HEADER_PARAM_ST))
  186. {
  187. if (!tls_fwup_img_header_check(&booter))
  188. {
  189. request->status = TLS_FWUP_REQ_STATUS_FIO;
  190. fwup->current_state |= TLS_FWUP_STATE_ERROR_IO;
  191. goto request_finish;
  192. }
  193. fwup->program_base = booter.upgrade_img_addr | FLASH_BASE_ADDR;
  194. fwup->program_offset = 0;
  195. fwup->total_len = booter.img_len + sizeof(IMAGE_HEADER_PARAM_ST);
  196. if (booter.img_attr.b.signature)
  197. {
  198. fwup->total_len += 128;
  199. }
  200. /*write booter header to flash*/
  201. err = tls_fls_fast_write(fwup->program_base + fwup->program_offset, (u8 *)&booter, sizeof(IMAGE_HEADER_PARAM_ST));
  202. if(err != TLS_FLS_STATUS_OK)
  203. {
  204. TLS_DBGPRT_ERR("failed to program flash!\n");
  205. request->status = TLS_FWUP_REQ_STATUS_FIO;
  206. fwup->current_state |= TLS_FWUP_STATE_ERROR_IO;
  207. goto request_finish;
  208. }
  209. /*initialize updated_len*/
  210. fwup->updated_len = sizeof(IMAGE_HEADER_PARAM_ST);
  211. fwup->program_offset = sizeof(IMAGE_HEADER_PARAM_ST);
  212. }
  213. }
  214. fwup->received_len += request->data_len;
  215. }
  216. if (request->data_len > 0)
  217. {
  218. // TLS_DBGPRT_INFO("write the firmware image to the flash. %x\n\r", fwup->program_base + fwup->program_offset);
  219. err = tls_fls_fast_write(fwup->program_base + fwup->program_offset, buffer, request->data_len);
  220. if(err != TLS_FLS_STATUS_OK)
  221. {
  222. TLS_DBGPRT_ERR("failed to program flash!\n");
  223. request->status = TLS_FWUP_REQ_STATUS_FIO;
  224. fwup->current_state |= TLS_FWUP_STATE_ERROR_IO;
  225. goto request_finish;
  226. }
  227. fwup->program_offset += request->data_len;
  228. fwup->updated_len += request->data_len;
  229. //TLS_DBGPRT_INFO("updated: %d bytes\n" , fwup->updated_len);
  230. if(fwup->updated_len >= (fwup->total_len))
  231. {
  232. u8 *buffer_t;
  233. u32 len, left, offset;
  234. psCrcContext_t crcContext;
  235. tls_fls_fast_write_destroy();
  236. buffer_t = tls_mem_alloc(1024);
  237. if (buffer_t == NULL)
  238. {
  239. TLS_DBGPRT_ERR("unable to verify because of no memory\n");
  240. request->status = TLS_FWUP_REQ_STATUS_FMEM;
  241. fwup->current_state |= TLS_FWUP_STATE_ERROR_MEM;
  242. goto request_finish;
  243. }
  244. else
  245. {
  246. offset = sizeof(IMAGE_HEADER_PARAM_ST);
  247. if (booter.img_attr.b.signature)
  248. {
  249. left = fwup->total_len - 128 - sizeof(IMAGE_HEADER_PARAM_ST);
  250. }
  251. else
  252. {
  253. left = fwup->total_len - sizeof(IMAGE_HEADER_PARAM_ST);
  254. }
  255. tls_crypto_crc_init(&crcContext, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, 3);
  256. while (left > 0)
  257. {
  258. len = left > 1024 ? 1024 : left;
  259. err = tls_fls_read(fwup->program_base + offset, buffer_t, len);
  260. if (err != TLS_FLS_STATUS_OK)
  261. {
  262. request->status = TLS_FWUP_REQ_STATUS_FIO;
  263. fwup->current_state |= TLS_FWUP_STATE_ERROR_IO;
  264. goto request_finish;
  265. }
  266. tls_crypto_crc_update(&crcContext, buffer_t, len);
  267. offset += len;
  268. left -= len;
  269. }
  270. tls_crypto_crc_final(&crcContext, &image_checksum);
  271. tls_mem_free(buffer_t);
  272. }
  273. if (booter.org_checksum != image_checksum)
  274. {
  275. TLS_DBGPRT_ERR("verify incorrect[0x%02x, but 0x%02x]\n", booter.org_checksum, image_checksum);
  276. request->status = TLS_FWUP_REQ_STATUS_FCRC;
  277. fwup->current_state |= TLS_FWUP_STATE_ERROR_CRC;
  278. goto request_finish;
  279. }
  280. else
  281. {
  282. /*Write OTA flag to flash used by boot loader*/
  283. tls_fls_write(TLS_FLASH_OTA_FLAG_ADDR, (u8 *)&booter.org_checksum, sizeof(booter.org_checksum));
  284. }
  285. TLS_DBGPRT_INFO("update the firmware successfully!\n");
  286. fwup->current_state |= TLS_FWUP_STATE_COMPLETE;
  287. if (oneshotback != 0){
  288. tls_wifi_set_oneshot_flag(oneshotback); // 恢复一键配置
  289. }
  290. }
  291. }
  292. request->status = TLS_FWUP_REQ_STATUS_SUCCESS;
  293. request_finish:
  294. tls_os_sem_acquire(fwup->list_lock, 0);
  295. dl_list_del(&request->list);
  296. tls_os_sem_release(fwup->list_lock);
  297. if(dl_list_empty(&fwup->wait_list) == 1)
  298. {
  299. fwup->current_state &= ~TLS_FWUP_STATE_BUSY;
  300. }
  301. /*when all data has received or error happened, reset system*/
  302. if(((fwup->updated_len >= sizeof(IMAGE_HEADER_PARAM_ST)) && (fwup->updated_len >= (fwup->total_len)))
  303. || (request->status != TLS_FWUP_REQ_STATUS_SUCCESS))
  304. {
  305. fwup_update_autoflag();
  306. tls_sys_set_reboot_reason(REBOOT_REASON_ACTIVE);
  307. tls_sys_reset();
  308. }
  309. if(request->complete)
  310. {
  311. request->complete(request, request->arg);
  312. }
  313. }
  314. break;
  315. default:
  316. break;
  317. }
  318. }
  319. }
  320. void fwup_request_complete(struct tls_fwup_request *request, void *arg)
  321. {
  322. tls_os_sem_t *sem;
  323. if((request == NULL) || (arg == NULL))
  324. {
  325. return;
  326. }
  327. sem = (tls_os_sem_t *)arg;
  328. tls_os_sem_release(sem);
  329. }
  330. u32 tls_fwup_enter(enum tls_fwup_image_src image_src)
  331. {
  332. u32 session_id = 0;
  333. u32 cpu_sr;
  334. bool enable = FALSE;
  335. tls_fwup_init();
  336. if (fwup == NULL)
  337. {
  338. TLS_DBGPRT_INFO("fwup is null!\n");
  339. return 0;
  340. }
  341. if (fwup->busy == TRUE)
  342. {
  343. TLS_DBGPRT_INFO("fwup is busy!\n");
  344. return 0;
  345. }
  346. cpu_sr = tls_os_set_critical();
  347. do
  348. {
  349. session_id = rand();
  350. }while(session_id == 0);
  351. fwup->current_state = 0;
  352. fwup->current_image_src = image_src;
  353. fwup->received_len = 0;
  354. fwup->total_len = 0;
  355. fwup->updated_len = 0;
  356. fwup->program_base = 0;
  357. fwup->program_offset = 0;
  358. fwup->received_number = -1;
  359. fwup->current_session_id = session_id;
  360. fwup->busy = TRUE;
  361. oneshotback = tls_wifi_get_oneshot_flag();
  362. if (oneshotback != 0){
  363. tls_wifi_set_oneshot_flag(0); // 退出一键配置
  364. }
  365. tls_param_get(TLS_PARAM_ID_PSM, &enable, TRUE);
  366. if (TRUE == enable)
  367. {
  368. tls_wifi_set_psflag(FALSE, 0);
  369. }
  370. tls_fls_fast_write_init();
  371. tls_os_release_critical(cpu_sr);
  372. return session_id;
  373. }
  374. int tls_fwup_exit(u32 session_id)
  375. {
  376. u32 cpu_sr;
  377. bool enable = FALSE;
  378. //tls_os_task_t fwtask;
  379. //tls_os_status_t osstatus = 0;
  380. if ((fwup == NULL) || (fwup->busy == FALSE))
  381. {
  382. return TLS_FWUP_STATUS_EPERM;
  383. }
  384. if (session_id != fwup->current_session_id)
  385. {
  386. return TLS_FWUP_STATUS_ESESSIONID;
  387. }
  388. if (fwup->current_state & TLS_FWUP_STATE_BUSY)
  389. {
  390. return TLS_FWUP_STATUS_EBUSY;
  391. }
  392. cpu_sr = tls_os_set_critical();
  393. fwup->current_state = 0;
  394. fwup->received_len = 0;
  395. fwup->total_len = 0;
  396. fwup->updated_len = 0;
  397. fwup->program_base = 0;
  398. fwup->program_offset = 0;
  399. fwup->received_number = -1;
  400. fwup->current_session_id = 0;
  401. fwup->busy = FALSE;
  402. if (oneshotback != 0){
  403. tls_wifi_set_oneshot_flag(oneshotback); // 恢复一键配置
  404. }
  405. tls_param_get(TLS_PARAM_ID_PSM, &enable, TRUE);
  406. tls_wifi_set_psflag(enable, 0);
  407. tls_os_release_critical(cpu_sr);
  408. return TLS_FWUP_STATUS_OK;
  409. }
  410. int tls_fwup_get_current_session_id(void)
  411. {
  412. if (fwup){
  413. return fwup->current_session_id;
  414. }
  415. return 0;
  416. }
  417. int tls_fwup_set_update_numer(int number)
  418. {
  419. if(1 == number - fwup->received_number)
  420. {
  421. fwup->received_number = number;
  422. return TLS_FWUP_STATUS_OK;
  423. }
  424. return TLS_FWUP_STATE_UNDEF;
  425. }
  426. int tls_fwup_get_current_update_numer(void)
  427. {
  428. return fwup->received_number;
  429. }
  430. int tls_fwup_get_status(void)
  431. {
  432. return fwup->busy;
  433. }
  434. int tls_fwup_set_crc_error(u32 session_id)
  435. {
  436. if(fwup == NULL)
  437. {
  438. return TLS_FWUP_STATUS_EPERM;
  439. }
  440. if(session_id != fwup->current_session_id)
  441. {
  442. return TLS_FWUP_STATUS_ESESSIONID;
  443. }
  444. fwup->current_state |= TLS_FWUP_STATE_ERROR_CRC;
  445. return TLS_FWUP_STATUS_OK;
  446. }
  447. static int tls_fwup_request_async(u32 session_id, struct tls_fwup_request *request)
  448. {
  449. u8 need_sched;
  450. if(fwup == NULL)
  451. {
  452. return TLS_FWUP_STATUS_EPERM;
  453. }
  454. if(session_id != fwup->current_session_id)
  455. {
  456. return TLS_FWUP_STATUS_ESESSIONID;
  457. }
  458. if((request == NULL) || (request->data == NULL) || (request->data_len == 0))
  459. {
  460. return TLS_FWUP_STATUS_EINVALID;
  461. }
  462. tls_os_sem_acquire(fwup->list_lock, 0);
  463. if(dl_list_empty(&fwup->wait_list))
  464. {
  465. need_sched = 1;
  466. }
  467. else
  468. {
  469. need_sched = 0;
  470. }
  471. request->status = TLS_FWUP_REQ_STATUS_IDLE;
  472. dl_list_add_tail(&fwup->wait_list, &request->list);
  473. tls_os_sem_release(fwup->list_lock);
  474. if(need_sched == 1)
  475. {
  476. tls_os_queue_send(fwup_msg_queue, (void *)FWUP_MSG_START_ENGINEER, 0);
  477. }
  478. return TLS_FWUP_STATUS_OK;
  479. }
  480. int tls_fwup_request_sync(u32 session_id, u8 *data, u32 data_len)
  481. {
  482. int err;
  483. tls_os_sem_t *sem;
  484. struct tls_fwup_request request;
  485. if(fwup == NULL)
  486. {
  487. return TLS_FWUP_STATUS_EPERM;
  488. }
  489. if(session_id != fwup->current_session_id)
  490. {
  491. return TLS_FWUP_STATUS_ESESSIONID;
  492. }
  493. if((data == NULL) || (data_len == 0))
  494. {
  495. return TLS_FWUP_STATUS_EINVALID;
  496. }
  497. err = tls_os_sem_create(&sem, 0);
  498. if(err != TLS_OS_SUCCESS)
  499. {
  500. return TLS_FWUP_STATUS_EMEM;
  501. }
  502. request.data = data;
  503. request.data_len = data_len;
  504. request.complete = fwup_request_complete;
  505. request.arg = (void *)sem;
  506. err = tls_fwup_request_async(session_id, &request);
  507. if(err == TLS_FWUP_STATUS_OK)
  508. {
  509. tls_os_sem_acquire(sem, 0);
  510. }
  511. tls_os_sem_delete(sem);
  512. switch(request.status)
  513. {
  514. case TLS_FWUP_REQ_STATUS_SUCCESS:
  515. err = TLS_FWUP_STATUS_OK;
  516. break;
  517. case TLS_FWUP_REQ_STATUS_FIO:
  518. err = TLS_FWUP_STATUS_EIO;
  519. break;
  520. case TLS_FWUP_REQ_STATUS_FSIGNATURE:
  521. err = TLS_FWUP_STATUS_ESIGNATURE;
  522. break;
  523. case TLS_FWUP_REQ_STATUS_FMEM:
  524. err = TLS_FWUP_STATUS_EMEM;
  525. break;
  526. case TLS_FWUP_REQ_STATUS_FCRC:
  527. err = TLS_FWUP_STATUS_ECRC;
  528. break;
  529. case TLS_FWUP_REQ_STATUS_FCOMPLETE:
  530. err = TLS_FWUP_STATUS_EIO;
  531. break;
  532. default:
  533. err = TLS_FWUP_STATUS_EUNDEF;
  534. break;
  535. }
  536. return err;
  537. }
  538. u16 tls_fwup_current_state(u32 session_id)
  539. {
  540. if(fwup == NULL)
  541. {
  542. return TLS_FWUP_STATE_UNDEF;
  543. }
  544. if(session_id != fwup->current_session_id)
  545. {
  546. return TLS_FWUP_STATE_UNDEF;
  547. }
  548. return fwup->current_state;
  549. }
  550. int tls_fwup_reset(u32 session_id)
  551. {
  552. u32 cpu_sr;
  553. if ((fwup == NULL) || (fwup->busy == FALSE)) {return TLS_FWUP_STATUS_EPERM;}
  554. if (session_id != fwup->current_session_id) {return TLS_FWUP_STATUS_ESESSIONID;}
  555. if (fwup->current_state & TLS_FWUP_STATE_BUSY) {return TLS_FWUP_STATUS_EBUSY;}
  556. cpu_sr = tls_os_set_critical();
  557. fwup->current_state = 0;
  558. fwup->received_len = 0;
  559. fwup->total_len = 0;
  560. fwup->updated_len = 0;
  561. fwup->program_base = 0;
  562. fwup->program_offset = 0;
  563. tls_os_release_critical(cpu_sr);
  564. return TLS_FWUP_STATUS_OK;
  565. }
  566. int tls_fwup_clear_error(u32 session_id)
  567. {
  568. u32 cpu_sr;
  569. if ((fwup == NULL) || (fwup->busy == FALSE)) {return TLS_FWUP_STATUS_EPERM;}
  570. if (session_id != fwup->current_session_id) {return TLS_FWUP_STATUS_ESESSIONID;}
  571. if (fwup->current_state & TLS_FWUP_STATE_BUSY) {return TLS_FWUP_STATUS_EBUSY;}
  572. cpu_sr = tls_os_set_critical();
  573. fwup->current_state &= ~TLS_FWUP_STATE_ERROR;
  574. tls_os_release_critical(cpu_sr);
  575. return TLS_FWUP_STATUS_OK;
  576. }
  577. int tls_fwup_init(void)
  578. {
  579. int err;
  580. if(fwup != NULL)
  581. {
  582. TLS_DBGPRT_ERR("firmware update module has been installed!\n");
  583. return TLS_FWUP_STATUS_EBUSY;
  584. }
  585. fwup = tls_mem_alloc(sizeof(*fwup));
  586. if(fwup == NULL)
  587. {
  588. TLS_DBGPRT_ERR("allocate @fwup fail!\n");
  589. return TLS_FWUP_STATUS_EMEM;
  590. }
  591. memset(fwup, 0, sizeof(*fwup));
  592. err = tls_os_sem_create(&fwup->list_lock, 1);
  593. if(err != TLS_OS_SUCCESS)
  594. {
  595. TLS_DBGPRT_ERR("create semaphore @fwup->list_lock fail!\n");
  596. tls_mem_free(fwup);
  597. return TLS_FWUP_STATUS_EMEM;
  598. }
  599. dl_list_init(&fwup->wait_list);
  600. fwup->busy = FALSE;
  601. err = tls_os_queue_create(&fwup_msg_queue, FWUP_MSG_QUEUE_SIZE);
  602. if (err != TLS_OS_SUCCESS)
  603. {
  604. TLS_DBGPRT_ERR("create message queue @fwup_msg_queue fail!\n");
  605. tls_os_sem_delete(fwup->list_lock);
  606. tls_mem_free(fwup);
  607. return TLS_FWUP_STATUS_EMEM;
  608. }
  609. fwup_task_stk = (u32 *)tls_mem_alloc(FWUP_TASK_STK_SIZE * sizeof(u32));
  610. if (fwup_task_stk)
  611. {
  612. err = tls_os_task_create(NULL, "fwup",
  613. fwup_scheduler,
  614. (void *)fwup,
  615. (void *)fwup_task_stk,
  616. FWUP_TASK_STK_SIZE * sizeof(u32),
  617. TLS_FWUP_TASK_PRIO,
  618. 0);
  619. if (err != TLS_OS_SUCCESS)
  620. {
  621. TLS_DBGPRT_ERR("create firmware update process task fail!\n");
  622. tls_os_queue_delete(fwup_msg_queue);
  623. fwup_msg_queue = NULL;
  624. tls_os_sem_delete(fwup->list_lock);
  625. fwup->list_lock = NULL;
  626. tls_mem_free(fwup);
  627. fwup = NULL;
  628. tls_mem_free(fwup_task_stk);
  629. fwup_task_stk = NULL;
  630. return TLS_FWUP_STATUS_EMEM;
  631. }
  632. }
  633. else
  634. {
  635. tls_os_queue_delete(fwup_msg_queue);
  636. fwup_msg_queue = NULL;
  637. tls_os_sem_delete(fwup->list_lock);
  638. fwup->list_lock = NULL;
  639. tls_mem_free(fwup);
  640. return TLS_FWUP_STATUS_EMEM;
  641. }
  642. return TLS_FWUP_STATUS_OK;
  643. }