wm_fwup.c 17 KB

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