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