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