• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 ASR Microelectronics (Shanghai) 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 #include <string.h>
17 #include <stdlib.h>
18 #include "duet_common.h"
19 #include "cmsis_os2.h"
20 #include "include/kal.h"
21 #include "target_config.h"
22 #include "lega_rtos.h"
23 
24 #ifdef LEGA_CM4
25 #include "lega_cm4.h"
26 #else
27 #ifdef DUET_CM4
28 #include "duet_cm4.h"
29 #endif
30 #endif
31 
32 #define CM4_ICSR  0xE000ED04
33 
34 #define COMPRESS_LEN(x) (sizeof(size_t))
35 
36 lega_task_config_t task_cfg[LEGA_TASK_CONFIG_MAX] = {
37 #ifdef USE_SMALL_STACK
38     {LEGA_WPA3_AUTH_TASK_PRIORITY, 2560},
39     {LEGA_LWIFI_TASK_PRIORITY, 2560},
40 #else
41     {LEGA_WPA3_AUTH_TASK_PRIORITY, 13312},
42     {LEGA_LWIFI_TASK_PRIORITY, 2048},
43 #endif
44     {LEGA_UWIFI_RX_TASK_PRIORITY, 4096},
45     {LEGA_UWIFI_TASK_PRIORITY, 7168},
46     {LEGA_LWIP_DHCP_TASK_PRIORITY, 1536},
47     {LEGA_BLE_SCHEDULER_PRIORITY, 4096},
48 };
49 
lega_rtos_is_in_interrupt_context(void)50 OSBool lega_rtos_is_in_interrupt_context(void)
51 {
52     unsigned int state = 0;
53 
54     state = (*(unsigned int *) CM4_ICSR) & 0x3FF; // bit0:9 is IRQ NO.
55 
56     if (state != 0) {
57         return TRUE;
58     }
59 
60     return  FALSE;
61 }
62 
lega_vector_table_reloc(void)63 void lega_vector_table_reloc(void)
64 {
65 
66 }
67 /*******************************************************************
68 * Name: lega_task_cfg_init
69 * Description: this api get wifi task config
70 * input param: task index defined in lega_rtos.h
71 * output param: config data of wifi task
72 * return: OSSatus value
73 *******************************************************************/
lega_rtos_task_cfg_get(uint32_t index,lega_task_config_t * cfg)74 OSStatus lega_rtos_task_cfg_get(uint32_t index, lega_task_config_t *cfg)
75 {
76     if (!cfg || (index >= LEGA_TASK_CONFIG_MAX)) {
77         return kGeneralErr;
78     }
79     cfg->task_priority = task_cfg[index].task_priority;
80     cfg->stack_size = task_cfg[index].stack_size;
81 
82     return kNoErr;
83 }
84 /*******************************************************************
85 * Name: lega_rtos_create_thread
86 * Description: this api call freeRTOS function "xTaskCreate" to create task
87 * input param: task priority, stack_size, function, name
88 * output param: thread
89 * return: OSSatus value
90 *******************************************************************/
lega_rtos_create_thread(lega_thread_t * thread,uint8_t priority,const char * name,lega_thread_function_t function,uint32_t stack_size,lega_thread_arg_t arg)91 OSStatus lega_rtos_create_thread(lega_thread_t *thread, uint8_t priority, const char *name,
92                                   lega_thread_function_t function, uint32_t stack_size, lega_thread_arg_t arg)
93 {
94     uint8_t autorun = 1;
95     osThreadAttr_t attr = {0};
96     osThreadId_t threadId;
97 
98     if (thread == NULL || name == NULL || function == NULL) {
99         printf("thread create fail\r\n");
100         return kGeneralErr;
101     }
102 
103     attr.name = name;
104     attr.attr_bits = 0U;
105     attr.cb_mem = NULL;
106     attr.cb_size = 0U;
107     attr.stack_mem = NULL;
108     attr.stack_size = stack_size;
109     // here should add bound check!
110     attr.priority = priority;
111     if (autorun == 1) {
112         threadId = osThreadNew((osThreadFunc_t)function, (void *)arg, &attr);
113         if (threadId == 0) {
114             printf("thread %s create fail %d\r\n", name, (int)threadId);
115             return kGeneralErr;
116         }
117         *(unsigned int *)thread = (unsigned int)threadId;
118     }
119     return kNoErr;
120 }
121 
122 /*******************************************************************
123 * Name: lega_rtos_delete_thread
124 * Description: this api calls FreeRTOS function "xTaskDelete" to delete a task
125 * input param: thread
126 * output param: none
127 * return:  OSStatus
128 *******************************************************************/
lega_rtos_delete_thread(lega_thread_t * thread)129 OSStatus lega_rtos_delete_thread(lega_thread_t *thread)
130 {
131     osThreadId_t threadId;
132     if (thread == NULL) {
133         threadId = osThreadGetId();
134     } else {
135         threadId = (osThreadId_t)(*(unsigned int *)thread);
136     }
137 
138     if (osThreadTerminate(threadId) != 0) {
139         printf("thread delete fail\r\n");
140         return kGeneralErr;
141     }
142 
143     if (thread != NULL) {
144         *(unsigned int *)thread = 0;
145     }
146     return kNoErr;
147 }
148 /////////////////////////////  semaphore  //////////////////////////////////////
149 
150 /*******************************************************************
151 * Name:lega_rtos_init_semaphore
152 * Description: create a count semaphore
153 * input param: init value,
154 * output param: lega_semaphore_t* semaphore
155 * return: kNoErr or kGeneralErr;
156 *******************************************************************/
lega_rtos_init_semaphore(lega_semaphore_t * semaphore,int count)157 OSStatus lega_rtos_init_semaphore(lega_semaphore_t *semaphore, int count)
158 {
159     osSemaphoreId_t semId;
160 
161     semId = osSemaphoreNew(0xFF, (uint32_t)count, 0);
162     if (semId == 0) {
163         printf("sema init fail %d\r\n", (int)semId);
164         return kGeneralErr;
165     }
166 
167     *semaphore = (lega_semaphore_t *)semId;
168     return kNoErr;
169 }
170 /*******************************************************************
171 * Name:lega_rtos_get_semaphore
172 * Description: get semaphore value
173 * input param:semaphore, timeout_ms
174 * output param: semaphore
175 * return: kNoErr or kGeneralErr
176 *******************************************************************/
lega_rtos_get_semaphore(lega_semaphore_t * semaphore,uint32_t timeout_ms)177 OSStatus lega_rtos_get_semaphore(lega_semaphore_t *semaphore, uint32_t timeout_ms)
178 {
179     osStatus_t ret;
180 
181     ret = osSemaphoreAcquire((osSemaphoreId_t)(*semaphore), timeout_ms);
182     if (ret != osOK) {
183         printf("sem get fail %d\r\n", ret);
184         return kGeneralErr;
185     }
186 
187     return kNoErr;
188 }
189 
lega_rtos_set_semaphore(lega_semaphore_t * semaphore)190 FLASH_COMMON2_SEG OSStatus lega_rtos_set_semaphore(lega_semaphore_t *semaphore)
191 {
192     osStatus_t ret;
193 
194     ret = osSemaphoreRelease((osSemaphoreId_t)(*semaphore));
195     if (ret != osOK) {
196         printf("sema set fail %d\r\n", ret);
197         return kGeneralErr;
198     }
199 
200     return kNoErr;
201 }
202 
lega_rtos_deinit_semaphore(lega_semaphore_t * semaphore)203 OSStatus lega_rtos_deinit_semaphore(lega_semaphore_t *semaphore)
204 {
205     osStatus_t ret;
206 
207     ret = osSemaphoreDelete((osSemaphoreId_t)(*semaphore));
208     if (ret != osOK) {
209         printf("sema deinit fail %d\r\n", ret);
210         return kGeneralErr;
211     }
212     *semaphore = NULL;
213     return kNoErr;
214 }
215 
lega_rtos_semaphore_pending_task_null(lega_semaphore_t * semaphore)216 OSBool lega_rtos_semaphore_pending_task_null(lega_semaphore_t *semaphore)
217 {
218     osStatus_t ret;
219 
220     ret = osSemaphorePendingNoTask((osSemaphoreId_t)(*semaphore));
221     if (ret == osOK) {
222         return TRUE;
223     } else {
224         return FALSE;
225     }
226 }
227 
lega_rtos_init_mutex(lega_mutex_t * mutex)228 OSStatus lega_rtos_init_mutex(lega_mutex_t *mutex)
229 {
230     osMutexId_t mutexId;
231     mutexId = osMutexNew(0);
232     if (mutexId == 0) {
233         printf("mutex init fail %d\r\n", (int)mutexId);
234         return kGeneralErr;
235     }
236 
237     *mutex = (lega_mutex_t)mutexId;
238     return kNoErr;
239 }
240 
lega_rtos_lock_mutex(lega_mutex_t * mutex,uint32_t timeout_ms)241 OSStatus lega_rtos_lock_mutex(lega_mutex_t *mutex, uint32_t timeout_ms)
242 {
243     osStatus_t ret;
244 
245     ret = osMutexAcquire((osMutexId_t)(*mutex), timeout_ms);
246     if (ret != osOK) {
247         printf("mutex lock fail %d\r\n", ret);
248         return kGeneralErr;
249     }
250 
251     return kNoErr;
252 }
253 
lega_rtos_unlock_mutex(lega_mutex_t * mutex)254 OSStatus lega_rtos_unlock_mutex(lega_mutex_t *mutex)
255 {
256     osStatus_t ret;
257 
258     ret = osMutexRelease((osMutexId_t)(*mutex));
259     if (ret != osOK) {
260         printf("mutex unlock fail %d", ret);
261         return kGeneralErr;
262     }
263 
264     return kNoErr;
265 }
266 
lega_rtos_deinit_mutex(lega_mutex_t * mutex)267 OSStatus lega_rtos_deinit_mutex(lega_mutex_t *mutex)
268 {
269     osStatus_t ret;
270 
271     ret = osMutexDelete((osMutexId_t)(*mutex));
272     if (ret != osOK) {
273         printf("mutex deinit fail %d\r\n", ret);
274         return kGeneralErr;
275     }
276 
277     *mutex = NULL;
278     return kNoErr;
279 }
280 
lega_rtos_init_queue(lega_queue_t * queue,const char * name,uint32_t message_size,uint32_t number_of_messages)281 OSStatus lega_rtos_init_queue(lega_queue_t *queue, const char *name, uint32_t message_size,
282                               uint32_t number_of_messages)
283 {
284     osMessageQueueId_t queId;
285 
286     (void)name;
287     queId = osMessageQueueNew(number_of_messages, message_size, 0);
288     if (queId == 0) {
289         printf("queue init fail %d\r\n", (int)queId);
290         return kGeneralErr;
291     }
292 
293     *queue = queId;
294     return kNoErr;
295 }
296 
lega_rtos_push_to_queue(lega_queue_t * queue,void * message,uint32_t timeout_ms)297 OSStatus lega_rtos_push_to_queue(lega_queue_t *queue, void *message, uint32_t timeout_ms)
298 {
299     osStatus_t ret;
300 
301     if (lega_rtos_is_in_interrupt_context()) {
302         ret = osMessageQueuePut((osMessageQueueId_t)(*queue), message, 0, 0);
303     } else {
304         ret = osMessageQueuePut((osMessageQueueId_t)(*queue), message, 0, timeout_ms);
305     }
306     if (ret != osOK) {
307         printf("push_to_queue fail:%d\r\n", ret);
308         return kGeneralErr;
309     }
310 
311     return kNoErr;
312 }
313 
lega_rtos_pop_from_queue(lega_queue_t * queue,void * message,uint32_t timeout_ms)314 OSStatus lega_rtos_pop_from_queue(lega_queue_t *queue, void *message, uint32_t timeout_ms)
315 {
316     osStatus_t ret;
317 
318     ret = osMessageQueueGet((osMessageQueueId_t)(*queue), message, 0, timeout_ms);
319     if (ret != osOK) {
320         if (timeout_ms) {
321             printf("pop_from_queue fail:%d\r\n", ret);
322         }
323         return kGeneralErr;
324     }
325 
326     return kNoErr;
327 }
328 
lega_rtos_deinit_queue(lega_queue_t * queue)329 OSStatus lega_rtos_deinit_queue(lega_queue_t *queue)
330 {
331     osStatus_t ret;
332 
333     ret = osMessageQueueDelete((osMessageQueueId_t)(*queue));
334     if (ret != osOK) {
335         printf("queue deinit fail:%d\r\n", ret);
336         return kGeneralErr;
337     }
338 
339     return kNoErr;
340 }
341 
lega_rtos_is_queue_empty(lega_queue_t * queue)342 OSBool lega_rtos_is_queue_empty(lega_queue_t *queue)
343 {
344     OSBool ret;
345     lega_rtos_declare_critical();
346 
347     if (!lega_rtos_is_in_interrupt_context()) {
348         lega_rtos_enter_critical();
349     }
350 
351     if (osMessageQueueGetCount((osMessageQueueId_t)(*queue)) == 0) {
352         ret = TRUE;
353     } else {
354         ret = FALSE;
355     }
356 
357     if (!lega_rtos_is_in_interrupt_context()) {
358         lega_rtos_exit_critical();
359     }
360 
361     return ret;
362 }
363 
lega_rtos_is_queue_full(lega_queue_t * queue)364 OSBool lega_rtos_is_queue_full(lega_queue_t *queue)
365 {
366     OSBool ret;
367     lega_rtos_declare_critical();
368 
369     if (!lega_rtos_is_in_interrupt_context()) {
370         lega_rtos_enter_critical();
371     }
372 
373     if (osMessageQueueGetSpace((osMessageQueueId_t)(*queue)) == 0) {
374         ret = TRUE;
375     } else {
376         ret = FALSE;
377     }
378 
379     if (!lega_rtos_is_in_interrupt_context()) {
380         lega_rtos_exit_critical();
381     }
382 
383     return ret;
384 }
385 
386 #if 1
387 
lega_rtos_ms_to_ticks(uint32_t ms)388 uint32_t lega_rtos_ms_to_ticks(uint32_t ms)
389 {
390     uint32_t ticks;
391 
392     uint64_t padding;
393 
394     padding = MS_PER_SECONED / LOSCFG_BASE_CORE_TICK_PER_SECOND;
395     padding = (padding > 0) ? (padding - 1) : 0;
396 
397     ticks = ((ms + padding) * LOSCFG_BASE_CORE_TICK_PER_SECOND) / MS_PER_SECONED;
398     return ticks;
399 }
400 
401 #if 1
lega_rtos_init_timer(lega_timer_t * timer,uint32_t time_ms,timer_handler_t function,void * arg)402 OSStatus lega_rtos_init_timer(lega_timer_t *timer, uint32_t time_ms, timer_handler_t function, void *arg)
403 {
404     timer->function = function;
405     timer->arg      = arg;
406 
407     KalTimerType kalType = KAL_TIMER_PERIODIC;
408     KalTimerId timeId;
409 
410     timeId = KalTimerCreate(function, kalType, arg, time_ms);
411     if (timeId == 0) {
412         printf("rtos_init_timer err %d\r\n", (int)timeId);
413         return kGeneralErr;
414     }
415     timer->handle = timeId;
416 
417     return kNoErr;
418 }
419 #else
lega_rtos_init_timer_name(lega_timer_t * timer,uint32_t time_ms,timer_handler_t function,void * arg,uint8_t * name)420 OSStatus lega_rtos_init_timer_name(lega_timer_t *timer, uint32_t time_ms, timer_handler_t function, void *arg,
421                                    uint8_t  *name)
422 {
423     if (!timer) {
424         printf("%s %s timer err\n", __FUNCTION__, name);
425         return kGeneralErr;
426     }
427     timer->function = function;
428     if (!arg) {
429         timer->arg     = name;
430     } else {
431         timer->arg      = arg;
432     }
433 
434     KalTimerType kalType = KAL_TIMER_PERIODIC;
435     KalTimerId timeId;
436 
437     timeId = KalTimerCreate(timer->function, kalType, timer->arg, time_ms);
438     if (timeId == 0) {
439         printf("rtos_init_timer err %d\r\n", (int)timeId);
440         return kGeneralErr;
441     }
442     timer->handle = timeId;
443 
444     return kNoErr;
445 }
446 #endif
447 
lega_rtos_start_timer(lega_timer_t * timer)448 OSStatus lega_rtos_start_timer(lega_timer_t *timer)
449 {
450     if (!timer) {
451         printf("%s timer err\n", __FUNCTION__);
452         return kGeneralErr;
453     }
454     if (KalTimerStart((KalTimerId)(timer->handle)) == KAL_OK) {
455         return kNoErr;
456     }
457 
458     return kGeneralErr;
459 }
460 
lega_rtos_stop_timer(lega_timer_t * timer)461 OSStatus lega_rtos_stop_timer(lega_timer_t *timer)
462 {
463     if (!timer) {
464         printf("%s timer err\n", __FUNCTION__);
465         return kGeneralErr;
466     }
467     if (KalTimerStop((KalTimerId)(timer->handle)) == KAL_OK) {
468         // printf("rtos_stop_timer\r\n");
469         return kNoErr;
470     }
471 
472     return kGeneralErr;
473 }
474 
lega_rtos_reload_timer(lega_timer_t * timer)475 OSStatus lega_rtos_reload_timer(lega_timer_t *timer)
476 {
477     if (!timer) {
478         printf("%s timer err\n", __FUNCTION__);
479         return kGeneralErr;
480     }
481     if (KalTimerStop((KalTimerId)(timer->handle)) != KAL_OK) {
482         printf("rtos_reload_timer err1\r\n");
483         return kGeneralErr;
484     }
485 
486     if (KalTimerStart((KalTimerId)(timer->handle)) != KAL_OK) {
487         printf("rtos_reload_timer err2\r\n");
488         return kGeneralErr;
489     }
490 
491     return kNoErr;
492 }
493 
lega_rtos_deinit_timer(lega_timer_t * timer)494 OSStatus lega_rtos_deinit_timer(lega_timer_t *timer)
495 {
496     if (!timer) {
497         printf("%s timer err\n", __FUNCTION__);
498         return kGeneralErr;
499     }
500     if (KalTimerStop((KalTimerId)(timer->handle)) != KAL_OK) {
501         printf("rtos_stop_timer err\r\n");
502         return kGeneralErr;
503     }
504     if (KalTimerDelete((KalTimerId)(timer->handle)) == KAL_OK) {
505 
506         timer->handle = 0;
507         return kNoErr;
508     }
509     timer->handle = 0;
510 
511     return kGeneralErr;
512 }
513 
lega_rtos_is_timer_running(lega_timer_t * timer)514 OSBool lega_rtos_is_timer_running(lega_timer_t *timer)
515 {
516     if (!timer) {
517         printf("%s timer err\n", __FUNCTION__);
518         return kGeneralErr;
519     }
520 
521     if (KalTimerIsRunning((KalTimerId)(timer->handle))) {
522 
523         return TRUE;
524     }
525     return FALSE;
526 }
527 
lega_rtos_ticks_to_ms(uint32_t ticks)528 uint32_t lega_rtos_ticks_to_ms(uint32_t ticks)
529 {
530     uint64_t   padding;
531     uint32_t time;
532 
533     padding = LOSCFG_BASE_CORE_TICK_PER_SECOND / 1000;
534     padding = (padding > 0) ? (padding - 1) : 0;
535 
536     time = ((ticks + padding) * 1000) / LOSCFG_BASE_CORE_TICK_PER_SECOND;
537 
538     return time;
539 }
540 
lega_rtos_get_time(void)541 uint32_t lega_rtos_get_time(void)
542 {
543     return (uint32_t)lega_rtos_ticks_to_ms((unsigned int)osKernelGetTickCount());
544 }
545 
lega_rtos_get_system_ticks(void)546 uint32_t lega_rtos_get_system_ticks(void)
547 {
548     return (uint32_t)osKernelGetTickCount();
549 }
550 
lega_rtos_delay_milliseconds(uint32_t num_ms)551 OSStatus lega_rtos_delay_milliseconds(uint32_t num_ms)
552 {
553     uint32_t ticks;
554 
555     ticks = lega_rtos_ms_to_ticks(num_ms);
556     if (ticks == 0) {
557         ticks = 1;
558     }
559 
560     osDelay(ticks);
561 
562     return kNoErr;
563 }
564 
565 #endif
566 int32_t lega_malloc_cnt = 0;
_lega_rtos_malloc(uint32_t xWantedSize,const char * function,uint32_t line)567 void *_lega_rtos_malloc(uint32_t xWantedSize, const char *function, uint32_t line)
568 {
569     void *p = malloc(xWantedSize);
570     uint32_t size_cache = xWantedSize;
571     if (p) {
572         lega_malloc_cnt++;
573     } else {
574         if (size_cache != 0) {
575             printf("rtos malloc %u fail  %s:%u\r\n", (unsigned int)xWantedSize, function, (unsigned int)line);
576         }
577     }
578     while (size_cache) {
579         if (size_cache >= (sizeof(int))) {
580             size_cache -= sizeof(int);
581             * (int *)(p + size_cache) = 0;
582         } else {
583             size_cache--;
584             * (char *)(p + size_cache) = 0;   // clear memory alloced
585         }
586     }
587     return p;
588 }
589 
lega_rtos_free(void * mem)590 void lega_rtos_free(void *mem)
591 {
592     if (mem) {
593         lega_malloc_cnt--;
594     } else {
595         printf("rtos free null\r\n");
596         return;
597     }
598 
599     free(mem);
600 }
601 
lega_rtos_realloc(void * mem,uint32_t xWantedSize)602 void lega_rtos_realloc(void *mem, uint32_t xWantedSize)
603 {
604     if (mem) {
605         realloc(mem, xWantedSize);
606     } else {
607         printf("rtos realloc null\r\n");
608     }
609     return;
610 }
611 
pvPortMalloc(uint32_t xWantedSize)612 void *pvPortMalloc(uint32_t xWantedSize)
613 {
614     return lega_rtos_malloc(xWantedSize);
615 }
616 
vPortFree(void * pv)617 void vPortFree(void *pv)
618 {
619     lega_rtos_free(pv);
620 }
621 
622 /*******************************************************************
623 * Name:lega_rtos_enter_critical
624 * Description: get system into critical area where there is no context switch
625 * input param: none
626 * output param: none
627 * return:none
628 *******************************************************************/
_lega_rtos_enter_critical(void)629 lega_cpsr_t _lega_rtos_enter_critical(void)
630 {
631     lega_cpsr_t cpsr_save = LOS_IntLock();
632     return cpsr_save;
633 }
634 
635 /*******************************************************************
636 * Name:lega_rtos_exit_critical
637 * Description: get system out of critical area
638 * input param: none
639 * output param:none
640 * return:none
641 *******************************************************************/
_lega_rtos_exit_critical(lega_cpsr_t cpsr_store)642 void _lega_rtos_exit_critical(lega_cpsr_t cpsr_store)
643 {
644     LOS_IntRestore(cpsr_store);
645 }
646 
lega_intrpt_enter(void)647 void lega_intrpt_enter(void)
648 {
649 }
650 
651 /*******************************************************************
652 * Name:lega_intrpt_exit
653 * Description: exit interrupt
654 * input param: none
655 * output param:none
656 * return:none
657 *******************************************************************/
lega_intrpt_exit(void)658 void lega_intrpt_exit(void)
659 {
660 }
661