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