1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 /**************************************************************************/
12 /**************************************************************************/
13 /**                                                                       */
14 /** ThreadX Component                                                     */
15 /**                                                                       */
16 /**   FreeRTOS compatibility Kit                                          */
17 /**                                                                       */
18 /**************************************************************************/
19 /**************************************************************************/
20 /*  RELEASE HISTORY                                                       */
21 /*                                                                        */
22 /*    DATE              NAME                      DESCRIPTION             */
23 /*                                                                        */
24 /*  09-30-2020     William E. Lamie         Initial Version 6.1           */
25 /*  10-15-2021     William E. Lamie         Modified comment(s), and      */
26 /*                                            fixed compiler warnings,    */
27 /*                                            resulting in version 6.1.7  */
28 /*  01-31-2022     William E. Lamie         Modified comment(s), and      */
29 /*                                            fixed compiler warnings,    */
30 /*                                            resulting in version 6.1.10 */
31 /*  07-29-2022     Cindy Deng               Added simple static scheduler */
32 /*                                            start flag, corrected stack */
33 /*                                            allocation size,            */
34 /*                                            resulting in version 6.1.12 */
35 /*  12-31-2023     Xiuwen Cai               Modified comment(s), and      */
36 /*                                            added check for overflow in */
37 /*                                            queue size calculation,     */
38 /*                                            resulting in version 6.4.0  */
39 /*                                                                        */
40 /**************************************************************************/
41 
42 #include <stdint.h>
43 #include <limits.h>
44 
45 #include <tx_api.h>
46 #include <tx_thread.h>
47 #include <tx_semaphore.h>
48 #include <tx_queue.h>
49 
50 #include "FreeRTOS.h"
51 
52 #if (INCLUDE_vTaskDelete == 1)
53 static TX_THREAD txfr_idle_task;
54 #ifdef TX_FREERTOS_IDLE_STACK
55 static UINT txfr_idle_stack[TX_FREERTOS_IDLE_STACK];
56 #else
57 static UINT txfr_idle_stack[configMINIMAL_STACK_SIZE];
58 #endif
59 static TX_SEMAPHORE txfr_idle_sem;
60 
61 static txfr_task_t *p_delete_task_head;
62 #endif // #if (INCLUDE_vTaskDelete == 1)
63 
64 UBaseType_t g_txfr_task_count;
65 
66 #ifdef configTOTAL_HEAP_SIZE
67 static uint8_t txfr_heap_mem[configTOTAL_HEAP_SIZE];
68 static TX_BYTE_POOL txfr_heap;
69 #endif
70 
71 static UINT txfr_heap_initialized;
72 #if (TX_FREERTOS_AUTO_INIT == 1)
73 static UINT txfr_initialized;
74 static UINT txfr_scheduler_started;
75 #endif // #if (TX_FREERTOS_AUTO_INIT == 1)
76 
77 // TODO - do something with malloc.
txfr_malloc(size_t len)78 void *txfr_malloc(size_t len)
79 {
80     void *p;
81     UINT ret;
82 
83     if(txfr_heap_initialized == 1u) {
84         ret = tx_byte_allocate(&txfr_heap, &p, len, 0u);
85         if(ret != TX_SUCCESS) {
86             return NULL;
87         }
88     } else {
89         return NULL;
90     }
91 
92     return p;
93 }
94 
txfr_free(void * p)95 void txfr_free(void *p)
96 {
97     UINT ret;
98 
99     if(txfr_heap_initialized == 1u) {
100         ret = tx_byte_release(p);
101         if(ret != TX_SUCCESS) {
102             TX_FREERTOS_ASSERT_FAIL();
103         }
104     }
105 
106     return;
107 }
108 
109 #if (INCLUDE_vTaskDelete == 1)
txfr_idle_task_entry(ULONG id)110 static void txfr_idle_task_entry(ULONG id)
111 {
112     txfr_task_t *p_task;
113     UINT ret;
114     TX_INTERRUPT_SAVE_AREA;
115 
116 
117     for(;;) {
118         ret = tx_semaphore_get(&txfr_idle_sem, TX_WAIT_FOREVER);
119         if(ret != TX_SUCCESS) {
120             TX_FREERTOS_ASSERT_FAIL();
121         }
122 
123         TX_DISABLE;
124         p_task = p_delete_task_head;
125 
126         if(p_task != NULL) {
127             p_delete_task_head = p_task->p_next;
128         }
129         g_txfr_task_count--;
130         TX_RESTORE;
131 
132         if(p_task != NULL) {
133 
134             // Make sure the task is terminated, which may return an error if that's already the case so the return value is ignored.
135             (void)tx_thread_terminate(&p_task->thread);
136 
137             ret = tx_thread_delete(&p_task->thread);
138             if(ret != TX_SUCCESS) {
139                 TX_FREERTOS_ASSERT_FAIL();
140             }
141 
142             ret = tx_semaphore_delete(&p_task->notification_sem);
143             if(ret != TX_SUCCESS) {
144                 TX_FREERTOS_ASSERT_FAIL();
145             }
146 
147             if(p_task->allocated == 1u) {
148                 txfr_free(p_task);
149             }
150         }
151 
152     }
153 }
154 #endif // #if (INCLUDE_vTaskDelete == 1)
155 
txfr_prio_fr_to_tx(uint32_t prio)156 static uint32_t txfr_prio_fr_to_tx(uint32_t prio)
157 {
158     return TX_MAX_PRIORITIES - 1u - prio;
159 }
160 
161 
txfr_prio_tx_to_fr(uint32_t prio)162 static uint32_t txfr_prio_tx_to_fr(uint32_t prio)
163 {
164     return TX_MAX_PRIORITIES - 1u - prio;
165 }
166 
167 #if (TX_FREERTOS_AUTO_INIT == 1)
tx_freertos_auto_init(void)168 static void tx_freertos_auto_init(void)
169 {
170     UINT ret;
171 
172     tx_kernel_enter();
173 
174     ret = tx_freertos_init();
175     if(ret != TX_SUCCESS) {
176         TX_FREERTOS_ASSERT_FAIL();
177         return;
178     }
179 
180     txfr_initialized = 1u;
181 }
182 #endif // #if (TX_FREERTOS_AUTO_INIT == 1)
183 
184 #if (TX_FREERTOS_AUTO_INIT == 1)
tx_application_define(VOID * first_unused_memory)185 VOID tx_application_define(VOID * first_unused_memory)
186 {
187     // Empty tx_application_define() to support auto initialization.
188 }
189 #endif // #if (TX_FREERTOS_AUTO_INIT == 1)
190 
tx_freertos_init(void)191 UINT tx_freertos_init(void)
192 {
193     UINT ret;
194 
195 #ifdef configTOTAL_HEAP_SIZE
196     if(configTOTAL_HEAP_SIZE > 0u) {
197         ret = tx_byte_pool_create(&txfr_heap, "txfr_byte_pool", txfr_heap_mem, configTOTAL_HEAP_SIZE);
198         if(ret != TX_SUCCESS) {
199             return ret;
200         }
201         txfr_heap_initialized = 1u;
202     }
203 #endif
204 
205 #if (INCLUDE_vTaskDelete == 1)
206     ret = tx_semaphore_create(&txfr_idle_sem, "txfr_idle_semaphore", 0u);
207     if(ret != TX_SUCCESS) {
208         return ret;
209     }
210 
211     ret = tx_thread_create(&txfr_idle_task, "txfr_idle_task", txfr_idle_task_entry, 0u,
212             txfr_idle_stack, sizeof(txfr_idle_stack), TX_MAX_PRIORITIES - 1u, TX_MAX_PRIORITIES - 1u, 0u, TX_AUTO_START);
213     if(ret != TX_SUCCESS) {
214         return ret;
215     }
216 #endif // #if (INCLUDE_vTaskDelete == 1)
217 
218     return TX_SUCCESS;
219 }
220 
txfr_thread_wrapper(ULONG id)221 void txfr_thread_wrapper(ULONG id)
222 {
223     TX_THREAD *p_thread;
224     txfr_task_t *p_txfr_task;
225 
226     p_thread = tx_thread_identify();
227 
228     p_txfr_task = p_thread->txfr_thread_ptr;
229 
230     p_txfr_task->p_task_func(p_txfr_task->p_task_arg);
231 
232 #if (INCLUDE_vTaskDelete == 1)
233     vTaskDelete(NULL);
234 #else
235     // Returning from a task is not allowed when vTaskDelete is disabled.
236     TX_FREERTOS_ASSERT_FAIL();
237 #endif // #if (INCLUDE_vTaskDelete == 1)
238 }
239 
240 
pvPortMalloc(size_t xWantedSize)241 void *pvPortMalloc(size_t xWantedSize)
242 {
243     return txfr_malloc(xWantedSize);
244 }
245 
vPortFree(void * pv)246 void vPortFree(void *pv)
247 {
248     txfr_free(pv);
249 
250     return;
251 }
252 
vPortEnterCritical(void)253 void vPortEnterCritical(void)
254 {
255     portDISABLE_INTERRUPTS();
256     _tx_thread_preempt_disable++;
257 }
258 
vPortExitCritical(void)259 void vPortExitCritical(void)
260 {
261     if(_tx_thread_preempt_disable == 0u) {
262         TX_FREERTOS_ASSERT_FAIL();
263     }
264 
265     _tx_thread_preempt_disable--;
266 
267     if(_tx_thread_preempt_disable == 0u) {
268         portENABLE_INTERRUPTS();
269     }
270 }
271 
vTaskStartScheduler(void)272 void vTaskStartScheduler(void)
273 {
274 #if (TX_FREERTOS_AUTO_INIT == 1)
275     txfr_scheduler_started = 1u;
276     _tx_thread_schedule();
277 #else
278     // Nothing to do, THREADX scheduler is already started.
279 #endif
280 }
281 
282 
xTaskGetSchedulerState(void)283 BaseType_t xTaskGetSchedulerState(void)
284 {
285 #if (TX_FREERTOS_AUTO_INIT == 1)
286     if(txfr_scheduler_started == 0u) {
287         return taskSCHEDULER_NOT_STARTED;
288     }
289 #endif
290     if(_tx_thread_preempt_disable > 0u) {
291         return taskSCHEDULER_SUSPENDED;
292     } else {
293         return taskSCHEDULER_RUNNING;
294     }
295 }
296 
297 
vTaskSuspendAll(void)298 void vTaskSuspendAll(void)
299 {
300     TX_INTERRUPT_SAVE_AREA;
301 
302     TX_DISABLE;
303     _tx_thread_preempt_disable++;
304     TX_RESTORE;
305 }
306 
xTaskResumeAll(void)307 BaseType_t xTaskResumeAll(void)
308 {
309     TX_INTERRUPT_SAVE_AREA;
310 
311     TX_DISABLE;
312     _tx_thread_preempt_disable--;
313     TX_RESTORE;
314 
315     return pdFALSE;
316 }
317 
vTaskDelay(const TickType_t xTicksToDelay)318 void vTaskDelay(const TickType_t xTicksToDelay)
319 {
320     tx_thread_sleep(xTicksToDelay);
321 }
322 
xTaskCreateStatic(TaskFunction_t pxTaskCode,const char * const pcName,const configSTACK_DEPTH_TYPE ulStackDepth,void * const pvParameters,UBaseType_t uxPriority,StackType_t * const puxStackBuffer,StaticTask_t * const pxTaskBuffer)323 TaskHandle_t xTaskCreateStatic(TaskFunction_t pxTaskCode,
324                                const char *const pcName,
325                                const configSTACK_DEPTH_TYPE ulStackDepth,
326                                void *const pvParameters,
327                                UBaseType_t uxPriority,
328                                StackType_t *const puxStackBuffer,
329                                StaticTask_t *const pxTaskBuffer)
330 {
331     UINT prio;
332     UINT ret;
333     ULONG stack_depth_bytes;
334     TX_INTERRUPT_SAVE_AREA;
335 
336     configASSERT(pxTaskCode != NULL);
337     configASSERT(ulStackDepth >= configMINIMAL_STACK_SIZE);
338     configASSERT(uxPriority < configMAX_PRIORITIES);
339     configASSERT(puxStackBuffer != NULL);
340     configASSERT(pxTaskBuffer != NULL);
341 
342 #if (TX_FREERTOS_AUTO_INIT == 1)
343     if(txfr_initialized != 1u) {
344         tx_freertos_auto_init();
345     }
346 #endif
347 
348     if(ulStackDepth > (ULONG_MAX / sizeof(StackType_t))) {
349         /* Integer overflow in stack depth */
350         TX_FREERTOS_ASSERT_FAIL();
351         return NULL;
352     }
353     stack_depth_bytes = ulStackDepth * sizeof(StackType_t);
354 
355     TX_MEMSET(pxTaskBuffer, 0, sizeof(*pxTaskBuffer));
356     pxTaskBuffer->p_task_arg = pvParameters;
357     pxTaskBuffer->p_task_func = pxTaskCode;
358 
359     ret = tx_semaphore_create(&pxTaskBuffer->notification_sem, "", 0u);
360     if(ret != TX_SUCCESS) {
361         TX_FREERTOS_ASSERT_FAIL();
362         return NULL;
363     }
364 
365     prio = txfr_prio_fr_to_tx(uxPriority);
366 
367     ret = tx_thread_create(&pxTaskBuffer->thread, (CHAR *)pcName, txfr_thread_wrapper, (ULONG)pvParameters,
368             puxStackBuffer, stack_depth_bytes, prio, prio, 0u, TX_DONT_START);
369     if(ret != TX_SUCCESS) {
370         TX_FREERTOS_ASSERT_FAIL();
371         return NULL;
372     }
373 
374     pxTaskBuffer->thread.txfr_thread_ptr = pxTaskBuffer;
375 
376     ret = tx_thread_resume(&pxTaskBuffer->thread);
377     if(ret != TX_SUCCESS) {
378         TX_FREERTOS_ASSERT_FAIL();
379         return NULL;
380     }
381 
382     TX_DISABLE;
383     g_txfr_task_count++;
384     TX_RESTORE;
385 
386     return pxTaskBuffer;
387 }
388 
389 
xTaskCreate(TaskFunction_t pvTaskCode,const char * const pcName,const configSTACK_DEPTH_TYPE usStackDepth,void * pvParameters,UBaseType_t uxPriority,TaskHandle_t * const pxCreatedTask)390 BaseType_t xTaskCreate(TaskFunction_t pvTaskCode,
391                        const char * const pcName,
392                        const configSTACK_DEPTH_TYPE usStackDepth,
393                        void *pvParameters,
394                        UBaseType_t uxPriority,
395                        TaskHandle_t * const pxCreatedTask)
396 {
397     void *p_stack;
398     txfr_task_t *p_task;
399     UINT ret;
400     UINT prio;
401     ULONG stack_depth_bytes;
402     TX_INTERRUPT_SAVE_AREA;
403 
404     configASSERT(pvTaskCode != NULL);
405     configASSERT(usStackDepth >= configMINIMAL_STACK_SIZE);
406     configASSERT(uxPriority < configMAX_PRIORITIES);
407     configASSERT(pxCreatedTask != NULL);
408 
409 #if (TX_FREERTOS_AUTO_INIT == 1)
410     if(txfr_initialized != 1u) {
411         tx_freertos_auto_init();
412     }
413 #endif
414     if((usStackDepth > (SIZE_MAX / sizeof(StackType_t)))
415         || (usStackDepth > (ULONG_MAX / sizeof(StackType_t)))) {
416         /* Integer overflow in stack depth */
417         return errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
418     }
419     stack_depth_bytes = usStackDepth * sizeof(StackType_t);
420 
421     p_stack = txfr_malloc((size_t)stack_depth_bytes);
422     if(p_stack == NULL) {
423         return errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
424     }
425 
426     p_task = txfr_malloc(sizeof(txfr_task_t));
427     if(p_task == NULL) {
428         txfr_free(p_stack);
429         return errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
430     }
431 
432     *pxCreatedTask = p_task;
433 
434     TX_MEMSET(p_task, 0, sizeof(*p_task));
435     p_task->allocated = 1u;
436     p_task->p_task_arg = pvParameters;
437     p_task->p_task_func = pvTaskCode;
438 
439     ret = tx_semaphore_create(&p_task->notification_sem, "", 0u);
440     if(ret != TX_SUCCESS) {
441         txfr_free(p_stack);
442         txfr_free(p_task);
443         TX_FREERTOS_ASSERT_FAIL();
444         return (BaseType_t)NULL;
445     }
446 
447     prio = txfr_prio_fr_to_tx(uxPriority);
448 
449     ret = tx_thread_create(&p_task->thread, (CHAR *)pcName, txfr_thread_wrapper, (ULONG)pvParameters,
450             p_stack, stack_depth_bytes, prio, prio, 0u, TX_DONT_START);
451     if(ret != TX_SUCCESS) {
452         (void)tx_semaphore_delete(&p_task->notification_sem);
453         txfr_free(p_stack);
454         txfr_free(p_task);
455         TX_FREERTOS_ASSERT_FAIL();
456         return (BaseType_t)NULL;
457     }
458 
459     p_task->thread.txfr_thread_ptr = p_task;
460 
461     ret = tx_thread_resume(&p_task->thread);
462     if(ret != TX_SUCCESS) {
463         TX_FREERTOS_ASSERT_FAIL();
464     }
465 
466     TX_DISABLE;
467     g_txfr_task_count++;
468     TX_RESTORE;
469 
470     return pdPASS;
471 }
472 
473 
uxTaskGetNumberOfTasks(void)474 UBaseType_t uxTaskGetNumberOfTasks(void)
475 {
476     UBaseType_t count;
477     TX_INTERRUPT_SAVE_AREA;
478 
479     TX_DISABLE;
480     count = g_txfr_task_count;
481     TX_RESTORE;
482 
483     return count;
484 }
485 
486 #if (INCLUDE_vTaskDelete == 1)
vTaskDelete(TaskHandle_t xTask)487 void vTaskDelete(TaskHandle_t xTask)
488 {
489     UINT ret;
490     TX_THREAD *p_thread;
491     txfr_task_t *p_txfr_thread;
492     TX_INTERRUPT_SAVE_AREA;
493 
494     if(xTask == NULL) {
495         TX_THREAD_GET_CURRENT(p_thread);
496         p_txfr_thread = (txfr_task_t *)p_thread->txfr_thread_ptr;
497     } else {
498         p_txfr_thread = xTask;
499         p_thread = &xTask->thread;
500     }
501 
502     TX_DISABLE;
503 
504     p_txfr_thread->p_next = p_delete_task_head;
505     p_delete_task_head = p_txfr_thread;
506 
507     _tx_thread_preempt_disable++;
508 
509     ret = tx_semaphore_put(&txfr_idle_sem);
510     if(ret != TX_SUCCESS) {
511         _tx_thread_preempt_disable--;
512         TX_RESTORE;
513         TX_FREERTOS_ASSERT_FAIL();
514         return;
515     }
516 
517     _tx_thread_preempt_disable--;
518 
519     TX_RESTORE;
520 
521     ret = tx_thread_terminate(p_thread);
522     if(ret != TX_SUCCESS) {
523         TX_RESTORE;
524         TX_FREERTOS_ASSERT_FAIL();
525         return;
526     }
527 
528     return;
529 }
530 #endif
531 
532 
xTaskGetCurrentTaskHandle(void)533 TaskHandle_t xTaskGetCurrentTaskHandle(void)
534 {
535     TX_THREAD *p_thread;
536 
537     p_thread = tx_thread_identify();
538 
539     return p_thread->txfr_thread_ptr;
540 }
541 
542 
vTaskSuspend(TaskHandle_t xTaskToSuspend)543 void vTaskSuspend(TaskHandle_t xTaskToSuspend)
544 {
545     TX_THREAD *p_thread;
546     UINT ret;
547 
548     if(xTaskToSuspend == NULL) {
549         p_thread = tx_thread_identify();
550     } else {
551         p_thread = &xTaskToSuspend->thread;
552     }
553 
554     ret = tx_thread_suspend(p_thread);
555     if(ret != TX_SUCCESS) {
556         TX_FREERTOS_ASSERT_FAIL();
557         return;
558     }
559 }
560 
561 
vTaskResume(TaskHandle_t xTaskToResume)562 void vTaskResume(TaskHandle_t xTaskToResume)
563 {
564     UINT ret;
565 
566     configASSERT(xTaskToResume != NULL);
567 
568     ret = tx_thread_resume(&xTaskToResume->thread);
569     if(ret != TX_SUCCESS) {
570         TX_FREERTOS_ASSERT_FAIL();
571         return;
572     }
573 }
574 
575 
xTaskResumeFromISR(TaskHandle_t xTaskToResume)576 BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume)
577 {
578     configASSERT(xTaskToResume != NULL);
579 
580     vTaskResume(xTaskToResume);
581 
582     return pdFALSE;
583 }
584 
585 
xTaskAbortDelay(TaskHandle_t xTask)586 BaseType_t xTaskAbortDelay(TaskHandle_t xTask)
587 {
588     TX_THREAD *p_thread;
589     UINT ret;
590 
591     configASSERT(xTask != NULL);
592 
593     p_thread = &xTask->thread;
594 
595     ret = tx_thread_wait_abort(p_thread);
596     if(ret != TX_SUCCESS) {
597         return pdFAIL;
598     }
599 
600     return pdPASS;
601 }
602 
603 
uxTaskPriorityGet(const TaskHandle_t xTask)604 UBaseType_t uxTaskPriorityGet(const TaskHandle_t xTask)
605 {
606     TX_THREAD *p_thread;
607     UINT priority;
608     UINT ret;
609 
610     if(xTask == NULL) {
611         p_thread = tx_thread_identify();
612     } else {
613         p_thread = &xTask->thread;
614     }
615 
616     ret = tx_thread_info_get(p_thread, NULL, NULL, NULL, &priority, NULL, NULL, NULL, NULL);
617     if(ret != TX_SUCCESS) {
618         TX_FREERTOS_ASSERT_FAIL();
619         return 0;
620     }
621 
622     priority = txfr_prio_tx_to_fr(priority);
623 
624     return priority;
625 }
626 
627 
uxTaskPriorityGetFromISR(const TaskHandle_t xTask)628 UBaseType_t uxTaskPriorityGetFromISR(const TaskHandle_t xTask)
629 {
630     return uxTaskPriorityGet(xTask);
631 }
632 
633 
vTaskPrioritySet(TaskHandle_t xTask,UBaseType_t uxNewPriority)634 void vTaskPrioritySet(TaskHandle_t xTask,
635                       UBaseType_t uxNewPriority)
636 {
637     TX_THREAD *p_thread;
638     UINT priority;
639     UINT old_priority;
640     UINT ret;
641 
642     configASSERT(uxNewPriority < configMAX_PRIORITIES);
643 
644     if(xTask == NULL) {
645         p_thread = tx_thread_identify();
646     } else {
647         p_thread = &xTask->thread;
648     }
649 
650     priority = uxNewPriority;
651     priority = txfr_prio_fr_to_tx(priority);
652 
653     ret = tx_thread_priority_change(p_thread, priority, &old_priority);
654     if(ret != TX_SUCCESS) {
655         TX_FREERTOS_ASSERT_FAIL();
656         return;
657     }
658 
659 }
660 
661 
pcTaskGetName(TaskHandle_t xTaskToQuery)662 char *pcTaskGetName(TaskHandle_t xTaskToQuery)
663 {
664     TX_THREAD *p_thread;
665     char *p_task_name;
666     UINT ret;
667 
668     if(xTaskToQuery == NULL) {
669         p_thread = tx_thread_identify();
670     } else {
671         p_thread = &xTaskToQuery->thread;
672     }
673 
674     ret = tx_thread_info_get(p_thread, &p_task_name, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
675     if(ret != TX_SUCCESS) {
676         TX_FREERTOS_ASSERT_FAIL();
677         return 0;
678     }
679 
680     return p_task_name;
681 }
682 
683 
eTaskGetState(TaskHandle_t xTask)684 eTaskState eTaskGetState(TaskHandle_t xTask)
685 {
686     UINT thread_state;
687     eTaskState ret_state;
688     TX_THREAD *p_thread;
689 
690     TX_INTERRUPT_SAVE_AREA;
691 
692     if(xTask == NULL) {
693         return eInvalid;
694     }
695 
696     TX_DISABLE;
697     thread_state = xTask->thread.tx_thread_state;
698     p_thread = &xTask->thread;
699     TX_RESTORE;
700 
701     if(p_thread == tx_thread_identify()) {
702         return eRunning;
703     }
704 
705     switch(thread_state) {
706         case TX_READY:
707             ret_state = eReady;
708             break;
709 
710         case TX_COMPLETED:
711         case TX_TERMINATED:
712             ret_state = eDeleted;
713             break;
714 
715         case TX_SUSPENDED:
716         case TX_SLEEP:
717             ret_state = eSuspended;
718             break;
719 
720         case TX_QUEUE_SUSP:
721         case TX_SEMAPHORE_SUSP:
722         case TX_EVENT_FLAG:
723         case TX_BLOCK_MEMORY:
724         case TX_BYTE_MEMORY:
725         case TX_IO_DRIVER:
726         case TX_FILE:
727         case TX_TCP_IP:
728         case TX_MUTEX_SUSP:
729             ret_state = eBlocked;
730             break;
731 
732         default:
733             ret_state = eInvalid;
734             break;
735     }
736 
737     return ret_state;
738 }
739 
740 
vTaskDelayUntil(TickType_t * const pxPreviousWakeTime,const TickType_t xTimeIncrement)741 void vTaskDelayUntil(TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement)
742 {
743     TickType_t tick_cur;
744 
745     tick_cur = (uint16_t)tx_time_get();
746 
747     tx_thread_sleep(xTimeIncrement - (tick_cur - *pxPreviousWakeTime));
748 
749     *pxPreviousWakeTime = *pxPreviousWakeTime + xTimeIncrement;
750 }
751 
752 
xTaskNotifyGive(TaskHandle_t xTaskToNotify)753 BaseType_t xTaskNotifyGive(TaskHandle_t xTaskToNotify)
754 {
755     configASSERT(xTaskToNotify != NULL);
756 
757     return xTaskNotify(xTaskToNotify, 0u, eIncrement);
758 }
759 
760 
vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify,BaseType_t * pxHigherPriorityTaskWoken)761 void vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify,
762                             BaseType_t *pxHigherPriorityTaskWoken)
763 {
764     configASSERT(xTaskToNotify != NULL);
765 
766     (void)xTaskNotify(xTaskToNotify, 0u, eIncrement);
767 }
768 
769 
ulTaskNotifyTake(BaseType_t xClearCountOnExit,TickType_t xTicksToWait)770 uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit,
771                           TickType_t xTicksToWait)
772 {
773     TX_THREAD *p_thread;
774     uint32_t val;
775     UINT ret;
776     UCHAR pend;
777     txfr_task_t *p_task;
778     UINT timeout;
779 
780     if(xTicksToWait ==  portMAX_DELAY) {
781         timeout = TX_WAIT_FOREVER;
782     } else {
783         timeout = (UINT)xTicksToWait;
784     }
785 
786     pend = TX_FALSE;
787     p_thread = tx_thread_identify();
788     p_task = p_thread->txfr_thread_ptr;
789 
790     TX_INTERRUPT_SAVE_AREA;
791 
792     TX_DISABLE;
793 
794     ret = tx_semaphore_get(&p_task->notification_sem, 0u);
795     if(ret == TX_SUCCESS) {
796         val = p_task->task_notify_val;
797         p_task->p_notify_val_ret = NULL;
798         if(xClearCountOnExit != pdFALSE) {
799             p_task->task_notify_val = 0u;
800         } else {
801             p_task->task_notify_val--;
802         }
803     } else {
804         pend = TX_TRUE;
805         p_task->p_notify_val_ret = &val;
806         p_task->clear_on_pend = xClearCountOnExit;
807         p_task->clear_mask = (uint32_t)-1;
808     }
809 
810     TX_RESTORE;
811 
812     if(pend == TX_TRUE) {
813         ret = tx_semaphore_get(&p_task->notification_sem, timeout);
814         p_task->p_notify_val_ret = NULL;
815         if(ret != TX_SUCCESS) {
816             return 0u;
817         }
818     }
819 
820     return val;
821 }
822 
xTaskNotifyWait(uint32_t ulBitsToClearOnEntry,uint32_t ulBitsToClearOnExit,uint32_t * pulNotificationValue,TickType_t xTicksToWait)823 BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry,
824                            uint32_t ulBitsToClearOnExit,
825                            uint32_t *pulNotificationValue,
826                            TickType_t xTicksToWait)
827 {
828     TX_INTERRUPT_SAVE_AREA;
829     TX_THREAD *p_thread;
830     uint32_t val;
831     BaseType_t ret_val;
832     UINT ret;
833     UCHAR pend;
834     txfr_task_t *p_task;
835     UINT timeout;
836 
837     ret_val = pdPASS;
838 
839     if(xTicksToWait ==  portMAX_DELAY) {
840         timeout = TX_WAIT_FOREVER;
841     } else {
842         timeout = (UINT)xTicksToWait;
843     }
844 
845     pend = TX_FALSE;
846     p_thread = tx_thread_identify();
847     p_task = p_thread->txfr_thread_ptr;
848 
849     TX_DISABLE;
850 
851     ret = tx_semaphore_get(&p_task->notification_sem, 0u);
852     if(ret == TX_SUCCESS) {
853         val = p_task->task_notify_val;
854         p_task->p_notify_val_ret = NULL;
855         if(ulBitsToClearOnExit != 0u) {
856             p_task->task_notify_val &= ~ulBitsToClearOnExit;
857         }
858     } else {
859         pend = TX_TRUE;
860         p_task->p_notify_val_ret = &val;
861         p_task->clear_on_pend = 1u;
862         p_task->clear_mask = ulBitsToClearOnExit;
863     }
864 
865     TX_RESTORE;
866 
867     if(pend == TX_TRUE) {
868         ret = tx_semaphore_get(&p_task->notification_sem, timeout);
869         p_task->p_notify_val_ret = NULL;
870         if(ret != TX_SUCCESS) {
871             return 0u;
872         }
873     }
874 
875     *pulNotificationValue = val;
876 
877     return ret_val;
878 }
879 
880 
xTaskNotify(TaskHandle_t xTaskToNotify,uint32_t ulValue,eNotifyAction eAction)881 BaseType_t xTaskNotify(TaskHandle_t xTaskToNotify,
882                        uint32_t ulValue,
883                        eNotifyAction eAction)
884 {
885 
886     configASSERT(TXFR_NOTIFYACTION_VALID(eAction));
887 
888     return xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, NULL);
889 }
890 
xTaskNotifyFromISR(TaskHandle_t xTaskToNotify,uint32_t ulValue,eNotifyAction eAction,BaseType_t * pxHigherPriorityTaskWoken)891 BaseType_t xTaskNotifyFromISR(TaskHandle_t xTaskToNotify,
892                               uint32_t ulValue,
893                               eNotifyAction eAction,
894                               BaseType_t *pxHigherPriorityTaskWoken)
895 {
896 
897     configASSERT(xTaskToNotify != NULL);
898     configASSERT(TXFR_NOTIFYACTION_VALID(eAction));
899 
900     return xTaskNotify(xTaskToNotify, ulValue, eAction);
901 }
902 
xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify,uint32_t ulValue,eNotifyAction eAction,uint32_t * pulPreviousNotifyValue)903 BaseType_t xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify,
904                                uint32_t ulValue,
905                                eNotifyAction eAction,
906                                uint32_t *pulPreviousNotifyValue)
907 {
908     UINT ret;
909     UCHAR notified;
910     TX_INTERRUPT_SAVE_AREA;
911     BaseType_t ret_val;
912     UCHAR waiting;
913 
914     configASSERT(xTaskToNotify != NULL);
915     configASSERT(TXFR_NOTIFYACTION_VALID(eAction));
916 
917     TX_DISABLE;
918 
919     if(pulPreviousNotifyValue != NULL) {
920         *pulPreviousNotifyValue = xTaskToNotify->task_notify_val;
921     }
922 
923     waiting = TX_FALSE;
924     notified = TX_FALSE;
925     ret_val = pdPASS;
926 
927     if(xTaskToNotify->notification_sem.tx_semaphore_suspended_count != 0u) {
928         waiting = TX_TRUE;
929     }
930 
931     if(xTaskToNotify->notification_sem.tx_semaphore_count == 0u) {
932         _tx_thread_preempt_disable++;
933 
934         ret = tx_semaphore_put(&xTaskToNotify->notification_sem);
935 
936         _tx_thread_preempt_disable--;
937 
938         if(ret != TX_SUCCESS) {
939             TX_RESTORE;
940             TX_FREERTOS_ASSERT_FAIL();
941             return pdFAIL;
942         }
943         xTaskToNotify->task_notify_val_pend = xTaskToNotify->task_notify_val;
944 
945         notified = TX_TRUE;
946     }
947 
948     switch (eAction) {
949         case eNoAction:
950             break;
951 
952         case eSetBits:
953             xTaskToNotify->task_notify_val |= ulValue;
954             break;
955 
956         case eIncrement:
957             xTaskToNotify->task_notify_val++;
958             break;
959 
960         case eSetValueWithOverwrite:
961             xTaskToNotify->task_notify_val = ulValue;
962             break;
963 
964         case eSetValueWithoutOverwrite:
965             if(notified == TX_TRUE) {
966                 xTaskToNotify->task_notify_val = ulValue;
967             } else {
968                 ret_val = pdFALSE;
969             }
970             break;
971 
972         default:
973             TX_RESTORE;
974             return pdFAIL;
975             break;
976     }
977 
978     if(waiting == TX_TRUE) {
979         *xTaskToNotify->p_notify_val_ret = xTaskToNotify->task_notify_val;
980 
981         if(xTaskToNotify->clear_on_pend == TX_TRUE) {
982             xTaskToNotify->task_notify_val &= ~xTaskToNotify->clear_mask;
983         } else {
984             xTaskToNotify->task_notify_val--;
985         }
986     }
987 
988     TX_RESTORE;
989 
990     _tx_thread_system_preempt_check();
991 
992     return ret_val;
993 }
994 
995 
xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,uint32_t ulValue,eNotifyAction eAction,uint32_t * pulPreviousNotifyValue,BaseType_t * pxHigherPriorityTaskWoken)996 BaseType_t xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,
997                                       uint32_t ulValue,
998                                       eNotifyAction eAction,
999                                       uint32_t *pulPreviousNotifyValue,
1000                                       BaseType_t *pxHigherPriorityTaskWoken)
1001 {
1002     configASSERT(xTaskToNotify != NULL);
1003     configASSERT(TXFR_NOTIFYACTION_VALID(eAction));
1004 
1005 
1006     return xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue);
1007 }
1008 
1009 
xTaskNotifyStateClear(TaskHandle_t xTask)1010 BaseType_t xTaskNotifyStateClear(TaskHandle_t xTask)
1011 {
1012     BaseType_t ret_val;
1013     UINT ret;
1014     TX_THREAD *p_thread;
1015     txfr_task_t *p_task;
1016     TX_INTERRUPT_SAVE_AREA;
1017 
1018     if(xTask == NULL) {
1019         p_thread = tx_thread_identify();
1020         p_task = p_thread->txfr_thread_ptr;
1021     } else {
1022         p_thread = &xTask->thread;
1023         p_task = xTask;
1024     }
1025 
1026     TX_DISABLE;
1027 
1028     if(p_task->notification_sem.tx_semaphore_suspended_count != 0u) {
1029         ret_val = pdTRUE;
1030     } else {
1031         ret_val = pdFALSE;
1032     }
1033 
1034     ret = tx_semaphore_get(&p_task->notification_sem, 0u);
1035     if(ret != TX_SUCCESS) {
1036         TX_RESTORE;
1037         TX_FREERTOS_ASSERT_FAIL();
1038         return pdFALSE;
1039     }
1040 
1041     TX_RESTORE;
1042 
1043     return ret_val;
1044 }
1045 
1046 
ulTaskNotifyValueClear(TaskHandle_t xTask,uint32_t ulBitsToClear)1047 uint32_t ulTaskNotifyValueClear(TaskHandle_t xTask,
1048                                 uint32_t ulBitsToClear)
1049 {
1050     BaseType_t ret_val;
1051     TX_THREAD *p_thread;
1052     txfr_task_t *p_task;
1053     TX_INTERRUPT_SAVE_AREA;
1054 
1055     if(xTask == NULL) {
1056         p_thread = tx_thread_identify();
1057         p_task = p_thread->txfr_thread_ptr;
1058     } else {
1059         p_thread = &xTask->thread;
1060         p_task = xTask;
1061     }
1062 
1063     TX_DISABLE;
1064 
1065     ret_val = p_task->task_notify_val;
1066 
1067     p_task->task_notify_val &= ~ulBitsToClear;
1068 
1069     TX_RESTORE;
1070 
1071     return ret_val;
1072 }
1073 
1074 
xSemaphoreCreateCounting(UBaseType_t uxMaxCount,UBaseType_t uxInitialCount)1075 SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount,
1076                                            UBaseType_t uxInitialCount)
1077 {
1078     txfr_sem_t *p_sem;
1079     UINT ret;
1080 
1081     configASSERT(uxMaxCount != 0u);
1082     configASSERT(uxInitialCount <= uxMaxCount);
1083 
1084 #if (TX_FREERTOS_AUTO_INIT == 1)
1085     if(txfr_initialized != 1u) {
1086         tx_freertos_auto_init();
1087     }
1088 #endif
1089 
1090     p_sem = txfr_malloc(sizeof(txfr_sem_t));
1091     if(p_sem == NULL) {
1092         return NULL;
1093     }
1094 
1095     TX_MEMSET(p_sem, 0, sizeof(*p_sem));
1096     p_sem->max_count = uxMaxCount;
1097     p_sem->allocated = 1u;
1098     p_sem->is_mutex = 0u;
1099 
1100     ret = tx_semaphore_create(&p_sem->sem, "", uxInitialCount);
1101     if(ret != TX_SUCCESS) {
1102         txfr_free(p_sem);
1103         return NULL;
1104     }
1105 
1106     return p_sem;
1107 }
1108 
xSemaphoreCreateCountingStatic(UBaseType_t uxMaxCount,UBaseType_t uxInitialCount,StaticSemaphore_t * pxSemaphoreBuffer)1109 SemaphoreHandle_t xSemaphoreCreateCountingStatic(UBaseType_t uxMaxCount,
1110                                                  UBaseType_t uxInitialCount,
1111                                                  StaticSemaphore_t *pxSemaphoreBuffer)
1112 {
1113     UINT ret;
1114 
1115     configASSERT(uxMaxCount != 0u);
1116     configASSERT(uxInitialCount <= uxMaxCount);
1117     configASSERT(pxSemaphoreBuffer != NULL);
1118 
1119 #if (TX_FREERTOS_AUTO_INIT == 1)
1120     if(txfr_initialized != 1u) {
1121         tx_freertos_auto_init();
1122     }
1123 #endif
1124 
1125     TX_MEMSET(pxSemaphoreBuffer, 0, sizeof(*pxSemaphoreBuffer));
1126     pxSemaphoreBuffer->max_count = uxMaxCount;
1127     pxSemaphoreBuffer->allocated = 0u;
1128     pxSemaphoreBuffer->is_mutex = 0u;
1129 
1130     ret = tx_semaphore_create(&pxSemaphoreBuffer->sem, "", uxInitialCount);
1131     if(ret != TX_SUCCESS) {
1132         return NULL;
1133     }
1134 
1135     return pxSemaphoreBuffer;
1136 }
1137 
1138 
xSemaphoreCreateBinary(void)1139 SemaphoreHandle_t xSemaphoreCreateBinary(void)
1140 {
1141     return xSemaphoreCreateCounting(1u, 0u);
1142 }
1143 
1144 
xSemaphoreCreateBinaryStatic(StaticSemaphore_t * pxSemaphoreBuffer)1145 SemaphoreHandle_t xSemaphoreCreateBinaryStatic(StaticSemaphore_t *pxSemaphoreBuffer)
1146 {
1147     configASSERT(pxSemaphoreBuffer != NULL);
1148 
1149     return xSemaphoreCreateCountingStatic(1u, 0u, pxSemaphoreBuffer);
1150 }
1151 
1152 
xSemaphoreCreateMutex(void)1153 SemaphoreHandle_t xSemaphoreCreateMutex(void)
1154 {
1155     txfr_sem_t *p_sem;
1156     UINT ret;
1157 
1158 #if (TX_FREERTOS_AUTO_INIT == 1)
1159     if(txfr_initialized != 1u) {
1160         tx_freertos_auto_init();
1161     }
1162 #endif
1163 
1164     p_sem = txfr_malloc(sizeof(txfr_sem_t));
1165     if(p_sem == NULL) {
1166         return NULL;
1167     }
1168 
1169     TX_MEMSET(p_sem, 0, sizeof(*p_sem));
1170     p_sem->max_count = 1u;
1171     p_sem->allocated = 1u;
1172     p_sem->is_mutex = 1u;
1173 
1174     ret = tx_mutex_create(&p_sem->mutex, "", TX_NO_INHERIT);
1175     if(ret != TX_SUCCESS) {
1176         txfr_free(p_sem);
1177         return NULL;
1178     }
1179 
1180     return p_sem;
1181 }
1182 
1183 
xSemaphoreCreateMutexStatic(StaticSemaphore_t * pxMutexBuffer)1184 SemaphoreHandle_t xSemaphoreCreateMutexStatic(StaticSemaphore_t *pxMutexBuffer)
1185 {
1186     UINT ret;
1187 
1188     configASSERT(pxMutexBuffer != NULL);
1189 
1190     TX_MEMSET(pxMutexBuffer, 0, sizeof(*pxMutexBuffer));
1191     pxMutexBuffer->max_count = 1u;
1192     pxMutexBuffer->allocated = 0u;
1193     pxMutexBuffer->is_mutex = 1u;
1194 
1195     ret = tx_mutex_create(&pxMutexBuffer->mutex, "", TX_NO_INHERIT);
1196     if(ret != TX_SUCCESS) {
1197         return NULL;
1198     }
1199 
1200     return pxMutexBuffer;
1201 }
1202 
1203 
xSemaphoreCreateRecursiveMutex(void)1204 SemaphoreHandle_t xSemaphoreCreateRecursiveMutex(void)
1205 {
1206     txfr_sem_t *p_sem;
1207     UINT ret;
1208 
1209 #if (TX_FREERTOS_AUTO_INIT == 1)
1210     if(txfr_initialized != 1u) {
1211         tx_freertos_auto_init();
1212     }
1213 #endif
1214 
1215     p_sem = txfr_malloc(sizeof(txfr_sem_t));
1216     if(p_sem == NULL) {
1217         return NULL;
1218     }
1219 
1220     TX_MEMSET(p_sem, 0, sizeof(*p_sem));
1221     p_sem->max_count = 1u;
1222     p_sem->allocated = 1u;
1223     p_sem->is_mutex = 1u;
1224 
1225     ret = tx_mutex_create(&p_sem->mutex, "", TX_INHERIT);
1226     if(ret != TX_SUCCESS) {
1227         txfr_free(p_sem);
1228         return NULL;
1229     }
1230 
1231     return p_sem;
1232 }
1233 
1234 
xSemaphoreCreateRecursiveMutexStatic(StaticSemaphore_t * pxMutexBuffer)1235 SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic(StaticSemaphore_t *pxMutexBuffer)
1236 {
1237     UINT ret;
1238 
1239     configASSERT(pxMutexBuffer != NULL);
1240 
1241 #if (TX_FREERTOS_AUTO_INIT == 1)
1242     if(txfr_initialized != 1u) {
1243         tx_freertos_auto_init();
1244     }
1245 #endif
1246 
1247     TX_MEMSET(pxMutexBuffer, 0, sizeof(*pxMutexBuffer));
1248     pxMutexBuffer->max_count = 1u;
1249     pxMutexBuffer->allocated = 0u;
1250     pxMutexBuffer->is_mutex = 1u;
1251 
1252     ret = tx_mutex_create(&pxMutexBuffer->mutex, "", TX_INHERIT);
1253     if(ret != TX_SUCCESS) {
1254         return NULL;
1255     }
1256 
1257     return pxMutexBuffer;
1258 }
1259 
vSemaphoreDelete(SemaphoreHandle_t xSemaphore)1260 void vSemaphoreDelete(SemaphoreHandle_t xSemaphore)
1261 {
1262     UINT ret;
1263 
1264     configASSERT(xSemaphore != NULL);
1265 
1266     if(xSemaphore->is_mutex == 0u) {
1267         ret = tx_semaphore_delete(&xSemaphore->sem);
1268     } else {
1269         ret = tx_mutex_delete(&xSemaphore->mutex);
1270     }
1271 
1272     if(ret != TX_SUCCESS) {
1273         TX_FREERTOS_ASSERT_FAIL();
1274         return;
1275     }
1276 
1277     if(xSemaphore->allocated == 1u) {
1278         vPortFree(xSemaphore);
1279     }
1280 }
1281 
1282 
xSemaphoreTake(SemaphoreHandle_t xSemaphore,TickType_t xTicksToWait)1283 BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait)
1284 {
1285     UINT timeout;
1286     UINT ret;
1287 
1288     configASSERT(xSemaphore != NULL);
1289 
1290     if(xTicksToWait ==  portMAX_DELAY) {
1291         timeout = TX_WAIT_FOREVER;
1292     } else {
1293         timeout = (UINT)xTicksToWait;
1294     }
1295 
1296     if(xSemaphore->is_mutex == 1u) {
1297         if(xSemaphore->mutex.tx_mutex_owner == tx_thread_identify()) {
1298             return pdFALSE;
1299         }
1300         ret = tx_mutex_get(&xSemaphore->mutex, timeout);
1301         if(ret != TX_SUCCESS) {
1302             return pdFALSE;
1303         }
1304     } else {
1305         ret = tx_semaphore_get(&xSemaphore->sem, timeout);
1306         if(ret != TX_SUCCESS) {
1307             return pdFALSE;
1308         }
1309     }
1310 
1311     return pdTRUE;
1312 }
1313 
1314 
xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore,BaseType_t * pxHigherPriorityTaskWoken)1315 BaseType_t xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore, BaseType_t *pxHigherPriorityTaskWoken)
1316 {
1317     UINT ret;
1318 
1319     configASSERT(xSemaphore != NULL);
1320 
1321     if(xSemaphore->is_mutex == 1u) {
1322         return pdFALSE;
1323     } else {
1324         ret = tx_semaphore_get(&xSemaphore->sem, 0u);
1325         if(ret != TX_SUCCESS) {
1326             return pdFALSE;
1327         }
1328     }
1329 
1330     return pdTRUE;
1331 }
1332 
1333 
xSemaphoreTakeRecursive(SemaphoreHandle_t xMutex,TickType_t xTicksToWait)1334 BaseType_t xSemaphoreTakeRecursive(SemaphoreHandle_t xMutex, TickType_t xTicksToWait)
1335 {
1336     UINT timeout;
1337     UINT ret;
1338 
1339     configASSERT(xMutex != NULL);
1340 
1341     if(xTicksToWait ==  portMAX_DELAY) {
1342         timeout = TX_WAIT_FOREVER;
1343     } else {
1344         timeout = (UINT)xTicksToWait;
1345     }
1346 
1347     if(xMutex->is_mutex == 1u) {
1348         ret = tx_mutex_get(&xMutex->mutex, timeout);
1349         if(ret != TX_SUCCESS) {
1350             return pdFALSE;
1351         }
1352     } else {
1353         ret = tx_semaphore_get(&xMutex->sem, timeout);
1354         if(ret != TX_SUCCESS) {
1355             return pdFALSE;
1356         }
1357     }
1358 
1359     return pdTRUE;
1360 }
1361 
1362 
xSemaphoreGive(SemaphoreHandle_t xSemaphore)1363 BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore)
1364 {
1365     TX_INTERRUPT_SAVE_AREA
1366     UINT ret;
1367 
1368     configASSERT(xSemaphore != NULL);
1369 
1370     if(xSemaphore->is_mutex == 1u) {
1371         ret = tx_mutex_put(&xSemaphore->mutex);
1372         if(ret != TX_SUCCESS) {
1373             return pdFALSE;
1374         }
1375 
1376       return pdTRUE;
1377     }
1378 
1379     TX_DISABLE;
1380     _tx_thread_preempt_disable++;
1381 
1382     if(xSemaphore->sem.tx_semaphore_count >= xSemaphore->max_count) {
1383         /* Maximum semaphore count reached return failure. */
1384         _tx_thread_preempt_disable--;
1385          TX_RESTORE
1386         return pdFALSE;
1387     }
1388 
1389     ret = tx_semaphore_put(&xSemaphore->sem);
1390     if(ret != TX_SUCCESS) {
1391         _tx_thread_preempt_disable--;
1392         TX_RESTORE;
1393         return pdFALSE;
1394     }
1395 
1396     if(xSemaphore->p_set != NULL) {
1397         // To prevent deadlocks don't wait when posting on a queue set.
1398         ret = tx_queue_send(&xSemaphore->p_set->queue, &xSemaphore, TX_NO_WAIT);
1399         if((ret != TX_SUCCESS) && (ret != TX_QUEUE_FULL)) {
1400             // Fatal error, queue full errors are ignored on purpose to match the original behaviour.
1401             _tx_thread_preempt_disable--;
1402             TX_RESTORE;
1403             TX_FREERTOS_ASSERT_FAIL();
1404             return pdFALSE;
1405         }
1406     }
1407 
1408     _tx_thread_preempt_disable--;
1409     TX_RESTORE;
1410 
1411     _tx_thread_system_preempt_check();
1412 
1413     return pdTRUE;
1414 }
1415 
xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore,BaseType_t * pxHigherPriorityTaskWoken)1416 BaseType_t xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore, BaseType_t *pxHigherPriorityTaskWoken)
1417 {
1418 
1419     configASSERT(xSemaphore != NULL);
1420 
1421     return xSemaphoreGive(xSemaphore);
1422 }
1423 
xSemaphoreGiveRecursive(SemaphoreHandle_t xMutex)1424 BaseType_t xSemaphoreGiveRecursive(SemaphoreHandle_t xMutex)
1425 {
1426 
1427     configASSERT(xMutex != NULL);
1428 
1429     return xSemaphoreGive(xMutex);
1430 }
1431 
uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore)1432 UBaseType_t uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore)
1433 {
1434     UINT ret;
1435     ULONG count;
1436 
1437     configASSERT(xSemaphore != NULL);
1438 
1439     ret = tx_semaphore_info_get(&xSemaphore->sem, NULL, &count, NULL, NULL, NULL);
1440     if(ret != TX_SUCCESS) {
1441         TX_FREERTOS_ASSERT_FAIL();
1442         return 0;
1443     }
1444 
1445     return count;
1446 }
1447 
xSemaphoreGetMutexHolder(SemaphoreHandle_t xMutex)1448 TaskHandle_t xSemaphoreGetMutexHolder(SemaphoreHandle_t xMutex)
1449 {
1450     configASSERT(xMutex != NULL);
1451 
1452     return xMutex->mutex.tx_mutex_owner->txfr_thread_ptr;
1453 }
1454 
1455 
xSemaphoreGetMutexHolderFromISR(SemaphoreHandle_t xMutex)1456 TaskHandle_t xSemaphoreGetMutexHolderFromISR(SemaphoreHandle_t xMutex)
1457 {
1458     return xSemaphoreGetMutexHolder(xMutex);
1459 }
1460 
1461 
xTaskGetTickCount(void)1462 TickType_t xTaskGetTickCount(void)
1463 {
1464     return tx_time_get();
1465 }
1466 
xTaskGetTickCountFromISR(void)1467 TickType_t xTaskGetTickCountFromISR(void)
1468 {
1469     return tx_time_get();
1470 }
1471 
1472 
xQueueCreateStatic(UBaseType_t uxQueueLength,UBaseType_t uxItemSize,uint8_t * pucQueueStorageBuffer,StaticQueue_t * pxQueueBuffer)1473 QueueHandle_t xQueueCreateStatic(UBaseType_t uxQueueLength,
1474                                  UBaseType_t uxItemSize,
1475                                  uint8_t *pucQueueStorageBuffer,
1476                                  StaticQueue_t *pxQueueBuffer)
1477 {
1478     UINT ret;
1479 
1480     configASSERT(uxQueueLength != 0u);
1481     configASSERT(uxItemSize >= sizeof(UINT));
1482     configASSERT(pucQueueStorageBuffer != NULL);
1483     configASSERT(pxQueueBuffer != NULL);
1484 
1485 #if (TX_FREERTOS_AUTO_INIT == 1)
1486     if(txfr_initialized != 1u) {
1487         tx_freertos_auto_init();
1488     }
1489 #endif
1490 
1491     TX_MEMSET(pucQueueStorageBuffer, 0, uxQueueLength * uxItemSize);
1492     TX_MEMSET(pxQueueBuffer, 0, sizeof(*pxQueueBuffer));
1493     pxQueueBuffer->allocated = 0u;
1494     pxQueueBuffer->p_mem = pucQueueStorageBuffer;
1495     pxQueueBuffer->id = TX_QUEUE_ID;
1496 
1497     pxQueueBuffer->p_write = (uint8_t *)pucQueueStorageBuffer;
1498     pxQueueBuffer->p_read = (uint8_t *)pucQueueStorageBuffer;
1499     pxQueueBuffer->msg_size = uxItemSize;
1500     pxQueueBuffer->queue_length = uxQueueLength;
1501 
1502     ret = tx_semaphore_create(&pxQueueBuffer->read_sem, "", 0u);
1503     if(ret != TX_SUCCESS) {
1504         return NULL;
1505     }
1506 
1507     ret = tx_semaphore_create(&pxQueueBuffer->write_sem, "", uxQueueLength);
1508     if(ret != TX_SUCCESS) {
1509         return NULL;
1510     }
1511 
1512     return pxQueueBuffer;
1513 }
1514 
1515 
xQueueCreate(UBaseType_t uxQueueLength,UBaseType_t uxItemSize)1516 QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize)
1517 {
1518     txfr_queue_t *p_queue;
1519     void *p_mem;
1520     size_t mem_size;
1521     UINT ret;
1522 
1523     configASSERT(uxQueueLength != 0u);
1524     configASSERT(uxItemSize >= sizeof(UINT));
1525 
1526 #if (TX_FREERTOS_AUTO_INIT == 1)
1527     if(txfr_initialized != 1u) {
1528         tx_freertos_auto_init();
1529     }
1530 #endif
1531 
1532     if ((uxQueueLength > (SIZE_MAX / uxItemSize)) ||
1533         (uxQueueLength > (ULONG_MAX / uxItemSize))) {
1534 
1535         /* Integer overflow in queue size */
1536         return NULL;
1537     }
1538 
1539     p_queue = txfr_malloc(sizeof(txfr_queue_t));
1540     if(p_queue == NULL) {
1541         return NULL;
1542     }
1543 
1544     mem_size = uxQueueLength*(uxItemSize);
1545 
1546     p_mem = txfr_malloc(mem_size);
1547     if(p_mem == NULL) {
1548         txfr_free(p_queue);
1549         return NULL;
1550     }
1551 
1552     TX_MEMSET(p_mem, 0, mem_size);
1553     TX_MEMSET(p_queue, 0, sizeof(*p_queue));
1554     p_queue->allocated = 1u;
1555     p_queue->p_mem = p_mem;
1556     p_queue->id = TX_QUEUE_ID;
1557 
1558     p_queue->p_write = (uint8_t *)p_mem;
1559     p_queue->p_read = (uint8_t *)p_mem;
1560     p_queue->msg_size = uxItemSize;
1561     p_queue->queue_length = uxQueueLength;
1562 
1563     ret = tx_semaphore_create(&p_queue->read_sem, "", 0u);
1564     if(ret != TX_SUCCESS) {
1565         return NULL;
1566     }
1567 
1568     ret = tx_semaphore_create(&p_queue->write_sem, "", uxQueueLength);
1569     if(ret != TX_SUCCESS) {
1570         return NULL;
1571     }
1572 
1573     return p_queue;
1574 }
1575 
vQueueDelete(QueueHandle_t xQueue)1576 void vQueueDelete(QueueHandle_t xQueue)
1577 {
1578     UINT ret;
1579 
1580     configASSERT(xQueue != NULL);
1581 
1582     ret = tx_semaphore_delete(&xQueue->read_sem);
1583     if(ret != TX_SUCCESS) {
1584         TX_FREERTOS_ASSERT_FAIL();
1585     }
1586 
1587     ret = tx_semaphore_delete(&xQueue->write_sem);
1588     if(ret != TX_SUCCESS) {
1589         TX_FREERTOS_ASSERT_FAIL();
1590     }
1591 
1592     if(xQueue->allocated == 1u) {
1593         vPortFree(xQueue->p_mem);
1594         vPortFree(xQueue);
1595     }
1596 }
1597 
xQueueSend(QueueHandle_t xQueue,const void * pvItemToQueue,TickType_t xTicksToWait)1598 BaseType_t xQueueSend(QueueHandle_t xQueue,
1599                       const void *pvItemToQueue,
1600                       TickType_t xTicksToWait)
1601 {
1602     TX_INTERRUPT_SAVE_AREA;
1603     UINT timeout;
1604     UINT ret;
1605 
1606     configASSERT(xQueue != NULL);
1607     configASSERT(pvItemToQueue != NULL);
1608 
1609     if(xTicksToWait ==  portMAX_DELAY) {
1610         timeout = TX_WAIT_FOREVER;
1611     } else {
1612         timeout = (UINT)xTicksToWait;
1613     }
1614 
1615     // Wait for space to be available on the queue.
1616     ret = tx_semaphore_get(&xQueue->write_sem, timeout);
1617     if(ret != TX_SUCCESS) {
1618         return pdFALSE;
1619     }
1620 
1621     // Enqueue the message.
1622     TX_DISABLE;
1623     memcpy(xQueue->p_write, pvItemToQueue, xQueue->msg_size);
1624     if(xQueue->p_write >= (xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u)))) {
1625         xQueue->p_write = xQueue->p_mem;
1626     } else {
1627         xQueue->p_write += xQueue->msg_size;
1628     }
1629     TX_RESTORE;
1630 
1631     // Signal that there is an additional message available on the queue.
1632     ret = tx_semaphore_put(&xQueue->read_sem);
1633     if(ret != TX_SUCCESS) {
1634         TX_FREERTOS_ASSERT_FAIL();
1635         return pdFALSE;
1636     }
1637 
1638     if(xQueue->p_set != NULL) {
1639         // To prevent deadlocks don't wait when posting on a queue set.
1640         ret = tx_queue_send(&xQueue->p_set->queue, &xQueue, TX_NO_WAIT);
1641         if((ret != TX_SUCCESS) && (ret != TX_QUEUE_FULL)) {
1642             // Fatal error, queue full errors are ignored on purpose to match the original behaviour.
1643             TX_FREERTOS_ASSERT_FAIL();
1644             return pdFALSE;
1645         }
1646 
1647     }
1648 
1649     return pdPASS;
1650 }
1651 
xQueueSendFromISR(QueueHandle_t xQueue,const void * pvItemToQueue,BaseType_t * pxHigherPriorityTaskWoken)1652 BaseType_t xQueueSendFromISR(QueueHandle_t xQueue,
1653                              const void * pvItemToQueue,
1654                              BaseType_t *pxHigherPriorityTaskWoken)
1655 {
1656     configASSERT(xQueue != NULL);
1657     configASSERT(pvItemToQueue != NULL);
1658 
1659     return xQueueSend(xQueue, pvItemToQueue, 0u);
1660 }
1661 
xQueueSendToBack(QueueHandle_t xQueue,const void * pvItemToQueue,TickType_t xTicksToWait)1662 BaseType_t xQueueSendToBack(QueueHandle_t xQueue,
1663                             const void * pvItemToQueue,
1664                             TickType_t xTicksToWait)
1665 {
1666     configASSERT(xQueue != NULL);
1667     configASSERT(pvItemToQueue != NULL);
1668 
1669     return xQueueSend(xQueue, pvItemToQueue, xTicksToWait);
1670 }
1671 
xQueueSendToBackFromISR(QueueHandle_t xQueue,const void * pvItemToQueue,BaseType_t * pxHigherPriorityTaskWoken)1672 BaseType_t xQueueSendToBackFromISR(QueueHandle_t xQueue,
1673                              const void * pvItemToQueue,
1674                              BaseType_t *pxHigherPriorityTaskWoken)
1675 {
1676     configASSERT(xQueue != NULL);
1677     configASSERT(pvItemToQueue != NULL);
1678 
1679     return xQueueSend(xQueue, pvItemToQueue, 0u);
1680 }
1681 
xQueueSendToFront(QueueHandle_t xQueue,const void * pvItemToQueue,TickType_t xTicksToWait)1682 BaseType_t xQueueSendToFront(QueueHandle_t xQueue,
1683                              const void *pvItemToQueue,
1684                              TickType_t xTicksToWait)
1685 {
1686     TX_INTERRUPT_SAVE_AREA;
1687     UINT timeout;
1688     UINT ret;
1689     // TODO-
1690 
1691     configASSERT(xQueue != NULL);
1692     configASSERT(pvItemToQueue != NULL);
1693 
1694     if(xTicksToWait ==  portMAX_DELAY) {
1695         timeout = TX_WAIT_FOREVER;
1696     } else {
1697         timeout = (UINT)xTicksToWait;
1698     }
1699 
1700     if(xQueue->p_set != NULL) {
1701         TX_DISABLE;
1702         _tx_thread_preempt_disable++;
1703     }
1704 
1705     // Wait for space to be available on the queue.
1706     ret = tx_semaphore_get(&xQueue->write_sem, timeout);
1707     if(ret != TX_SUCCESS) {
1708         return pdFALSE;
1709     }
1710 
1711     // Enqueue the message at the front.
1712     TX_DISABLE;
1713     // Push back the read pointer.
1714     if(xQueue->p_read == xQueue->p_mem) {
1715         xQueue->p_read = xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u));
1716     } else {
1717         xQueue->p_read -= xQueue->msg_size;
1718     }
1719 
1720     memcpy(xQueue->p_read, pvItemToQueue, xQueue->msg_size);
1721     TX_RESTORE;
1722 
1723     // Signal that there is an additional message available on the queue.
1724     ret = tx_semaphore_put(&xQueue->read_sem);
1725     if(ret != TX_SUCCESS) {
1726         if(xQueue->p_set != NULL) {
1727             _tx_thread_preempt_disable--;
1728             TX_RESTORE;
1729         }
1730         TX_FREERTOS_ASSERT_FAIL();
1731         return pdFALSE;
1732     }
1733 
1734     if(xQueue->p_set != NULL) {
1735         // To prevent deadlocks don't wait when posting on a queue set.
1736         ret = tx_queue_send(&xQueue->p_set->queue, &xQueue, TX_NO_WAIT);
1737         if((ret != TX_SUCCESS) && (ret != TX_QUEUE_FULL)) {
1738             // Fatal error, queue full errors are ignored on purpose to match the original behaviour.
1739             _tx_thread_preempt_disable--;
1740             TX_RESTORE;
1741             TX_FREERTOS_ASSERT_FAIL();
1742             return pdFALSE;
1743         }
1744 
1745         TX_RESTORE;
1746         _tx_thread_preempt_disable--;
1747 
1748         _tx_thread_system_preempt_check();
1749     }
1750 
1751     return pdPASS;
1752 }
1753 
xQueueSendToFrontFromISR(QueueHandle_t xQueue,const void * pvItemToQueue,BaseType_t * pxHigherPriorityTaskWoken)1754 BaseType_t xQueueSendToFrontFromISR(QueueHandle_t xQueue,
1755                              const void * pvItemToQueue,
1756                              BaseType_t *pxHigherPriorityTaskWoken)
1757 {
1758     configASSERT(xQueue != NULL);
1759     configASSERT(pvItemToQueue != NULL);
1760 
1761     return xQueueSendToFront(xQueue, pvItemToQueue, 0u);
1762 }
1763 
xQueueReceive(QueueHandle_t xQueue,void * pvBuffer,TickType_t xTicksToWait)1764 BaseType_t xQueueReceive(QueueHandle_t xQueue,
1765                          void *pvBuffer,
1766                          TickType_t xTicksToWait)
1767 {
1768     TX_INTERRUPT_SAVE_AREA;
1769     UINT timeout;
1770     UINT ret;
1771 
1772     configASSERT(xQueue != NULL);
1773     configASSERT(pvBuffer != NULL);
1774 
1775     if(xTicksToWait == portMAX_DELAY) {
1776         timeout = TX_WAIT_FOREVER;
1777     } else {
1778         timeout = (UINT)xTicksToWait;
1779     }
1780 
1781     // Wait for a message to be available on the queue.
1782     ret = tx_semaphore_get(&xQueue->read_sem, timeout);
1783     if(ret != TX_SUCCESS) {
1784         return pdFAIL;
1785     }
1786 
1787     // Retrieve the message.
1788     TX_DISABLE
1789     memcpy(pvBuffer, xQueue->p_read, xQueue->msg_size);
1790     if(xQueue->p_read >= (xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u)))) {
1791         xQueue->p_read = xQueue->p_mem;
1792     } else {
1793         xQueue->p_read += xQueue->msg_size;
1794     }
1795     TX_RESTORE
1796 
1797     // Signal that there's additional space available on the queue.
1798     ret = tx_semaphore_put(&xQueue->write_sem);
1799     if(ret != TX_SUCCESS) {
1800         TX_FREERTOS_ASSERT_FAIL();
1801         return pdFALSE;
1802     }
1803 
1804     return pdPASS;
1805 }
1806 
xQueueReceiveFromISR(QueueHandle_t xQueue,void * pvBuffer,BaseType_t * pxHigherPriorityTaskWoken)1807 BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue,
1808                                 void *pvBuffer,
1809                                 BaseType_t *pxHigherPriorityTaskWoken)
1810 {
1811     BaseType_t ret;
1812 
1813     configASSERT(xQueue != NULL);
1814     configASSERT(pvBuffer != NULL);
1815 
1816     ret = xQueueReceive(xQueue, pvBuffer, 0u);
1817 
1818     return ret;
1819 }
1820 
xQueuePeek(QueueHandle_t xQueue,void * pvBuffer,TickType_t xTicksToWait)1821 BaseType_t xQueuePeek(QueueHandle_t xQueue,
1822                       void *pvBuffer,
1823                       TickType_t xTicksToWait)
1824 {
1825     TX_INTERRUPT_SAVE_AREA;
1826     UINT timeout;
1827     UINT ret;
1828 
1829     configASSERT(xQueue != NULL);
1830     configASSERT(pvBuffer != NULL);
1831 
1832     if(xTicksToWait ==  portMAX_DELAY) {
1833         timeout = TX_WAIT_FOREVER;
1834     } else {
1835         timeout = (UINT)xTicksToWait;
1836     }
1837 
1838     // Wait for a message to be available on the queue.
1839     ret = tx_semaphore_get(&xQueue->read_sem, timeout);
1840     if(ret != TX_SUCCESS) {
1841         return pdFAIL;
1842     }
1843 
1844     // Retrieve the message.
1845     TX_DISABLE;
1846     _tx_thread_preempt_disable++;
1847 
1848     memcpy(pvBuffer, xQueue->p_read, xQueue->msg_size);
1849 
1850     // Restore the original space on the queue.
1851     ret = tx_semaphore_put(&xQueue->read_sem);
1852     if(ret != TX_SUCCESS) {
1853         TX_FREERTOS_ASSERT_FAIL();
1854         return pdFALSE;
1855     }
1856 
1857     _tx_thread_preempt_disable--;
1858     TX_RESTORE;
1859 
1860     return pdPASS;
1861 }
1862 
xQueuePeekFromISR(QueueHandle_t xQueue,void * pvBuffer)1863 BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue,
1864                              void *pvBuffer)
1865 {
1866     configASSERT(xQueue != NULL);
1867     configASSERT(pvBuffer != NULL);
1868 
1869     return xQueuePeek(xQueue, pvBuffer, 0u);
1870 }
1871 
uxQueueMessagesWaiting(QueueHandle_t xQueue)1872 UBaseType_t uxQueueMessagesWaiting(QueueHandle_t xQueue)
1873 {
1874     ULONG count;
1875     UINT ret;
1876 
1877     configASSERT(xQueue != NULL);
1878 
1879     ret = tx_semaphore_info_get(&xQueue->read_sem, NULL, &count, NULL, NULL, NULL);
1880     if(ret != TX_SUCCESS) {
1881         TX_FREERTOS_ASSERT_FAIL();
1882         return 0;
1883     }
1884 
1885     return count;
1886 }
1887 
uxQueueMessagesWaitingFromISR(QueueHandle_t xQueue)1888 UBaseType_t uxQueueMessagesWaitingFromISR(QueueHandle_t xQueue)
1889 {
1890     configASSERT(xQueue != NULL);
1891 
1892     return uxQueueMessagesWaiting(xQueue);
1893 }
1894 
uxQueueSpacesAvailable(QueueHandle_t xQueue)1895 UBaseType_t uxQueueSpacesAvailable(QueueHandle_t xQueue)
1896 {
1897     ULONG count;
1898     UINT ret;
1899 
1900     configASSERT(xQueue != NULL);
1901 
1902     ret = tx_semaphore_info_get(&xQueue->write_sem, NULL, &count, NULL, NULL, NULL);
1903     if(ret != TX_SUCCESS) {
1904         TX_FREERTOS_ASSERT_FAIL();
1905         return 0;
1906     }
1907 
1908     return count;
1909 }
1910 
xQueueIsQueueEmptyFromISR(const QueueHandle_t xQueue)1911 BaseType_t xQueueIsQueueEmptyFromISR(const QueueHandle_t xQueue)
1912 {
1913     ULONG count;
1914     UINT ret;
1915 
1916     configASSERT(xQueue != NULL);
1917 
1918     ret = tx_semaphore_info_get(&xQueue->read_sem, NULL, &count, NULL, NULL, NULL);
1919     if(ret != TX_SUCCESS) {
1920         TX_FREERTOS_ASSERT_FAIL();
1921         return 0;
1922     }
1923 
1924     if(count == 0u) {
1925         return pdTRUE;
1926     } else {
1927         return pdFALSE;
1928     }
1929 }
1930 
xQueueIsQueueFullFromISR(const QueueHandle_t xQueue)1931 BaseType_t xQueueIsQueueFullFromISR(const QueueHandle_t xQueue)
1932 {
1933     ULONG count;
1934     UINT ret;
1935 
1936     configASSERT(xQueue != NULL);
1937 
1938     ret = tx_semaphore_info_get(&xQueue->write_sem, NULL, &count, NULL, NULL, NULL);
1939     if(ret != TX_SUCCESS) {
1940         TX_FREERTOS_ASSERT_FAIL();
1941         return 0;
1942     }
1943 
1944     if(count == 0u) {
1945         return pdTRUE;
1946     } else {
1947         return pdFALSE;
1948     }
1949 }
1950 
1951 
xQueueReset(QueueHandle_t xQueue)1952 BaseType_t xQueueReset(QueueHandle_t xQueue)
1953 {
1954     TX_INTERRUPT_SAVE_AREA;
1955     UINT ret;
1956     UINT write_post;
1957 
1958     configASSERT(xQueue != NULL);
1959 
1960     write_post = 0u;
1961     TX_DISABLE;
1962     _tx_thread_preempt_disable++;
1963 
1964     // Reset pointers.
1965     xQueue->p_write = xQueue->p_mem;
1966     xQueue->p_read = xQueue->p_mem;
1967 
1968     // Reset read semaphore.
1969     xQueue->read_sem.tx_semaphore_count = 0u;
1970 
1971     // Reset write semaphore.
1972     if(xQueue->write_sem.tx_semaphore_count != xQueue->queue_length) {
1973         write_post = 1u;
1974         xQueue->write_sem.tx_semaphore_count = xQueue->queue_length - 1u;
1975     }
1976 
1977     _tx_thread_preempt_disable--;
1978     TX_RESTORE;
1979 
1980     if(write_post == 1u) {
1981         // Signal that there's space available on the queue in case a writer was waiting before the reset.
1982         ret = tx_semaphore_put(&xQueue->write_sem);
1983         if(ret != TX_SUCCESS) {
1984             TX_FREERTOS_ASSERT_FAIL();
1985             return pdFALSE;
1986         }
1987     } else {
1988         _tx_thread_system_preempt_check();
1989     }
1990 
1991     return pdPASS;
1992 }
1993 
1994 
xQueueOverwrite(QueueHandle_t xQueue,const void * pvItemToQueue)1995 BaseType_t xQueueOverwrite(QueueHandle_t xQueue,
1996                            const void * pvItemToQueue)
1997 {
1998     TX_INTERRUPT_SAVE_AREA;
1999     UINT ret;
2000     UINT read_post;
2001     uint8_t *p_write_temp;
2002 
2003     configASSERT(xQueue != NULL);
2004     configASSERT(pvItemToQueue != NULL);
2005 
2006     read_post = 0u;
2007     TX_DISABLE;
2008 
2009     if(xQueue->read_sem.tx_semaphore_count != 0u) {
2010         // Go back one message.
2011         p_write_temp = xQueue->p_write;
2012         if(p_write_temp == xQueue->p_mem) {
2013             p_write_temp = (xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u)));
2014         } else {
2015             p_write_temp -= xQueue->msg_size;
2016         }
2017 
2018         memcpy(p_write_temp, pvItemToQueue, xQueue->msg_size);
2019     } else {
2020         memcpy(xQueue->p_write, pvItemToQueue, xQueue->msg_size);
2021         if(xQueue->p_write >= (xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u)))) {
2022             xQueue->p_write = xQueue->p_mem;
2023         } else {
2024             xQueue->p_write += xQueue->msg_size;
2025         }
2026         read_post = 1u;
2027     }
2028 
2029     TX_RESTORE;
2030 
2031     if(read_post == 1u) {
2032         // Signal that there is an additional message available on the queue.
2033         ret = tx_semaphore_put(&xQueue->read_sem);
2034         if(ret != TX_SUCCESS) {
2035             TX_FREERTOS_ASSERT_FAIL();
2036             return pdFALSE;
2037         }
2038     }
2039 
2040     return pdPASS;
2041 }
2042 
2043 
xQueueOverwriteFromISR(QueueHandle_t xQueue,const void * pvItemToQueue,BaseType_t * pxHigherPriorityTaskWoken)2044 BaseType_t xQueueOverwriteFromISR(QueueHandle_t xQueue,
2045                                   const void * pvItemToQueue,
2046                                   BaseType_t *pxHigherPriorityTaskWoken)
2047 {
2048     configASSERT(xQueue != NULL);
2049     configASSERT(pvItemToQueue != NULL);
2050 
2051     return xQueueOverwrite(xQueue, pvItemToQueue);
2052 }
2053 
2054 
xEventGroupCreate(void)2055 EventGroupHandle_t xEventGroupCreate(void)
2056 {
2057     txfr_event_t *p_event;
2058     UINT ret;
2059 
2060 #if (TX_FREERTOS_AUTO_INIT == 1)
2061     if(txfr_initialized != 1u) {
2062         tx_freertos_auto_init();
2063     }
2064 #endif
2065 
2066     p_event = txfr_malloc(sizeof(txfr_event_t));
2067     if(p_event == NULL) {
2068         return NULL;
2069     }
2070 
2071     TX_MEMSET(p_event, 0, sizeof(*p_event));
2072     p_event->allocated = 1u;
2073 
2074     ret = tx_event_flags_create(&p_event->event, "");
2075     if(ret != TX_SUCCESS) {
2076         txfr_free(p_event);
2077         return NULL;
2078     }
2079 
2080     return p_event;
2081 }
2082 
xEventGroupCreateStatic(StaticEventGroup_t * pxEventGroupBuffer)2083 EventGroupHandle_t xEventGroupCreateStatic(StaticEventGroup_t *pxEventGroupBuffer)
2084 {
2085     UINT ret;
2086 
2087     configASSERT(pxEventGroupBuffer != NULL);
2088 
2089 #if (TX_FREERTOS_AUTO_INIT == 1)
2090     if(txfr_initialized != 1u) {
2091         tx_freertos_auto_init();
2092     }
2093 #endif
2094 
2095     TX_MEMSET(pxEventGroupBuffer, 0, sizeof(*pxEventGroupBuffer));
2096     pxEventGroupBuffer->allocated = 0u;
2097 
2098     ret = tx_event_flags_create(&pxEventGroupBuffer->event, "");
2099     if(ret != TX_SUCCESS) {
2100         return NULL;
2101     }
2102 
2103     return pxEventGroupBuffer;
2104 }
2105 
vEventGroupDelete(EventGroupHandle_t xEventGroup)2106 void vEventGroupDelete(EventGroupHandle_t xEventGroup)
2107 {
2108     UINT ret;
2109 
2110     configASSERT(xEventGroup != NULL);
2111 
2112     ret = tx_event_flags_delete(&xEventGroup->event);
2113     if(ret != TX_SUCCESS) {
2114         TX_FREERTOS_ASSERT_FAIL();
2115         return;
2116     }
2117 
2118     if(xEventGroup->allocated == 1u) {
2119         vPortFree(xEventGroup);
2120     }
2121 }
2122 
xEventGroupWaitBits(const EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToWaitFor,const BaseType_t xClearOnExit,const BaseType_t xWaitForAllBits,TickType_t xTicksToWait)2123 EventBits_t xEventGroupWaitBits(const EventGroupHandle_t xEventGroup,
2124                                 const EventBits_t uxBitsToWaitFor,
2125                                 const BaseType_t xClearOnExit,
2126                                 const BaseType_t xWaitForAllBits,
2127                                 TickType_t xTicksToWait)
2128 {
2129     ULONG bits;
2130     UINT timeout;
2131     UINT ret;
2132     UINT get_option;
2133 
2134     configASSERT(xEventGroup != NULL);
2135 
2136     if(xTicksToWait == portMAX_DELAY) {
2137         timeout = TX_WAIT_FOREVER;
2138     } else {
2139         timeout = (UINT)xTicksToWait;
2140     }
2141 
2142     if(xWaitForAllBits == pdFALSE) {
2143         if(xClearOnExit == pdFALSE) {
2144             get_option = TX_OR;
2145         } else {
2146             get_option = TX_OR_CLEAR;
2147         }
2148     } else {
2149         if(xClearOnExit == pdFALSE) {
2150             get_option = TX_AND;
2151         } else {
2152             get_option = TX_AND_CLEAR;
2153         }
2154     }
2155 
2156     ret = tx_event_flags_get(&xEventGroup->event, uxBitsToWaitFor, get_option, &bits, timeout);
2157     if(ret != TX_SUCCESS) {
2158         return 0;
2159     }
2160 
2161     return bits;
2162 }
2163 
xEventGroupSetBits(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet)2164 EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup,
2165                                const EventBits_t uxBitsToSet)
2166 {
2167     UINT ret;
2168     ULONG bits;
2169 
2170     configASSERT(xEventGroup != NULL);
2171 
2172     ret = tx_event_flags_set(&xEventGroup->event, uxBitsToSet, TX_OR);
2173     if(ret != TX_SUCCESS) {
2174         TX_FREERTOS_ASSERT_FAIL();
2175         return 0u;
2176     }
2177 
2178     ret = tx_event_flags_info_get(&xEventGroup->event, NULL, &bits, NULL, NULL, NULL);
2179     if(ret != TX_SUCCESS) {
2180         TX_FREERTOS_ASSERT_FAIL();
2181         return 0u;
2182     }
2183 
2184     return bits;
2185 }
2186 
xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet,BaseType_t * pxHigherPriorityTaskWoken)2187 BaseType_t xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,
2188                                      const EventBits_t uxBitsToSet,
2189                                      BaseType_t *pxHigherPriorityTaskWoken)
2190 {
2191     configASSERT(xEventGroup != NULL);
2192 
2193     return xEventGroupSetBits(xEventGroup, uxBitsToSet);
2194 }
2195 
xEventGroupClearBits(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToClear)2196 EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup,
2197                                  const EventBits_t uxBitsToClear)
2198 {
2199     UINT ret;
2200     ULONG bits;
2201     ULONG bits_before;
2202     TX_INTERRUPT_SAVE_AREA;
2203 
2204     configASSERT(xEventGroup != NULL);
2205 
2206     TX_DISABLE;
2207 
2208     ret = tx_event_flags_info_get(&xEventGroup->event, NULL, &bits_before, NULL, NULL, NULL);
2209     if(ret != TX_SUCCESS) {
2210         TX_RESTORE;
2211         TX_FREERTOS_ASSERT_FAIL();
2212         return 0u;
2213     }
2214 
2215     bits = uxBitsToClear;
2216     ret = tx_event_flags_set(&xEventGroup->event, ~bits, TX_AND);
2217     if(ret != TX_SUCCESS) {
2218         TX_RESTORE;
2219         TX_FREERTOS_ASSERT_FAIL();
2220         return 0u;
2221     }
2222 
2223     TX_RESTORE;
2224 
2225     return bits_before;
2226 }
2227 
xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToClear)2228 BaseType_t xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup,
2229                                        const EventBits_t uxBitsToClear)
2230 {
2231     configASSERT(xEventGroup != NULL);
2232 
2233     return xEventGroupClearBits(xEventGroup, uxBitsToClear);
2234 }
2235 
xEventGroupGetBits(EventGroupHandle_t xEventGroup)2236 EventBits_t xEventGroupGetBits(EventGroupHandle_t xEventGroup)
2237 {
2238     UINT ret;
2239     ULONG bits;
2240 
2241     configASSERT(xEventGroup != NULL);
2242 
2243     ret = tx_event_flags_info_get(&xEventGroup->event, NULL, &bits, NULL, NULL, NULL);
2244     if(ret != TX_SUCCESS) {
2245         TX_FREERTOS_ASSERT_FAIL();
2246         return 0u;
2247     }
2248 
2249     return bits;
2250 }
2251 
2252 
xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup)2253 EventBits_t xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup)
2254 {
2255     configASSERT(xEventGroup != NULL);
2256 
2257     return xEventGroupGetBits(xEventGroup);
2258 }
2259 
2260 
txfr_timer_callback_wrapper(ULONG id)2261 void txfr_timer_callback_wrapper(ULONG id)
2262 {
2263     txfr_timer_t *p_timer;
2264 
2265     p_timer = (txfr_timer_t *)id;
2266 
2267     if(p_timer == NULL) {
2268         TX_FREERTOS_ASSERT_FAIL();
2269     }
2270 
2271     p_timer->callback(p_timer);
2272 }
2273 
2274 
xTimerCreate(const char * const pcTimerName,const TickType_t xTimerPeriod,const UBaseType_t uxAutoReload,void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction)2275 TimerHandle_t xTimerCreate(const char * const pcTimerName,
2276                            const TickType_t xTimerPeriod,
2277                            const UBaseType_t uxAutoReload,
2278                            void * const pvTimerID,
2279                            TimerCallbackFunction_t pxCallbackFunction)
2280 {
2281     txfr_timer_t *p_timer;
2282     UINT ret;
2283     ULONG resch_ticks;
2284 
2285     configASSERT(xTimerPeriod != 0u);
2286     configASSERT(pxCallbackFunction != NULL);
2287 
2288 #if (TX_FREERTOS_AUTO_INIT == 1)
2289     if(txfr_initialized != 1u) {
2290         tx_freertos_auto_init();
2291     }
2292 #endif
2293 
2294     p_timer = txfr_malloc(sizeof(txfr_timer_t));
2295     if(p_timer == NULL) {
2296         return NULL;
2297     }
2298 
2299     TX_MEMSET(p_timer, 0, sizeof(*p_timer));
2300     p_timer->allocated = 1u;
2301     p_timer->period = xTimerPeriod;
2302     p_timer->id = pvTimerID;
2303     p_timer->callback = pxCallbackFunction;
2304 
2305     if(uxAutoReload != pdFALSE) {
2306         resch_ticks = xTimerPeriod;
2307         p_timer->one_shot = 1u;
2308     } else {
2309         p_timer->one_shot = 0u;
2310         resch_ticks = 0u;
2311     }
2312 
2313     ret = tx_timer_create(&p_timer->timer, (char *)pcTimerName, txfr_timer_callback_wrapper, (ULONG)p_timer, xTimerPeriod, resch_ticks, TX_NO_ACTIVATE);
2314     if(ret != TX_SUCCESS) {
2315         txfr_free(p_timer);
2316         return NULL;
2317     }
2318 
2319     return p_timer;
2320 }
2321 
xTimerCreateStatic(const char * const pcTimerName,const TickType_t xTimerPeriod,const UBaseType_t uxAutoReload,void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction,StaticTimer_t * pxTimerBuffer)2322 TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
2323                                  const TickType_t xTimerPeriod,
2324                                  const UBaseType_t uxAutoReload,
2325                                  void * const pvTimerID,
2326                                  TimerCallbackFunction_t pxCallbackFunction,
2327                                  StaticTimer_t *pxTimerBuffer)
2328 {
2329     UINT ret;
2330     ULONG resch_ticks;
2331 
2332     configASSERT(xTimerPeriod != 0u);
2333     configASSERT(pxCallbackFunction != NULL);
2334     configASSERT(pxTimerBuffer != NULL);
2335 
2336 #if (TX_FREERTOS_AUTO_INIT == 1)
2337     if(txfr_initialized != 1u) {
2338         tx_freertos_auto_init();
2339     }
2340 #endif
2341 
2342     TX_MEMSET(pxTimerBuffer, 0, sizeof(*pxTimerBuffer));
2343     pxTimerBuffer->allocated = 0u;
2344     pxTimerBuffer->period = xTimerPeriod;
2345     pxTimerBuffer->id = pvTimerID;
2346     pxTimerBuffer->callback = pxCallbackFunction;
2347 
2348     if(uxAutoReload != pdFALSE) {
2349         resch_ticks = xTimerPeriod;
2350     } else {
2351         resch_ticks = 0u;
2352     }
2353 
2354     ret = tx_timer_create(&pxTimerBuffer->timer, (char *)pcTimerName, txfr_timer_callback_wrapper, (ULONG)pxTimerBuffer, xTimerPeriod, resch_ticks, TX_NO_ACTIVATE);
2355     if(ret != TX_SUCCESS) {
2356         return NULL;
2357     }
2358 
2359     return pxTimerBuffer;
2360 }
2361 
2362 
xTimerDelete(TimerHandle_t xTimer,TickType_t xBlockTime)2363 BaseType_t xTimerDelete(TimerHandle_t xTimer, TickType_t xBlockTime)
2364 {
2365     UINT ret;
2366 
2367     configASSERT(xTimer != NULL);
2368 
2369     ret = tx_timer_delete(&xTimer->timer);
2370     if(ret != TX_SUCCESS) {
2371         TX_FREERTOS_ASSERT_FAIL();
2372         return pdFAIL;
2373     }
2374 
2375     if(xTimer->allocated == 1u) {
2376         vPortFree(xTimer);
2377     }
2378 
2379     return pdPASS;
2380 }
2381 
2382 
xTimerIsTimerActive(TimerHandle_t xTimer)2383 BaseType_t xTimerIsTimerActive(TimerHandle_t xTimer)
2384 {
2385     UINT ret;
2386     UINT is_active;
2387 
2388     configASSERT(xTimer != NULL);
2389 
2390     ret = tx_timer_info_get(&xTimer->timer, NULL, &is_active, NULL, NULL, NULL);
2391     if(ret !=  TX_SUCCESS) {
2392         return pdFALSE;
2393     }
2394 
2395     if(is_active == TX_TRUE) {
2396         return pdTRUE;
2397     } else {
2398         return pdFALSE;
2399     }
2400 }
2401 
2402 
xTimerStart(TimerHandle_t xTimer,TickType_t xBlockTime)2403 BaseType_t xTimerStart(TimerHandle_t xTimer,
2404                        TickType_t xBlockTime)
2405 {
2406     UINT ret;
2407 
2408     configASSERT(xTimer != NULL);
2409 
2410     ret = tx_timer_activate(&xTimer->timer);
2411     if(ret != TX_SUCCESS) {
2412         return pdFAIL;
2413     }
2414 
2415     return pdPASS;
2416 }
2417 
2418 
xTimerStop(TimerHandle_t xTimer,TickType_t xBlockTime)2419 BaseType_t xTimerStop(TimerHandle_t xTimer,
2420                       TickType_t xBlockTime)
2421 {
2422     UINT ret;
2423 
2424     configASSERT(xTimer != NULL);
2425 
2426     ret = tx_timer_deactivate(&xTimer->timer);
2427     if(ret != TX_SUCCESS) {
2428         return pdFAIL;
2429     }
2430 
2431     return pdPASS;
2432 }
2433 
2434 
xTimerChangePeriod(TimerHandle_t xTimer,TickType_t xNewPeriod,TickType_t xBlockTime)2435 BaseType_t xTimerChangePeriod(TimerHandle_t xTimer,
2436                               TickType_t xNewPeriod,
2437                               TickType_t xBlockTime)
2438 {
2439     UINT ret;
2440     TX_INTERRUPT_SAVE_AREA;
2441 
2442     configASSERT(xTimer != NULL);
2443     configASSERT(xNewPeriod != 0u);
2444 
2445     TX_DISABLE;
2446 
2447     ret = tx_timer_deactivate(&xTimer->timer);
2448     if(ret != TX_SUCCESS) {
2449         TX_RESTORE;
2450         return pdFAIL;
2451     }
2452 
2453     if(xTimer->one_shot != 0u) {
2454         ret = tx_timer_change(&xTimer->timer, xNewPeriod, xNewPeriod);
2455     } else {
2456         ret = tx_timer_change(&xTimer->timer, xNewPeriod, 0u);
2457     }
2458     if(ret != TX_SUCCESS) {
2459         TX_RESTORE;
2460         return pdFAIL;
2461     }
2462 
2463     ret = tx_timer_activate(&xTimer->timer);
2464     if(ret != TX_SUCCESS) {
2465         TX_RESTORE;
2466         return pdFAIL;
2467     }
2468 
2469     TX_RESTORE;
2470 
2471     return pdPASS;
2472 }
2473 
2474 
xTimerReset(TimerHandle_t xTimer,TickType_t xBlockTime)2475 BaseType_t xTimerReset(TimerHandle_t xTimer,
2476                        TickType_t xBlockTime)
2477 {
2478     UINT ret;
2479     TX_INTERRUPT_SAVE_AREA;
2480 
2481     configASSERT(xTimer != NULL);
2482 
2483     TX_DISABLE;
2484 
2485     ret = tx_timer_deactivate(&xTimer->timer);
2486     if(ret != TX_SUCCESS) {
2487         TX_RESTORE;
2488         return pdFAIL;
2489     }
2490 
2491     if(xTimer->one_shot != 0u) {
2492         ret = tx_timer_change(&xTimer->timer, xTimer->period, xTimer->period);
2493     } else {
2494         ret = tx_timer_change(&xTimer->timer, xTimer->period, 0u);
2495     }
2496     if(ret != TX_SUCCESS) {
2497         TX_RESTORE;
2498         return pdFAIL;
2499     }
2500 
2501     ret = tx_timer_activate(&xTimer->timer);
2502     if(ret != TX_SUCCESS) {
2503         TX_RESTORE;
2504         return pdFAIL;
2505     }
2506 
2507     TX_RESTORE;
2508 
2509     return pdPASS;
2510 }
2511 
2512 
xTimerStartFromISR(TimerHandle_t xTimer,BaseType_t * pxHigherPriorityTaskWoken)2513 BaseType_t xTimerStartFromISR(TimerHandle_t xTimer,
2514                               BaseType_t *pxHigherPriorityTaskWoken)
2515 {
2516     configASSERT(xTimer != NULL);
2517 
2518     return xTimerStart(xTimer, 0u);
2519 }
2520 
2521 
xTimerStopFromISR(TimerHandle_t xTimer,BaseType_t * pxHigherPriorityTaskWoken)2522 BaseType_t xTimerStopFromISR(TimerHandle_t xTimer,
2523                              BaseType_t *pxHigherPriorityTaskWoken)
2524 {
2525     configASSERT(xTimer != NULL);
2526 
2527     return xTimerStop(xTimer, 0u);
2528 }
2529 
2530 
xTimerChangePeriodFromISR(TimerHandle_t xTimer,TickType_t xNewPeriod,BaseType_t * pxHigherPriorityTaskWoken)2531 BaseType_t xTimerChangePeriodFromISR(TimerHandle_t xTimer,
2532                                      TickType_t xNewPeriod,
2533                                      BaseType_t *pxHigherPriorityTaskWoken)
2534 {
2535     configASSERT(xTimer != NULL);
2536     configASSERT(xNewPeriod != 0u);
2537 
2538     return xTimerChangePeriod(xTimer, xNewPeriod, 0u);
2539 }
2540 
2541 
xTimerResetFromISR(TimerHandle_t xTimer,BaseType_t * pxHigherPriorityTaskWoken)2542 BaseType_t xTimerResetFromISR(TimerHandle_t xTimer,
2543                               BaseType_t *pxHigherPriorityTaskWoken)
2544 {
2545     configASSERT(xTimer != NULL);
2546 
2547     return xTimerReset(xTimer, 0u);
2548 }
2549 
2550 
pvTimerGetTimerID(TimerHandle_t xTimer)2551 void *pvTimerGetTimerID(TimerHandle_t xTimer)
2552 {
2553     TX_INTERRUPT_SAVE_AREA;
2554     void *p_id;
2555 
2556     configASSERT(xTimer != NULL);
2557 
2558     TX_DISABLE;
2559     p_id = xTimer->id;
2560     TX_RESTORE;
2561 
2562     return p_id;
2563 }
2564 
vTimerSetTimerID(TimerHandle_t xTimer,void * pvNewID)2565 void vTimerSetTimerID(TimerHandle_t xTimer, void *pvNewID)
2566 {
2567     TX_INTERRUPT_SAVE_AREA;
2568 
2569     configASSERT(xTimer != NULL);
2570 
2571     TX_DISABLE;
2572     xTimer->id = pvNewID;
2573     TX_RESTORE;
2574 
2575     return;
2576 }
2577 
vTimerSetReloadMode(TimerHandle_t xTimer,const UBaseType_t uxAutoReload)2578 void vTimerSetReloadMode(TimerHandle_t xTimer,
2579                          const UBaseType_t uxAutoReload)
2580 {
2581     UINT ret;
2582     TX_INTERRUPT_SAVE_AREA;
2583     ULONG left;
2584 
2585     configASSERT(xTimer != NULL);
2586 
2587     TX_DISABLE;
2588 
2589     ret = tx_timer_deactivate(&xTimer->timer);
2590     if(ret != TX_SUCCESS) {
2591         TX_RESTORE;
2592         return;
2593     }
2594 
2595     left = xTimer->timer.tx_timer_internal.tx_timer_internal_remaining_ticks;
2596 
2597     if(uxAutoReload != pdFALSE) {
2598         ret = tx_timer_change(&xTimer->timer, left, xTimer->period);
2599     } else {
2600         ret = tx_timer_change(&xTimer->timer, left, 0u);
2601     }
2602     if(ret != TX_SUCCESS) {
2603         TX_RESTORE;
2604         return;
2605     }
2606 
2607     ret = tx_timer_activate(&xTimer->timer);
2608     if(ret != TX_SUCCESS) {
2609         TX_RESTORE;
2610         return;
2611     }
2612 
2613     TX_RESTORE;
2614 
2615     return;
2616 }
2617 
2618 
pcTimerGetName(TimerHandle_t xTimer)2619 const char * pcTimerGetName(TimerHandle_t xTimer)
2620 {
2621     configASSERT(xTimer != NULL);
2622 
2623     return (const char *)xTimer->timer.tx_timer_name;
2624 }
2625 
2626 
xTimerGetPeriod(TimerHandle_t xTimer)2627 TickType_t xTimerGetPeriod(TimerHandle_t xTimer)
2628 {
2629     TX_INTERRUPT_SAVE_AREA;
2630     TickType_t period;
2631 
2632     configASSERT(xTimer != NULL);
2633 
2634     TX_DISABLE;
2635 
2636     period = xTimer->period;
2637 
2638     TX_RESTORE;
2639 
2640     return period;
2641 }
2642 
2643 
xTimerGetExpiryTime(TimerHandle_t xTimer)2644 TickType_t xTimerGetExpiryTime(TimerHandle_t xTimer)
2645 {
2646     TX_INTERRUPT_SAVE_AREA;
2647     ULONG time_tx;
2648     TickType_t time;
2649     UINT ret;
2650 
2651     configASSERT(xTimer != NULL);
2652 
2653     TX_DISABLE;
2654 
2655     ret = tx_timer_info_get(&xTimer->timer, NULL, NULL, &time_tx, NULL, NULL);
2656     if(ret != TX_SUCCESS) {
2657         TX_FREERTOS_ASSERT_FAIL();
2658         return 0u;
2659     }
2660 
2661     time = (TickType_t)(tx_time_get() + time_tx);
2662 
2663     TX_RESTORE;
2664 
2665     return time;
2666 }
2667 
2668 
uxTimerGetReloadMode(TimerHandle_t xTimer)2669 UBaseType_t uxTimerGetReloadMode(TimerHandle_t xTimer)
2670 {
2671     TX_INTERRUPT_SAVE_AREA;
2672     UBaseType_t type;
2673 
2674     configASSERT(xTimer != NULL);
2675 
2676     TX_DISABLE;
2677 
2678     if(xTimer->one_shot == 0u) {
2679         type = pdTRUE;
2680     } else {
2681         type = pdFALSE;
2682     }
2683 
2684     TX_RESTORE;
2685 
2686     return type;
2687 }
2688 
2689 
xQueueCreateSet(const UBaseType_t uxEventQueueLength)2690 QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength)
2691 {
2692     txfr_queueset_t *p_set;
2693     void *p_mem;
2694     ULONG queue_size;
2695     UINT ret;
2696 
2697     configASSERT(uxEventQueueLength != 0u);
2698 
2699 #if (TX_FREERTOS_AUTO_INIT == 1)
2700     if(txfr_initialized != 1u) {
2701         tx_freertos_auto_init();
2702     }
2703 #endif
2704 
2705     if ((uxEventQueueLength > (SIZE_MAX / sizeof(void *))) ||
2706         (uxEventQueueLength > (ULONG_MAX / sizeof(void *)))) {
2707 
2708         /* Integer overflow in queue size */
2709         return NULL;
2710     }
2711 
2712     p_set = txfr_malloc(sizeof(txfr_queueset_t));
2713     if(p_set == NULL) {
2714         return NULL;
2715     }
2716 
2717     queue_size = sizeof(void *) * uxEventQueueLength;
2718     p_mem = txfr_malloc(queue_size);
2719     if(p_mem == NULL) {
2720         txfr_free(p_set);
2721         return NULL;
2722     }
2723 
2724     ret = tx_queue_create(&p_set->queue, "", sizeof(void *) / sizeof(UINT), p_mem, queue_size);
2725     if(ret != TX_SUCCESS) {
2726         TX_FREERTOS_ASSERT_FAIL();
2727         return NULL;
2728     }
2729 
2730     return p_set;
2731 }
2732 
2733 
xQueueAddToSet(QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet)2734 BaseType_t xQueueAddToSet(QueueSetMemberHandle_t xQueueOrSemaphore,
2735                           QueueSetHandle_t xQueueSet)
2736 {
2737     txfr_sem_t *p_sem;
2738     txfr_queue_t *p_queue;
2739     TX_INTERRUPT_SAVE_AREA;
2740 
2741     configASSERT(xQueueOrSemaphore != NULL);
2742     configASSERT(xQueueSet != NULL);
2743 
2744     TX_DISABLE;
2745     if(*((ULONG *)(xQueueOrSemaphore)) == TX_SEMAPHORE_ID) {
2746         p_sem = (txfr_sem_t *)xQueueOrSemaphore;
2747         if(p_sem->p_set != NULL) {
2748             TX_RESTORE;
2749             return pdFAIL;
2750         }
2751 
2752         p_sem->p_set = xQueueSet;
2753 
2754     } else if(*((ULONG *)(xQueueOrSemaphore)) == TX_QUEUE_ID) {
2755         p_queue = (txfr_queue_t *)xQueueOrSemaphore;
2756         if(p_queue->p_set != NULL) {
2757             TX_RESTORE;
2758             return pdFAIL;
2759         }
2760 
2761         p_queue->p_set = xQueueSet;
2762 
2763     } else {
2764         TX_RESTORE;
2765         configASSERT(0u);
2766         return pdFAIL;
2767     }
2768 
2769     TX_RESTORE;
2770 
2771     return pdPASS;
2772 }
2773 
2774 
xQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet)2775 BaseType_t xQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore,
2776                                QueueSetHandle_t xQueueSet)
2777 {
2778     txfr_sem_t *p_sem;
2779     txfr_queue_t *p_queue;
2780     TX_INTERRUPT_SAVE_AREA;
2781 
2782     configASSERT(xQueueOrSemaphore != NULL);
2783     configASSERT(xQueueSet != NULL);
2784 
2785     TX_DISABLE;
2786 
2787     if(*((ULONG *)(xQueueOrSemaphore)) == TX_SEMAPHORE_ID) {
2788         p_sem = (txfr_sem_t *)xQueueOrSemaphore;
2789 
2790         if(p_sem->p_set != xQueueSet) {
2791             TX_RESTORE;
2792             return pdFAIL;
2793         } else  {
2794             p_sem->p_set = NULL;
2795         }
2796 
2797     } else if(*((ULONG *)(xQueueOrSemaphore)) == TX_QUEUE_ID) {
2798         p_queue = (txfr_queue_t *)xQueueOrSemaphore;
2799 
2800         if(p_queue->p_set != xQueueSet) {
2801             TX_RESTORE;
2802             return pdFAIL;
2803         } else  {
2804             p_queue->p_set = NULL;
2805         }
2806 
2807     } else {
2808         TX_RESTORE;
2809         configASSERT(0u);
2810         return pdFAIL;
2811     }
2812 
2813     TX_RESTORE;
2814 
2815     return pdPASS;
2816 }
2817 
2818 
xQueueSelectFromSet(QueueSetHandle_t xQueueSet,const TickType_t xTicksToWait)2819 QueueSetMemberHandle_t xQueueSelectFromSet(QueueSetHandle_t xQueueSet,
2820                                            const TickType_t xTicksToWait)
2821 {
2822     void *p_ptr;
2823     UINT ret;
2824     UINT timeout;
2825 
2826     configASSERT(xQueueSet != NULL);
2827 
2828     if(xTicksToWait == portMAX_DELAY) {
2829         timeout = TX_WAIT_FOREVER;
2830     } else {
2831         timeout = (UINT)xTicksToWait;
2832     }
2833 
2834     ret = tx_queue_receive(&xQueueSet->queue, &p_ptr, timeout);
2835     if(ret != TX_SUCCESS) {
2836         return NULL;
2837     }
2838 
2839     return p_ptr;
2840 }
2841 
2842 
xQueueSelectFromSetFromISR(QueueSetHandle_t xQueueSet)2843 QueueSetMemberHandle_t xQueueSelectFromSetFromISR(QueueSetHandle_t xQueueSet)
2844 {
2845     return xQueueSelectFromSet(xQueueSet, 0u);
2846 }
2847