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